]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-82062: Fix support of parameter defaults on methods in extension modules (GH-115270)
authorSergey B Kirpichev <skirpichev@gmail.com>
Thu, 2 May 2024 14:44:33 +0000 (17:44 +0300)
committerGitHub <noreply@github.com>
Thu, 2 May 2024 14:44:33 +0000 (17:44 +0300)
Now inspect.signature() supports references to the module globals in
parameter defaults on methods in extension modules.  Previously it was
only supported in functions.  The workaround was to specify the fully
qualified name, including the module name.

Lib/inspect.py
Lib/test/test_inspect/test_inspect.py
Misc/NEWS.d/next/Library/2024-02-11-07-31-43.gh-issue-82062.eeS6w7.rst [new file with mode: 0644]
Modules/_testcapi/docstring.c

index d46514f4b104677479fbc2c6599d84e7a8f209e4..a0c80bd5c8b6014b5ea03ce36deb5eb09abacfc3 100644 (file)
@@ -2285,7 +2285,12 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
 
     module = None
     module_dict = {}
+
     module_name = getattr(obj, '__module__', None)
+    if not module_name:
+        objclass = getattr(obj, '__objclass__', None)
+        module_name = getattr(objclass, '__module__', None)
+
     if module_name:
         module = sys.modules.get(module_name, None)
         if module:
index fbef34eddacb3a4e515bc70ae63e6a4f291ffdcb..d12240353ff8324bfbb666a8481b70cd3ff3cf49 100644 (file)
@@ -3069,6 +3069,13 @@ class TestSignatureObject(unittest.TestCase):
                 self.assertEqual(inspect.signature(builtin),
                                  inspect.signature(template))
 
+    @unittest.skipIf(MISSING_C_DOCSTRINGS,
+                     "Signature information for builtins requires docstrings")
+    def test_signature_parsing_with_defaults(self):
+        _testcapi = import_helper.import_module("_testcapi")
+        meth = _testcapi.DocStringUnrepresentableSignatureTest.with_default
+        self.assertEqual(str(inspect.signature(meth)), '(self, /, x=1)')
+
     def test_signature_on_non_function(self):
         with self.assertRaisesRegex(TypeError, 'is not a callable object'):
             inspect.signature(42)
diff --git a/Misc/NEWS.d/next/Library/2024-02-11-07-31-43.gh-issue-82062.eeS6w7.rst b/Misc/NEWS.d/next/Library/2024-02-11-07-31-43.gh-issue-82062.eeS6w7.rst
new file mode 100644 (file)
index 0000000..a57a591
--- /dev/null
@@ -0,0 +1,3 @@
+Fix :func:`inspect.signature()` to correctly handle parameter defaults
+on methods in extension modules that use names defined in the module
+namespace.
index d99fbdd904b59499bcff3cf864c82e1fe30c567c..3f7acbae1b181b207f8d00c7cf3929d082b02f6e 100644 (file)
@@ -169,6 +169,13 @@ static PyMethodDef DocStringUnrepresentableSignatureTest_methods[] = {
             "--\n\n"
             "This docstring has a signature with unrepresentable default."
         )},
+    {"with_default",
+        (PyCFunction)test_with_docstring, METH_VARARGS,
+        PyDoc_STR(
+            "with_default($self, /, x=ONE)\n"
+            "--\n\n"
+            "This instance method has a default parameter value from the module scope."
+        )},
     {NULL},
 };
 
@@ -193,5 +200,8 @@ _PyTestCapi_Init_Docstring(PyObject *mod)
     if (PyModule_AddType(mod, &DocStringUnrepresentableSignatureTest) < 0) {
         return -1;
     }
+    if (PyModule_AddObject(mod, "ONE", PyLong_FromLong(1)) < 0) {
+        return -1;
+    }
     return 0;
 }