Skip to content

Commit 9789440

Browse files
authored
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.
1 parent 81939da commit 9789440

File tree

4 files changed

+25
-0
lines changed

4 files changed

+25
-0
lines changed

Lib/inspect.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2285,7 +2285,12 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
22852285

22862286
module = None
22872287
module_dict = {}
2288+
22882289
module_name = getattr(obj, '__module__', None)
2290+
if not module_name:
2291+
objclass = getattr(obj, '__objclass__', None)
2292+
module_name = getattr(objclass, '__module__', None)
2293+
22892294
if module_name:
22902295
module = sys.modules.get(module_name, None)
22912296
if module:

Lib/test/test_inspect/test_inspect.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3069,6 +3069,13 @@ def test_signature_on_builtins_no_signature(self):
30693069
self.assertEqual(inspect.signature(builtin),
30703070
inspect.signature(template))
30713071

3072+
@unittest.skipIf(MISSING_C_DOCSTRINGS,
3073+
"Signature information for builtins requires docstrings")
3074+
def test_signature_parsing_with_defaults(self):
3075+
_testcapi = import_helper.import_module("_testcapi")
3076+
meth = _testcapi.DocStringUnrepresentableSignatureTest.with_default
3077+
self.assertEqual(str(inspect.signature(meth)), '(self, /, x=1)')
3078+
30723079
def test_signature_on_non_function(self):
30733080
with self.assertRaisesRegex(TypeError, 'is not a callable object'):
30743081
inspect.signature(42)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix :func:`inspect.signature()` to correctly handle parameter defaults
2+
on methods in extension modules that use names defined in the module
3+
namespace.

Modules/_testcapi/docstring.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,13 @@ static PyMethodDef DocStringUnrepresentableSignatureTest_methods[] = {
169169
"--\n\n"
170170
"This docstring has a signature with unrepresentable default."
171171
)},
172+
{"with_default",
173+
(PyCFunction)test_with_docstring, METH_VARARGS,
174+
PyDoc_STR(
175+
"with_default($self, /, x=ONE)\n"
176+
"--\n\n"
177+
"This instance method has a default parameter value from the module scope."
178+
)},
172179
{NULL},
173180
};
174181

@@ -193,5 +200,8 @@ _PyTestCapi_Init_Docstring(PyObject *mod)
193200
if (PyModule_AddType(mod, &DocStringUnrepresentableSignatureTest) < 0) {
194201
return -1;
195202
}
203+
if (PyModule_AddObject(mod, "ONE", PyLong_FromLong(1)) < 0) {
204+
return -1;
205+
}
196206
return 0;
197207
}

0 commit comments

Comments
 (0)