summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2023-06-02 23:05:49 (GMT)
committerGitHub <noreply@github.com>2023-06-02 23:05:49 (GMT)
commitd3922c4688172c6865caaee69ed1afb439907919 (patch)
treef8253891c6771eced8e69bfd9c03e9733b4d8859
parent72d5dfaa8f475498644035839f5a6469db486407 (diff)
downloadcpython-d3922c4688172c6865caaee69ed1afb439907919.zip
cpython-d3922c4688172c6865caaee69ed1afb439907919.tar.gz
cpython-d3922c4688172c6865caaee69ed1afb439907919.tar.bz2
[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 9ad199ba36791711f596393ca9a20dbf118ef858) Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com>
-rw-r--r--Lib/inspect.py23
-rw-r--r--Lib/test/test_inspect.py18
-rw-r--r--Misc/NEWS.d/next/Library/2023-06-02-02-38-26.gh-issue-105080.2imGMg.rst1
3 files changed, 31 insertions, 11 deletions
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 15eefdb..a550202 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -2581,17 +2581,18 @@ def _signature_from_callable(obj, *,
factory_method = None
new = _signature_get_user_defined_method(obj, '__new__')
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
+
+ # 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
+ if new is not None and '__new__' in base.__dict__:
+ factory_method = new
+ break
+ # or an own '__init__' method
+ elif init is not None and '__init__' in base.__dict__:
+ factory_method = init
+ break
if factory_method is not None:
sig = _get_signature_of(factory_method)
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index 6a49e3b..d89953a 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -3927,6 +3927,24 @@ class TestSignatureObject(unittest.TestCase):
('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):
def test_signature_parameter_kinds(self):
diff --git a/Misc/NEWS.d/next/Library/2023-06-02-02-38-26.gh-issue-105080.2imGMg.rst b/Misc/NEWS.d/next/Library/2023-06-02-02-38-26.gh-issue-105080.2imGMg.rst
new file mode 100644
index 0000000..efe8365
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-06-02-02-38-26.gh-issue-105080.2imGMg.rst
@@ -0,0 +1 @@
+Fixed inconsistent signature on derived classes for :func:`inspect.signature`