From b4ddcc9671496bec6a1a7f3b322e0ac554816c87 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Fri, 31 Mar 2023 19:28:29 +0100 Subject: [PATCH 1/2] gh-74690: Micro-optimise `typing._get_protocol_attrs` --- Lib/typing.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/Lib/typing.py b/Lib/typing.py index 3d086dc1cb90bb..3bedd794d58581 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1903,15 +1903,19 @@ class _TypingEllipsis: """Internal placeholder for ... (ellipsis).""" -_TYPING_INTERNALS = ['__parameters__', '__orig_bases__', '__orig_class__', - '_is_protocol', '_is_runtime_protocol'] +_TYPING_INTERNALS = frozenset({ + '__parameters__', '__orig_bases__', '__orig_class__', + '_is_protocol', '_is_runtime_protocol' +}) -_SPECIAL_NAMES = ['__abstractmethods__', '__annotations__', '__dict__', '__doc__', - '__init__', '__module__', '__new__', '__slots__', - '__subclasshook__', '__weakref__', '__class_getitem__'] +_SPECIAL_NAMES = frozenset({ + '__abstractmethods__', '__annotations__', '__dict__', '__doc__', + '__init__', '__module__', '__new__', '__slots__', + '__subclasshook__', '__weakref__', '__class_getitem__' +}) # These special attributes will be not collected as protocol members. -EXCLUDED_ATTRIBUTES = _TYPING_INTERNALS + _SPECIAL_NAMES + ['_MutableMapping__marker'] +EXCLUDED_ATTRIBUTES = _TYPING_INTERNALS | _SPECIAL_NAMES | {'_MutableMapping__marker'} def _get_protocol_attrs(cls): @@ -1922,10 +1926,9 @@ def _get_protocol_attrs(cls): """ attrs = set() for base in cls.__mro__[:-1]: # without object - if base.__name__ in ('Protocol', 'Generic'): + if base.__name__ in {'Protocol', 'Generic'}: continue - annotations = getattr(base, '__annotations__', {}) - for attr in list(base.__dict__.keys()) + list(annotations.keys()): + for attr in (*base.__dict__, *base.__annotations__): if not attr.startswith('_abc_') and attr not in EXCLUDED_ATTRIBUTES: attrs.add(attr) return attrs From d6c3b657b0009d51fd94d29347a019a68c5316e0 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Fri, 31 Mar 2023 21:26:40 +0100 Subject: [PATCH 2/2] Revert direct __annotations__ access --- Lib/typing.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/typing.py b/Lib/typing.py index 3bedd794d58581..a88542cfbaecd5 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1928,7 +1928,8 @@ def _get_protocol_attrs(cls): for base in cls.__mro__[:-1]: # without object if base.__name__ in {'Protocol', 'Generic'}: continue - for attr in (*base.__dict__, *base.__annotations__): + annotations = getattr(base, '__annotations__', {}) + for attr in (*base.__dict__, *annotations): if not attr.startswith('_abc_') and attr not in EXCLUDED_ATTRIBUTES: attrs.add(attr) return attrs