Skip to content

Commit

Permalink
validate can take callable instances
Browse files Browse the repository at this point in the history
  • Loading branch information
mmckerns committed Mar 25, 2023
1 parent 0e66d36 commit 2bf5a15
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 4 deletions.
14 changes: 10 additions & 4 deletions klepto/_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,11 @@ def signature(func, variadic=True, markup=True, safe=False):
p_kwds = func.keywords or {} # dict of default kwd values
func = func.func
identified = True
except AttributeError: #XXX: anything else to try? No? Give up.
pass
except AttributeError:
if hasattr(func, '__call__') and not hasattr(func, '__name__'):
func = func.__call__ # treat callable instance as __call__
else: #XXX: anything else to try? No? Give up.
pass
if not identified:
p_args = ()
p_kwds = {}
Expand Down Expand Up @@ -197,8 +200,11 @@ def validate(func, *args, **kwds):
func = func.func
p_required = set(p_named) - set(p_defaults)
identified = True
except AttributeError: #XXX: anything else to try? No? Give up.
pass
except AttributeError:
if hasattr(func, '__call__') and not hasattr(func, '__name__'):
func = func.__call__ # treat callable instance as __call__
else: #XXX: anything else to try? No? Give up.
pass
if not identified:
p_args = p_named = ()
p_kwds = p_defaults = {}
Expand Down
129 changes: 129 additions & 0 deletions klepto/tests/test_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,132 @@
def foo(x,y,z,a=1,b=2):
return x+y+z+a+b

class Bar(object):
def foo(self, x,y,z,a=1,b=2):
return foo(x,y,z,a=a,b=b)
def __call__(self, x,y,z,a=1,b=2): #NOTE: *args, **kwds):
return foo(x,y,z,a=a,b=b)

def test_foo():
p = foo
try:
res1 = p(1,2,3,4,b=5)
res2 = Exception()
except:
res1,res2 = sys.exc_info()[:2]
try:
re_1 = validate(p,1,2,3,4,b=5)
re_2 = Exception()
except:
re_1,re_2 = sys.exc_info()[:2]
assert re_1 is None

try:
res1 = p()
res2 = Exception()
except:
res1,res2 = sys.exc_info()[:2]
try:
re_1 = validate(p)
re_2 = Exception()
except:
re_1,re_2 = sys.exc_info()[:2]
assert res1 == re_1
#XXX: "foo() missing 3 required positional arguments"

try:
res1 = p(1,2,3,4,r=5)
res2 = Exception()
except:
res1,res2 = sys.exc_info()[:2]
try:
re_1 = validate(p,1,2,3,4,r=5)
re_2 = Exception()
except:
re_1,re_2 = sys.exc_info()[:2]
assert res1 == re_1
#XXX: "foo() got unexpected keyword argument 'r'"

def test_Bar_foo():
p = Bar().foo
try:
res1 = p(1,2,3,4,b=5)
res2 = Exception()
except:
res1,res2 = sys.exc_info()[:2]
try:
re_1 = validate(p,1,2,3,4,b=5)
re_2 = Exception()
except:
re_1,re_2 = sys.exc_info()[:2]
assert re_1 is None

try:
res1 = p()
res2 = Exception()
except:
res1,res2 = sys.exc_info()[:2]
try:
re_1 = validate(p)
re_2 = Exception()
except:
re_1,re_2 = sys.exc_info()[:2]
assert res1 == re_1
#XXX: "foo() missing 3 required positional arguments"

try:
res1 = p(1,2,3,4,r=5)
res2 = Exception()
except:
res1,res2 = sys.exc_info()[:2]
try:
re_1 = validate(p,1,2,3,4,r=5)
re_2 = Exception()
except:
re_1,re_2 = sys.exc_info()[:2]
assert res1 == re_1
#XXX: "foo() got unexpected keyword argument 'r'"

def test_Bar():
p = Bar()
try:
res1 = p(1,2,3,4,b=5)
res2 = Exception()
except:
res1,res2 = sys.exc_info()[:2]
try:
re_1 = validate(p,1,2,3,4,b=5)
re_2 = Exception()
except:
re_1,re_2 = sys.exc_info()[:2]
assert re_1 is None

try:
res1 = p()
res2 = Exception()
except:
res1,res2 = sys.exc_info()[:2]
try:
re_1 = validate(p)
re_2 = Exception()
except:
re_1,re_2 = sys.exc_info()[:2]
assert res1 == re_1
#XXX: "foo() missing 3 required positional arguments"

try:
res1 = p(1,2,3,4,r=5)
res2 = Exception()
except:
res1,res2 = sys.exc_info()[:2]
try:
re_1 = validate(p,1,2,3,4,r=5)
re_2 = Exception()
except:
re_1,re_2 = sys.exc_info()[:2]
assert res1 == re_1
#XXX: "foo() got unexpected keyword argument 'r'"

def test_partial_foo_xy():
p = partial(foo, 0,1)
try:
Expand Down Expand Up @@ -160,6 +286,9 @@ def test_partial_foo_xa():


if __name__ == '__main__':
test_foo()
test_Bar_foo()
test_Bar()
test_partial_foo_xy()
test_partial_foo_xx()
test_partial_foo_xyzabcde()
Expand Down

0 comments on commit 2bf5a15

Please sign in to comment.