bpo-40897:Give priority to using the current class constructor in `inspect.signature` (GH-27177) (#27189)
Co-authored-by: Ćukasz Langa <lukasz@langa.pl>
(cherry picked from commit 6aab5f9bf303a8e4cd8377fabcdcb499e0541f9a)
Co-authored-by: Weipeng Hong <hongweichen8888@sina.com>
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 0273ffa..750fd45 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -2471,15 +2471,23 @@ def _signature_from_callable(obj, *,
if call is not None:
sig = _get_signature_of(call)
else:
- # Now we check if the 'obj' class has a '__new__' method
+ factory_method = None
new = _signature_get_user_defined_method(obj, '__new__')
- if new is not None:
- sig = _get_signature_of(new)
- else:
- # Finally, we should have at least __init__ implemented
- init = _signature_get_user_defined_method(obj, '__init__')
- if init is not None:
- sig = _get_signature_of(init)
+ init = _signature_get_user_defined_method(obj, '__init__')
+ # Now we check if the 'obj' class has an own '__new__' method
+ if '__new__' in obj.__dict__:
+ factory_method = new
+ # or an own '__init__' method
+ elif '__init__' in obj.__dict__:
+ factory_method = init
+ # If not, we take inherited '__new__' or '__init__', if present
+ elif new is not None:
+ factory_method = new
+ elif init is not None:
+ factory_method = init
+
+ if factory_method is not None:
+ sig = _get_signature_of(factory_method)
if sig is None:
# At this point we know, that `obj` is a class, with no user-