mirror of
https://github.com/python/cpython.git
synced 2024-11-24 10:24:35 +08:00
inspect.Signature: Make from_builtin to raise an exception if no signature can
be provided #20422
This commit is contained in:
parent
9f2e46de34
commit
b77511da92
@ -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
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user