summaryrefslogtreecommitdiffstats
path: root/Lib/typing.py
diff options
context:
space:
mode:
authorAlex Waygood <Alex.Waygood@Gmail.com>2023-04-02 13:22:19 (GMT)
committerGitHub <noreply@github.com>2023-04-02 13:22:19 (GMT)
commit6d59c9e32ebb6d8468c7eb26e7cf3efd458c7a73 (patch)
tree908d594aba573e0e8d2e2b7edb87a8b4a93101df /Lib/typing.py
parentd828b35785eeb590b8ca92684038f33177989e46 (diff)
downloadcpython-6d59c9e32ebb6d8468c7eb26e7cf3efd458c7a73.zip
cpython-6d59c9e32ebb6d8468c7eb26e7cf3efd458c7a73.tar.gz
cpython-6d59c9e32ebb6d8468c7eb26e7cf3efd458c7a73.tar.bz2
gh-102433: Use `inspect.getattr_static` in `typing._ProtocolMeta.__instancecheck__` (#103034)
Diffstat (limited to 'Lib/typing.py')
-rw-r--r--Lib/typing.py26
1 files changed, 21 insertions, 5 deletions
diff --git a/Lib/typing.py b/Lib/typing.py
index a88542c..442d684 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -1998,6 +1998,17 @@ _PROTO_ALLOWLIST = {
}
+@functools.cache
+def _lazy_load_getattr_static():
+ # Import getattr_static lazily so as not to slow down the import of typing.py
+ # Cache the result so we don't slow down _ProtocolMeta.__instancecheck__ unnecessarily
+ from inspect import getattr_static
+ return getattr_static
+
+
+_cleanups.append(_lazy_load_getattr_static.cache_clear)
+
+
class _ProtocolMeta(ABCMeta):
# This metaclass is really unfortunate and exists only because of
# the lack of __instancehook__.
@@ -2025,12 +2036,17 @@ class _ProtocolMeta(ABCMeta):
return True
if is_protocol_cls:
- if all(hasattr(instance, attr) and
- # All *methods* can be blocked by setting them to None.
- (not callable(getattr(cls, attr, None)) or
- getattr(instance, attr) is not None)
- for attr in protocol_attrs):
+ getattr_static = _lazy_load_getattr_static()
+ for attr in protocol_attrs:
+ try:
+ val = getattr_static(instance, attr)
+ except AttributeError:
+ break
+ if callable(getattr(cls, attr, None)) and val is None:
+ break
+ else:
return True
+
return super().__instancecheck__(instance)