diff options
author | Alex Waygood <Alex.Waygood@Gmail.com> | 2023-12-04 15:41:41 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-04 15:41:41 (GMT) |
commit | c718ab92a584fa658b6a626a744f5a71a048b47c (patch) | |
tree | 15a1a786040fe90f2e93d765be483955a7901d15 /Lib/typing.py | |
parent | 9560e0d6d7a316341939b4016e47e03bd5bf17c3 (diff) | |
download | cpython-c718ab92a584fa658b6a626a744f5a71a048b47c.zip cpython-c718ab92a584fa658b6a626a744f5a71a048b47c.tar.gz cpython-c718ab92a584fa658b6a626a744f5a71a048b47c.tar.bz2 |
gh-74690: Optimise `isinstance()` and `issubclass()` calls against runtime-checkable protocols by avoiding costly `super()` calls (#112708)
Diffstat (limited to 'Lib/typing.py')
-rw-r--r-- | Lib/typing.py | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/Lib/typing.py b/Lib/typing.py index 4c19aad..aa64ed9 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1782,6 +1782,14 @@ copyreg.pickle(ParamSpecKwargs, _pickle_pskwargs) del _pickle_psargs, _pickle_pskwargs +# Preload these once, as globals, as a micro-optimisation. +# This makes a significant difference to the time it takes +# to do `isinstance()`/`issubclass()` checks +# against runtime-checkable protocols with only one callable member. +_abc_instancecheck = ABCMeta.__instancecheck__ +_abc_subclasscheck = ABCMeta.__subclasscheck__ + + class _ProtocolMeta(ABCMeta): # This metaclass is somewhat unfortunate, # but is necessary for several reasons... @@ -1841,7 +1849,7 @@ class _ProtocolMeta(ABCMeta): "Instance and class checks can only be used with " "@runtime_checkable protocols" ) - return super().__subclasscheck__(other) + return _abc_subclasscheck(cls, other) def __instancecheck__(cls, instance): # We need this method for situations where attributes are @@ -1850,7 +1858,7 @@ class _ProtocolMeta(ABCMeta): return type.__instancecheck__(cls, instance) if not getattr(cls, "_is_protocol", False): # i.e., it's a concrete subclass of a protocol - return super().__instancecheck__(instance) + return _abc_instancecheck(cls, instance) if ( not getattr(cls, '_is_runtime_protocol', False) and @@ -1859,7 +1867,7 @@ class _ProtocolMeta(ABCMeta): raise TypeError("Instance and class checks can only be used with" " @runtime_checkable protocols") - if super().__instancecheck__(instance): + if _abc_instancecheck(cls, instance): return True getattr_static = _lazy_load_getattr_static() |