diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index c6f08ff8a052ab..e7bf94ee8cc1e8 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4574,6 +4574,19 @@ def c(self) -> int: return 5 with self.assertRaisesRegex(TypeError, "not a Protocol"): get_protocol_members(ConcreteInherit()) + def test_get_protocol_members_named_protocol_or_generic(self): + # gh-145688: Protocols named "Protocol" or "Generic" should still + # have their members collected correctly. + class Protocol(typing.Protocol): + a: int + + self.assertEqual(get_protocol_members(Protocol), {'a'}) + + class Generic(typing.Protocol): + b: str + + self.assertEqual(get_protocol_members(Generic), {'b'}) + def test_is_protocol(self): self.assertTrue(is_protocol(Proto)) self.assertTrue(is_protocol(Point)) diff --git a/Lib/typing.py b/Lib/typing.py index e78fb8b71a996c..d1fbc893b37d7c 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1884,7 +1884,7 @@ def _get_protocol_attrs(cls): """ attrs = set() for base in cls.__mro__[:-1]: # without object - if base.__name__ in {'Protocol', 'Generic'}: + if base is Protocol or base is Generic: continue try: annotations = base.__annotations__ diff --git a/Misc/NEWS.d/next/Library/2026-03-09-00-00-00.gh-issue-145688.protocol-name.rst b/Misc/NEWS.d/next/Library/2026-03-09-00-00-00.gh-issue-145688.protocol-name.rst new file mode 100644 index 00000000000000..27839f9c52976e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-09-00-00-00.gh-issue-145688.protocol-name.rst @@ -0,0 +1,2 @@ +Fixed :func:`typing.get_protocol_members` returning empty results for +:class:`typing.Protocol` subclasses named ``"Protocol"`` or ``"Generic"``.