Skip to content
Merged
5 changes: 5 additions & 0 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
7 changes: 7 additions & 0 deletions Lib/test/test_inspect/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -3069,6 +3069,13 @@ def test_signature_on_builtins_no_signature(self):
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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix :func:`inspect.signature()` to correctly handle globals in extension
modules. Now signatures are correct if globals are use to define default
values in extension functions and/or methods.
10 changes: 10 additions & 0 deletions Modules/_testcapi/docstring.c
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};

Expand All @@ -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;
}