diff --git a/CHANGELOG.md b/CHANGELOG.md index 8060d6a4..c5f19626 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ - Preliminary changes for compatibility with the draft implementation of PEP 649 in Python 3.14. +- Fix regression in v4.12.0 where nested `Annotated` types would cause + `TypeError` to be raised if the nested `Annotated` type had unhashable + metadata. # Release 4.12.0 (May 23, 2024) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index 7214b709..8ba0bf74 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -4769,6 +4769,14 @@ def test_annotated_in_other_types(self): X = List[Annotated[T, 5]] self.assertEqual(X[int], List[Annotated[int, 5]]) + def test_nested_annotated_with_unhashable_metadata(self): + X = Annotated[ + List[Annotated[str, {"unhashable_metadata"}]], + "metadata" + ] + self.assertEqual(X.__origin__, List[Annotated[str, {"unhashable_metadata"}]]) + self.assertEqual(X.__metadata__, ("metadata",)) + class GetTypeHintsTests(BaseTestCase): def test_get_type_hints(self): diff --git a/src/typing_extensions.py b/src/typing_extensions.py index abf6f41e..46084fa5 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -2958,9 +2958,9 @@ def _has_generic_or_protocol_as_origin() -> bool: except AttributeError: return False # err on the side of leniency else: - return frame.f_locals.get("origin") in { + return frame.f_locals.get("origin") in ( typing.Generic, Protocol, typing.Protocol - } + ) _TYPEVARTUPLE_TYPES = {TypeVarTuple, getattr(typing, "TypeVarTuple", None)}