Share Pastebin
Guest
Public paste!

mlk

By: a guest | Jul 21st, 2008 | Syntax: Python | Size: 1.53 KB | Hits: 134 | Expires: Never
Copy text to clipboard
  1. from peak.util.assembler import *
  2. from peak.util.decorators import rewrap
  3. import new
  4. import inspect
  5.  
  6.  
  7. def accepts(*argtypes):
  8.     def decorate(func):
  9.         argnames = inspect.getargspec(func)[0]
  10.         code_args = [process_arg(i, argnames[i], cls) for i, cls in enumerate(argtypes)]
  11.         c = Code.from_function(func)
  12.         c.return_(Call(Const(func), code_args))
  13.         wrapped = new.function(c.code(), {})
  14.         return rewrap(func, wrapped)
  15.     return decorate
  16.  
  17.  
  18. @nodetype()
  19. def process_arg(i, argname, spec, code=None):
  20.     if code is None:
  21.         return i, argname, spec
  22.     else:
  23.         arg = Local(argname)
  24.         code(Call(Const(isinstance), [arg, Const(spec)]))
  25.         skip = code.JUMP_IF_TRUE()
  26.         error_msg = Suite([ Const("Expected %r for argument #%d got %%r" % (spec, i+1)),
  27.                             Call(Const(type), [arg]),
  28.                             Code.BINARY_MODULO])
  29.         code(Call(Const(TypeError), [error_msg]))
  30.         code.RAISE_VARARGS(1)
  31.         skip()
  32.         code.POP_TOP()
  33.         code(arg)
  34.  
  35.  
  36. @accepts(float, float)
  37. def float_div(a, b):
  38.     """
  39.    A function that divides floats.
  40.    Any other types of arguments will throw an exception
  41.  
  42.        >>> float_div(1.0, 2.0)
  43.        0.5
  44.        >>> float_div(1, 1.0)
  45.        Traceback (most recent call last):
  46.        ...
  47.        TypeError: Expected <type 'float'> for argument #1 got <type 'int'>
  48.    """
  49.     return a / b
  50.  
  51.  
  52. if __name__ == '__main__':
  53.     import doctest
  54.     doctest.testmod(verbose=True)