Skip to content

Commit aca77b5

Browse files
authoredJun 4, 2023
[3.11] gh-105080: Fixed inconsistent signature on derived classes (GH… (#105274)
1 parent 86eab08 commit aca77b5

File tree

3 files changed

+31
-11
lines changed

3 files changed

+31
-11
lines changed
 

‎Lib/inspect.py

+12-11
Original file line numberDiff line numberDiff line change
@@ -2538,17 +2538,18 @@ def _signature_from_callable(obj, *,
25382538
factory_method = None
25392539
new = _signature_get_user_defined_method(obj, '__new__')
25402540
init = _signature_get_user_defined_method(obj, '__init__')
2541-
# Now we check if the 'obj' class has an own '__new__' method
2542-
if '__new__' in obj.__dict__:
2543-
factory_method = new
2544-
# or an own '__init__' method
2545-
elif '__init__' in obj.__dict__:
2546-
factory_method = init
2547-
# If not, we take inherited '__new__' or '__init__', if present
2548-
elif new is not None:
2549-
factory_method = new
2550-
elif init is not None:
2551-
factory_method = init
2541+
2542+
# Go through the MRO and see if any class has user-defined
2543+
# pure Python __new__ or __init__ method
2544+
for base in obj.__mro__:
2545+
# Now we check if the 'obj' class has an own '__new__' method
2546+
if new is not None and '__new__' in base.__dict__:
2547+
factory_method = new
2548+
break
2549+
# or an own '__init__' method
2550+
elif init is not None and '__init__' in base.__dict__:
2551+
factory_method = init
2552+
break
25522553

25532554
if factory_method is not None:
25542555
sig = _get_signature_of(factory_method)

‎Lib/test/test_inspect.py

+18
Original file line numberDiff line numberDiff line change
@@ -3688,6 +3688,24 @@ def foo(): pass
36883688
self.assertEqual(signature_func(foo), inspect.Signature())
36893689
self.assertEqual(inspect.get_annotations(foo), {})
36903690

3691+
def test_signature_on_derived_classes(self):
3692+
# gh-105080: Make sure that signatures are consistent on derived classes
3693+
3694+
class B:
3695+
def __new__(self, *args, **kwargs):
3696+
return super().__new__(self)
3697+
def __init__(self, value):
3698+
self.value = value
3699+
3700+
class D1(B):
3701+
def __init__(self, value):
3702+
super().__init__(value)
3703+
3704+
class D2(D1):
3705+
pass
3706+
3707+
self.assertEqual(inspect.signature(D2), inspect.signature(D1))
3708+
36913709

36923710
class TestParameterObject(unittest.TestCase):
36933711
def test_signature_parameter_kinds(self):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed inconsistent signature on derived classes for :func:`inspect.signature`

0 commit comments

Comments
 (0)