inspect.signature: Make sure that if a callable object has '_patialmethod'

attribute, that attribute is an instance of 'functools.partialmethod'.
This commit is contained in:
Yury Selivanov 2014-01-29 12:18:59 -05:00
parent c45873e434
commit 0486f819c9
2 changed files with 17 additions and 11 deletions

View File

@ -1651,20 +1651,21 @@ def signature(obj):
except AttributeError:
pass
else:
# Unbound partialmethod (see functools.partialmethod)
# This means, that we need to calculate the signature
# as if it's a regular partial object, but taking into
# account that the first positional argument
# (usually `self`, or `cls`) will not be passed
# automatically (as for boundmethods)
if isinstance(partialmethod, functools.partialmethod):
# Unbound partialmethod (see functools.partialmethod)
# This means, that we need to calculate the signature
# as if it's a regular partial object, but taking into
# account that the first positional argument
# (usually `self`, or `cls`) will not be passed
# automatically (as for boundmethods)
wrapped_sig = signature(partialmethod.func)
sig = _signature_get_partial(wrapped_sig, partialmethod, (None,))
wrapped_sig = signature(partialmethod.func)
sig = _signature_get_partial(wrapped_sig, partialmethod, (None,))
first_wrapped_param = tuple(wrapped_sig.parameters.values())[0]
new_params = (first_wrapped_param,) + tuple(sig.parameters.values())
first_wrapped_param = tuple(wrapped_sig.parameters.values())[0]
new_params = (first_wrapped_param,) + tuple(sig.parameters.values())
return sig.replace(parameters=new_params)
return sig.replace(parameters=new_params)
if _signature_is_builtin(obj):
return Signature.from_builtin(obj)

View File

@ -1983,6 +1983,11 @@ class TestSignatureObject(unittest.TestCase):
('c', 1, ..., 'keyword_only')),
'spam'))
def test_signature_on_fake_partialmethod(self):
def foo(a): pass
foo._partialmethod = 'spam'
self.assertEqual(str(inspect.signature(foo)), '(a)')
def test_signature_on_decorated(self):
import functools