diff options
author | Alex Waygood <Alex.Waygood@Gmail.com> | 2023-04-02 13:22:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-02 13:22:19 (GMT) |
commit | 6d59c9e32ebb6d8468c7eb26e7cf3efd458c7a73 (patch) | |
tree | 908d594aba573e0e8d2e2b7edb87a8b4a93101df /Lib/typing.py | |
parent | d828b35785eeb590b8ca92684038f33177989e46 (diff) | |
download | cpython-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.py | 26 |
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) |