@@ -1931,9 +1931,9 @@ def _get_protocol_attrs(cls):
1931
1931
return attrs
1932
1932
1933
1933
1934
- def _is_callable_members_only (cls ):
1934
+ def _is_callable_members_only (cls , protocol_attrs ):
1935
1935
# PEP 544 prohibits using issubclass() with protocols that have non-method members.
1936
- return all (callable (getattr (cls , attr , None )) for attr in _get_protocol_attrs ( cls ) )
1936
+ return all (callable (getattr (cls , attr , None )) for attr in protocol_attrs )
1937
1937
1938
1938
1939
1939
def _no_init_or_replace_init (self , * args , ** kwargs ):
@@ -2008,16 +2008,18 @@ def __instancecheck__(cls, instance):
2008
2008
raise TypeError ("Instance and class checks can only be used with"
2009
2009
" @runtime_checkable protocols" )
2010
2010
2011
+ protocol_attrs = _get_protocol_attrs (cls )
2012
+
2011
2013
if ((not getattr (cls , '_is_protocol' , False ) or
2012
- _is_callable_members_only (cls )) and
2014
+ _is_callable_members_only (cls , protocol_attrs )) and
2013
2015
issubclass (instance .__class__ , cls )):
2014
2016
return True
2015
2017
if cls ._is_protocol :
2016
2018
if all (hasattr (instance , attr ) and
2017
2019
# All *methods* can be blocked by setting them to None.
2018
2020
(not callable (getattr (cls , attr , None )) or
2019
2021
getattr (instance , attr ) is not None )
2020
- for attr in _get_protocol_attrs ( cls ) ):
2022
+ for attr in protocol_attrs ):
2021
2023
return True
2022
2024
return super ().__instancecheck__ (instance )
2023
2025
@@ -2074,7 +2076,10 @@ def _proto_hook(other):
2074
2076
return NotImplemented
2075
2077
raise TypeError ("Instance and class checks can only be used with"
2076
2078
" @runtime_checkable protocols" )
2077
- if not _is_callable_members_only (cls ):
2079
+
2080
+ protocol_attrs = _get_protocol_attrs (cls )
2081
+
2082
+ if not _is_callable_members_only (cls , protocol_attrs ):
2078
2083
if _allow_reckless_class_checks ():
2079
2084
return NotImplemented
2080
2085
raise TypeError ("Protocols with non-method members"
@@ -2084,7 +2089,7 @@ def _proto_hook(other):
2084
2089
raise TypeError ('issubclass() arg 1 must be a class' )
2085
2090
2086
2091
# Second, perform the actual structural compatibility check.
2087
- for attr in _get_protocol_attrs ( cls ) :
2092
+ for attr in protocol_attrs :
2088
2093
for base in other .__mro__ :
2089
2094
# Check if the members appears in the class dictionary...
2090
2095
if attr in base .__dict__ :
0 commit comments