cpython: inspect.Signature: Make from_builtin to raise an exception if no signature can
http://hg.python.org/cpython/rev/9433b380ad33 changeset: 88809:9433b380ad33 parent: 88807:483096ef1cf6 user: Yury Selivanov <yselivanov@sprymix.com> date: Wed Jan 29 10:46:14 2014 -0500 summary: inspect.Signature: Make from_builtin to raise an exception if no signature can be provided #20422 files: Lib/inspect.py | 30 ++++++++++++++++++--------- Lib/test/test_inspect.py | 4 +++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1514,18 +1514,24 @@ 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 @@ @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 @@ 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 @@ return cls(parameters, return_annotation=cls.empty) - @property def parameters(self): return self._parameters diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -1667,6 +1667,10 @@ 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): -- Repository URL: http://hg.python.org/cpython
participants (1)
-
yury.selivanov