mirror of https://github.com/python/cpython
gh-107576: Ensure `__orig_bases__` are our own in `get_original_bases` (#107584)
Co-authored-by: Chris Bouchard <chris@upliftinglemma.net> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
parent
77e09192b5
commit
ed4a978449
|
@ -1397,6 +1397,7 @@ class ClassCreationTests(unittest.TestCase):
|
||||||
class B(typing.Generic[T]): pass
|
class B(typing.Generic[T]): pass
|
||||||
class C(B[int]): pass
|
class C(B[int]): pass
|
||||||
class D(B[str], float): pass
|
class D(B[str], float): pass
|
||||||
|
|
||||||
self.assertEqual(types.get_original_bases(A), (object,))
|
self.assertEqual(types.get_original_bases(A), (object,))
|
||||||
self.assertEqual(types.get_original_bases(B), (typing.Generic[T],))
|
self.assertEqual(types.get_original_bases(B), (typing.Generic[T],))
|
||||||
self.assertEqual(types.get_original_bases(C), (B[int],))
|
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(E), (list[T],))
|
||||||
self.assertEqual(types.get_original_bases(F), (list[int],))
|
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):
|
class ClassBasedNamedTuple(typing.NamedTuple):
|
||||||
x: int
|
x: int
|
||||||
|
|
||||||
|
|
11
Lib/types.py
11
Lib/types.py
|
@ -165,14 +165,11 @@ def get_original_bases(cls, /):
|
||||||
assert get_original_bases(int) == (object,)
|
assert get_original_bases(int) == (object,)
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return cls.__orig_bases__
|
return cls.__dict__.get("__orig_bases__", cls.__bases__)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
raise TypeError(
|
||||||
return cls.__bases__
|
f"Expected an instance of type, not {type(cls).__name__!r}"
|
||||||
except AttributeError:
|
) from None
|
||||||
raise TypeError(
|
|
||||||
f'Expected an instance of type, not {type(cls).__name__!r}'
|
|
||||||
) from None
|
|
||||||
|
|
||||||
|
|
||||||
class DynamicClassAttribute:
|
class DynamicClassAttribute:
|
||||||
|
|
|
@ -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.
|
Loading…
Reference in New Issue