inspect.Signature: Make from_builtin to raise an exception if no signature can

be provided #20422
This commit is contained in:
Yury Selivanov 2014-01-29 10:46:14 -05:00
parent 9f2e46de34
commit b77511da92
2 changed files with 24 additions and 10 deletions

View File

@ -1514,18 +1514,24 @@ def _signature_bound_method(sig):
return sig.replace(parameters=params)
def _signature_is_builtin(obj):
# Internal helper to test if `obj` is a callable that might
# support Argument Clinic's __text_signature__ protocol.
return (isinstance(obj, _NonUserDefinedCallables) or
ismethoddescriptor(obj) or
# Can't test 'isinstance(type)' here, as it would
# also be True for regular python classes
obj in (type, object))
def signature(obj):
'''Get a signature object for the passed callable.'''
if not callable(obj):
raise TypeError('{!r} is not a callable object'.format(obj))
if (isinstance(obj, _NonUserDefinedCallables) or
ismethoddescriptor(obj) or
isinstance(obj, type)):
sig = Signature.from_builtin(obj)
if sig:
return sig
if _signature_is_builtin(obj):
return Signature.from_builtin(obj)
if isinstance(obj, types.MethodType):
# In this case we skip the first parameter of the underlying
@ -2017,9 +2023,13 @@ class Signature:
@classmethod
def from_builtin(cls, func):
if not _signature_is_builtin(func):
raise TypeError("{!r} is not a Python builtin "
"function".format(func))
s = getattr(func, "__text_signature__", None)
if not s:
return None
raise ValueError("no signature found for builtin {!r}".format(func))
Parameter = cls._parameter_cls
@ -2038,9 +2048,10 @@ class Signature:
try:
module = ast.parse(s)
except SyntaxError:
return None
module = None
if not isinstance(module, ast.Module):
return None
raise ValueError("{!r} builtin has invalid signature".format(func))
f = module.body[0]
@ -2149,7 +2160,6 @@ class Signature:
return cls(parameters, return_annotation=cls.empty)
@property
def parameters(self):
return self._parameters

View File

@ -1667,6 +1667,10 @@ class TestSignatureObject(unittest.TestCase):
with self.assertRaisesRegex(TypeError, 'is not a Python function'):
inspect.Signature.from_function(42)
def test_signature_from_builtin_errors(self):
with self.assertRaisesRegex(TypeError, 'is not a Python builtin'):
inspect.Signature.from_builtin(42)
def test_signature_on_method(self):
class Test:
def __init__(*args):