From ec4051ad0bb9284a27d47a55ef8153ad35541d34 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Mon, 4 Dec 2023 14:13:48 +0000 Subject: [PATCH 1/3] gh-74690: Optimise `isinstance()` and `issubclass()` calls against runtime-checkable protocols by avoiding costly `super()` calls --- Lib/typing.py | 14 +++++++++++--- .../2023-12-04-14-05-24.gh-issue-74690.eODKRm.rst | 4 ++++ 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-12-04-14-05-24.gh-issue-74690.eODKRm.rst 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. From ff333fd83617f574ca09571786f40a2ccc8fbbee Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Mon, 4 Dec 2023 14:18:26 +0000 Subject: [PATCH 2/3] fix NEWS --- .../2023-12-04-14-05-24.gh-issue-74690.eODKRm.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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 index 417c86c7519840..7baf8d5ddbc9ef 100644 --- 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 @@ -1,4 +1,5 @@ -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. +Speedup :func:`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. From a7d76f6d6644acc2a7d0c1a16909be442b0c9930 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Mon, 4 Dec 2023 14:19:57 +0000 Subject: [PATCH 3/3] actually fix NEWS --- .../next/Library/2023-12-04-14-05-24.gh-issue-74690.eODKRm.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 7baf8d5ddbc9ef..36d793f787302e 100644 --- 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 @@ -1,5 +1,5 @@ Speedup :func:`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%. +Speedup :func:`issubclass` checks for these protocols by roughly 10%. Patch by Alex Waygood.