Archive

Archive for April, 2009

‘strict’ typing of function arguments in python

April 2nd, 2009 3 comments

Sometimes you just need strict variable typing in python. For example if you provide an XML-RPC function, where you have to ensure that the incoming data has the correct type. One solution for this is to write type-checking and converting manually within every function. Since that idea is not very nice and clean, i wrote a function and function decorator that can ensure that the function is always called with the desired types as arguments. To achieve that you need to use a certain naming scheme for the functions arguments: variableType_variableName. So int_a, str_s, list_myList, etc. (see example in code)

code (working example, just run):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# strictly typed python function arguments example
# Thomas Fischer <thomas{AT}thomasfischer{DOT}biz>

# function that checks the variable name and its type
# to use a certain type for a variable, just write variabletype_variablename
# for example: int_number, str_s, list_l
def checkFunctionArgumentTypes(function_pointer, args):
  args = list(args) # we want to assign stuff to it later on
  # now list some built-in types we check for
  arg_types = {'int':int, 'str':str, 'list':list, 'dict':dict, 'bool':bool, 'unicode':unicode, 'tuple':tuple, 'buffer':buffer, 'xrange':xrange, 'float':float, 'long':long, 'complex':complex, 'set':set, 'frozenset':frozenset}
  # care about default arguments (means args <= len of function arguments)
  arg_num = len(args)

  self_exist = False
  if function_pointer.func_code.co_argcount > 0 and function_pointer.func_code.co_varnames[0] == 'self':
    self_exist = True

  for argnum in range(0, arg_num):
    arg_def = None
    if self_exist:
      arg_def = function_pointer.func_code.co_varnames[argnum+1]
    else:
      arg_def = function_pointer.func_code.co_varnames[argnum]
    arg_ext = args[argnum]
    atype = None
    for arg_type in arg_types.keys():
      if arg_def.startswith(arg_type):
        atype = arg_types[arg_type]
        break
    if atype is None:
      # we cannot check the type, since no keyword was found :-/
      # maybe this is fatal for you and you want to return False as well
      continue
    # try to convert the type
    try:
      args[argnum] = atype.__call__(arg_ext)
    except Exception, e:
      res_str = "wrong type for function %s, argument %s (%d.) has to be type '%s' and not '%s'" % (function_pointer.__name__, arg_def, argnum, atype, type(arg_ext))
      return False, res_str
  return True, args

# some fancy function decorator that acts as a type checking wrapper around the function
def checkArgumentTypes(f):
  def wrapper(*args, **kwargs):
    ok, args = checkFunctionArgumentTypes(f, args)
    if not ok:
      return ok, args
    f(*args, **kwargs)
  return wrapper

# magic with python decorators :)
@checkArgumentTypes
def func1(str_s, int_number):
  print "func1 called with:", str_s, type(str_s), int_number, type(int_number)

# ok, fits:
print func1('test', 123)

# ok, will be converted:
print func1('test', '123')

# fails, cannot convert ABC to int:
print func1('test', 'ABC')

the result upon run:

func1 called with: test <type 'str'> 123 <type 'int'>
None
func1 called with: test <type 'str'> 123 <type 'int'>
None
(False, "wrong type for function func1, argument int_number (1.) has to be type '<type 'int'>' and not '<type 'str'>'")

this thing makes using XML-RPC much easier :)

Categories: coding, python Tags:

clone discs over the network

April 1st, 2009 No comments

its easy if you know how:
A is the computer we want to clone, B is the target.
1) download and burn two gentoo installation CDs and boot them on both systems.
2) give the root user a password and start sshd:

1
2
passwd
/etc/init.d/sshd start

3) clone discs via dd and ssh: (execute this on A)

1
dd if=/dev/hda bs=512 | ssh root@&lt;IP of B&gt; "dd of=/dev/hda"

4) thats all. You can view the status of the operation via:

1
kill -SIGUSR1 `ps | grep dd | awk '{ print $1 }'`

EDIT: better solution (with compression over the network):
on B:

1
netcat -l -p 11000 | bzip2 -d | dd of=/dev/sda

on A:

1
bzip2 -c /dev/sda | netcat &lt;IP of B&gt; 11000
Categories: gentoo, hardware Tags: