gh-82062: Fix support of parameter defaults on methods in extension modules (GH-115270)

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.
This commit is contained in:
Sergey B Kirpichev 2024-05-02 17:44:33 +03:00 • committed by GitHub
parent 81939dad77
commit 9789440de3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 25 additions and 0 deletions

View 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:

View 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)

View file

@ -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.

View 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;
}