[Python-checkins] cpython: inspect.Signature: Make from_builtin to raise an exception if no signature can

yury.selivanov python-checkins at python.org
Wed Jan 29 16:46:28 CET 2014


http://hg.python.org/cpython/rev/9433b380ad33
changeset:   88809:9433b380ad33
parent:      88807:483096ef1cf6
user:        Yury Selivanov <yselivanov at 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


More information about the Python-checkins mailing list