Skip to content

Instantly share code, notes, and snippets.

@letoh
Created June 22, 2012 08:02
Show Gist options
  • Select an option

  • Save letoh/2971209 to your computer and use it in GitHub Desktop.

Select an option

Save letoh/2971209 to your computer and use it in GitHub Desktop.
simple function signature checking in python
from itertools import izip
def isiterable(o):
try:
it = iter(o)
except TypeError:
return False
return True
class Args(object):
def __init__(s, *args):
s.args = args
def __call__(s, f):
def wrapper(*args, **kwargs):
if len(args) != len(s.args):
raise TypeError, "wrong arguments"
for n in izip(args, s.args):
if type(n[0]) != n[1]:
msg = repr(n[0]) + " is not in type " + repr(n[1])
raise TypeError, msg
r = f(*args, **kwargs)
return r
return wrapper
class Ret(object):
def __init__(s, *args):
s.args = args
def __call__(s, f):
def wrapper(*args, **kwargs):
r = f(*args, **kwargs)
if not isiterable(r):
r = (r,)
if len(r) != len(s.args):
raise TypeError, "wrong return values"
for n in izip(r, s.args):
if type(n[0]) != n[1]:
msg = repr(n[0]) + " is not in type " + repr(n[1])
raise TypeError, msg
return r
return wrapper
###
### test
###
@Args(int, int)
@Ret(int)
def foo(a, b):
print a, b
return a + b
@Args(int, int)
@Ret(int, int)
def bar(a, b):
print a, b
return a, b
def test(f, args):
try:
apply(f, args)
except TypeError, msg:
print 'Error:', msg
test(foo, (5, 6))
test(foo, (4, "abc"))
test(foo, (4, None))
test(foo, (7,))
test(foo, ())
test(bar, (100, 200))
test(bar, (100, "string"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment