gh-137317: Fix inspect.signature() for class with wrapped __init__ or __new__ (GH-137862)

Fixed several cases where __init__, __new__ or metaclass` __call__ is a descriptor
that returns a wrapped function.
This commit is contained in:
Ju4tCode 2025-08-28 22:57:53 +08:00 committed by GitHub
parent ef4dd1d655
commit 025a2135ef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 287 additions and 35 deletions

View file

@ -1917,17 +1917,21 @@ def _signature_get_user_defined_method(cls, method_name, *, follow_wrapper_chain
if meth is None:
return None
# NOTE: The meth may wraps a non-user-defined callable.
# In this case, we treat the meth as non-user-defined callable too.
# (e.g. cls.__new__ generated by @warnings.deprecated)
unwrapped_meth = None
if follow_wrapper_chains:
meth = unwrap(meth, stop=(lambda m: hasattr(m, "__signature__")
unwrapped_meth = unwrap(meth, stop=(lambda m: hasattr(m, "__signature__")
or _signature_is_builtin(m)))
if isinstance(meth, _NonUserDefinedCallables):
if (isinstance(meth, _NonUserDefinedCallables)
or isinstance(unwrapped_meth, _NonUserDefinedCallables)):
# Once '__signature__' will be added to 'C'-level
# callables, this check won't be necessary
return None
if method_name != '__new__':
meth = _descriptor_get(meth, cls)
if follow_wrapper_chains:
meth = unwrap(meth, stop=lambda m: hasattr(m, "__signature__"))
return meth