mirror of
https://github.com/python/cpython
synced 2024-10-14 13:38:02 +00:00
gh-74690: Optimise isinstance()
and issubclass()
calls against runtime-checkable protocols by avoiding costly super()
calls (#112708)
This commit is contained in:
parent
9560e0d6d7
commit
c718ab92a5
|
@ -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()
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
Speedup :func:`isinstance` checks by roughly 20% for
|
||||
:func:`runtime-checkable protocols <typing.runtime_checkable>`
|
||||
that only have one callable member.
|
||||
Speedup :func:`issubclass` checks for these protocols by roughly 10%.
|
||||
Patch by Alex Waygood.
|
Loading…
Reference in a new issue