https://github.com/python/cpython/commit/666eeda13d319aa82b151eef3e3c55a48d90a052 commit: 666eeda13d319aa82b151eef3e3c55a48d90a052 branch: main author: Jelle Zijlstra <jelle.zijls...@gmail.com> committer: JelleZijlstra <jelle.zijls...@gmail.com> date: 2025-04-15T10:14:27-07:00 summary:
gh-132493: Support deferred annotations in Protocols (#132494) files: A Misc/NEWS.d/next/Library/2025-04-13-21-35-50.gh-issue-132493.5SAQJn.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 9f9e3eb17b9fc9..fc893807837eb9 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4554,6 +4554,15 @@ class Commentable(Protocol): ) self.assertIs(type(exc.__cause__), CustomError) + def test_deferred_evaluation_of_annotations(self): + class DeferredProto(Protocol): + x: DoesNotExist + self.assertEqual(get_protocol_members(DeferredProto), {"x"}) + self.assertEqual( + annotationlib.get_annotations(DeferredProto, format=annotationlib.Format.STRING), + {'x': 'DoesNotExist'} + ) + class GenericTests(BaseTestCase): diff --git a/Lib/typing.py b/Lib/typing.py index e5d14b03a4fc94..08b2ba356fc014 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1801,7 +1801,9 @@ def _get_protocol_attrs(cls): for base in cls.__mro__[:-1]: # without object if base.__name__ in {'Protocol', 'Generic'}: continue - annotations = getattr(base, '__annotations__', {}) + annotations = _lazy_annotationlib.get_annotations( + base, format=_lazy_annotationlib.Format.FORWARDREF + ) for attr in (*base.__dict__, *annotations): if not attr.startswith('_abc_') and attr not in EXCLUDED_ATTRIBUTES: attrs.add(attr) diff --git a/Misc/NEWS.d/next/Library/2025-04-13-21-35-50.gh-issue-132493.5SAQJn.rst b/Misc/NEWS.d/next/Library/2025-04-13-21-35-50.gh-issue-132493.5SAQJn.rst new file mode 100644 index 00000000000000..bda09e2356d56d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-04-13-21-35-50.gh-issue-132493.5SAQJn.rst @@ -0,0 +1,2 @@ +Support creation of :class:`typing.Protocol` classes with annotations that +cannot be resolved at class creation time. _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com