Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Release 4.8.0 (???)

- Drop support for Python 3.7 (including PyPy-3.7). Patch by Alex Waygood.
- Fix bug where `get_original_bases()` would return incorrect results when
called on a concrete subclass of a generic class. Patch by Alex Waygood
(backporting https://github.com/python/cpython/pull/107584, by James
Hilton-Balfe).

# Release 4.7.1 (July 2, 2023)

Expand Down
19 changes: 19 additions & 0 deletions src/test_typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5704,6 +5704,25 @@ class F(list[int]): pass
self.assertEqual(get_original_bases(E), (list[T],))
self.assertEqual(get_original_bases(F), (list[int],))

@skipIf(
sys.version_info[:3] == (3, 12, 0) and sys.version_info[3] in {"alpha", "beta"},
"Early versions of py312 had a bug"
)
def test_concrete_subclasses_of_generic_classes(self):
T = TypeVar("T")

class FirstBase(Generic[T]): pass
class SecondBase(Generic[T]): pass
class First(FirstBase[int]): pass
class Second(SecondBase[int]): pass
class G(First, Second): pass
self.assertEqual(get_original_bases(G), (First, Second))

class First_(Generic[T]): pass
class Second_(Generic[T]): pass
class H(First_, Second_): pass
self.assertEqual(get_original_bases(H), (First_, Second_))

def test_namedtuples(self):
# On 3.12, this should work well with typing.NamedTuple and typing_extensions.NamedTuple
# On lower versions, it will only work fully with typing_extensions.NamedTuple
Expand Down
11 changes: 4 additions & 7 deletions src/typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2570,14 +2570,11 @@ class Baz(list[str]): ...
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


# NewType is a class on Python 3.10+, making it pickleable
Expand Down