]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-107576: Ensure `__orig_bases__` are our own in `get_original_bases` (#107584)
authorJames Hilton-Balfe <gobot1234yt@gmail.com>
Thu, 3 Aug 2023 14:19:24 +0000 (15:19 +0100)
committerGitHub <noreply@github.com>
Thu, 3 Aug 2023 14:19:24 +0000 (14:19 +0000)
Co-authored-by: Chris Bouchard <chris@upliftinglemma.net>
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Lib/test/test_types.py
Lib/types.py
Misc/NEWS.d/next/Library/2023-08-03-11-31-11.gh-issue-107576.pO_s9I.rst [new file with mode: 0644]

index 81744940f25b829be84367c421df1d5dbe1c7bd1..f2efee90dc02401d3bf8863fbbf67c6d282dbe0a 100644 (file)
@@ -1397,6 +1397,7 @@ class ClassCreationTests(unittest.TestCase):
         class B(typing.Generic[T]): pass
         class C(B[int]): pass
         class D(B[str], float): pass
+
         self.assertEqual(types.get_original_bases(A), (object,))
         self.assertEqual(types.get_original_bases(B), (typing.Generic[T],))
         self.assertEqual(types.get_original_bases(C), (B[int],))
@@ -1409,6 +1410,18 @@ class ClassCreationTests(unittest.TestCase):
         self.assertEqual(types.get_original_bases(E), (list[T],))
         self.assertEqual(types.get_original_bases(F), (list[int],))
 
+        class FirstBase(typing.Generic[T]): pass
+        class SecondBase(typing.Generic[T]): pass
+        class First(FirstBase[int]): pass
+        class Second(SecondBase[int]): pass
+        class G(First, Second): pass
+        self.assertEqual(types.get_original_bases(G), (First, Second))
+
+        class First_(typing.Generic[T]): pass
+        class Second_(typing.Generic[T]): pass
+        class H(First_, Second_): pass
+        self.assertEqual(types.get_original_bases(H), (First_, Second_))
+
         class ClassBasedNamedTuple(typing.NamedTuple):
             x: int
 
index 6110e6e1de7249eb01b50ea55ea93e9479b918cb..b4aa19cec40c8986f911b653a43c60afd8c37a66 100644 (file)
@@ -165,14 +165,11 @@ def get_original_bases(cls, /):
         assert get_original_bases(int) == (object,)
     """
     try:
-        return cls.__orig_bases__
+        return cls.__dict__.get("__orig_bases__", cls.__bases__)
     except AttributeError:
-        try:
-            return cls.__bases__
-        except AttributeError:
-            raise TypeError(
-                f'Expected an instance of type, not {type(cls).__name__!r}'
-            ) from None
+        raise TypeError(
+            f"Expected an instance of type, not {type(cls).__name__!r}"
+        ) from None
 
 
 class DynamicClassAttribute:
diff --git a/Misc/NEWS.d/next/Library/2023-08-03-11-31-11.gh-issue-107576.pO_s9I.rst b/Misc/NEWS.d/next/Library/2023-08-03-11-31-11.gh-issue-107576.pO_s9I.rst
new file mode 100644 (file)
index 0000000..67677dd
--- /dev/null
@@ -0,0 +1,3 @@
+Fix :func:`types.get_original_bases` to only return
+:attr:`!__orig_bases__` if it is present on ``cls`` directly. Patch by
+James Hilton-Balfe.