diff --git a/Lib/typing.py b/Lib/typing.py index 4c19aadabe3b87..aa64ed93f76fbf 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1782,6 +1782,14 @@ def _pickle_pskwargs(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 @@ def __subclasscheck__(cls, other): "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 @@ def __instancecheck__(cls, instance): 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 @@ def __instancecheck__(cls, instance): 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() diff --git a/Misc/NEWS.d/next/Library/2023-12-04-14-05-24.gh-issue-74690.eODKRm.rst b/Misc/NEWS.d/next/Library/2023-12-04-14-05-24.gh-issue-74690.eODKRm.rst new file mode 100644 index 00000000000000..417c86c7519840 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-04-14-05-24.gh-issue-74690.eODKRm.rst @@ -0,0 +1,4 @@ +Speedup `isinstance()` checks by roughly 20% for :func:`runtime-checkable +protocols ` that only have one callable member. +Speedup `issubclass()` checks for these protocols by roughly 10%. Patch by +Alex Waygood.