[3.12] gh-105080: Fixed inconsistent signature on derived classes (GH-105217) (#105257)

gh-105080: Fixed inconsistent signature on derived classes (GH-105217)
(cherry picked from commit 9ad199ba36)

Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com>
This commit is contained in:
Miss Islington (bot) 2023-06-02 16:05:49 -07:00 committed by GitHub
parent 72d5dfaa8f
commit d3922c4688
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 11 deletions

View file

@ -2581,17 +2581,18 @@ def _signature_from_callable(obj, *,
factory_method = None factory_method = None
new = _signature_get_user_defined_method(obj, '__new__') new = _signature_get_user_defined_method(obj, '__new__')
init = _signature_get_user_defined_method(obj, '__init__') init = _signature_get_user_defined_method(obj, '__init__')
# Go through the MRO and see if any class has user-defined
# pure Python __new__ or __init__ method
for base in obj.__mro__:
# Now we check if the 'obj' class has an own '__new__' method # Now we check if the 'obj' class has an own '__new__' method
if '__new__' in obj.__dict__: if new is not None and '__new__' in base.__dict__:
factory_method = new factory_method = new
break
# or an own '__init__' method # or an own '__init__' method
elif '__init__' in obj.__dict__: elif init is not None and '__init__' in base.__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 factory_method = init
break
if factory_method is not None: if factory_method is not None:
sig = _get_signature_of(factory_method) sig = _get_signature_of(factory_method)

View file

@ -3927,6 +3927,24 @@ class TestSignatureObject(unittest.TestCase):
('b', 2, ..., 'positional_or_keyword')), ('b', 2, ..., 'positional_or_keyword')),
...)) ...))
def test_signature_on_derived_classes(self):
# gh-105080: Make sure that signatures are consistent on derived classes
class B:
def __new__(self, *args, **kwargs):
return super().__new__(self)
def __init__(self, value):
self.value = value
class D1(B):
def __init__(self, value):
super().__init__(value)
class D2(D1):
pass
self.assertEqual(inspect.signature(D2), inspect.signature(D1))
class TestParameterObject(unittest.TestCase): class TestParameterObject(unittest.TestCase):
def test_signature_parameter_kinds(self): def test_signature_parameter_kinds(self):

View file

@ -0,0 +1 @@
Fixed inconsistent signature on derived classes for :func:`inspect.signature`