@@ -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 ):
@@ -2000,24 +2000,32 @@ class _ProtocolMeta(ABCMeta):
2000
2000
def __instancecheck__ (cls , instance ):
2001
2001
# We need this method for situations where attributes are
2002
2002
# assigned in __init__.
2003
+ is_protocol_cls = getattr (cls , "_is_protocol" , False )
2003
2004
if (
2004
- getattr ( cls , '_is_protocol' , False ) and
2005
+ is_protocol_cls and
2005
2006
not getattr (cls , '_is_runtime_protocol' , False ) and
2006
2007
not _allow_reckless_class_checks (depth = 2 )
2007
2008
):
2008
2009
raise TypeError ("Instance and class checks can only be used with"
2009
2010
" @runtime_checkable protocols" )
2010
2011
2011
- if ((not getattr (cls , '_is_protocol' , False ) or
2012
- _is_callable_members_only (cls )) and
2013
- issubclass (instance .__class__ , cls )):
2012
+ if not is_protocol_cls and issubclass (instance .__class__ , cls ):
2014
2013
return True
2015
- if cls ._is_protocol :
2014
+
2015
+ protocol_attrs = _get_protocol_attrs (cls )
2016
+
2017
+ if (
2018
+ _is_callable_members_only (cls , protocol_attrs )
2019
+ and issubclass (instance .__class__ , cls )
2020
+ ):
2021
+ return True
2022
+
2023
+ if is_protocol_cls :
2016
2024
if all (hasattr (instance , attr ) and
2017
2025
# All *methods* can be blocked by setting them to None.
2018
2026
(not callable (getattr (cls , attr , None )) or
2019
2027
getattr (instance , attr ) is not None )
2020
- for attr in _get_protocol_attrs ( cls ) ):
2028
+ for attr in protocol_attrs ):
2021
2029
return True
2022
2030
return super ().__instancecheck__ (instance )
2023
2031
@@ -2074,7 +2082,10 @@ def _proto_hook(other):
2074
2082
return NotImplemented
2075
2083
raise TypeError ("Instance and class checks can only be used with"
2076
2084
" @runtime_checkable protocols" )
2077
- if not _is_callable_members_only (cls ):
2085
+
2086
+ protocol_attrs = _get_protocol_attrs (cls )
2087
+
2088
+ if not _is_callable_members_only (cls , protocol_attrs ):
2078
2089
if _allow_reckless_class_checks ():
2079
2090
return NotImplemented
2080
2091
raise TypeError ("Protocols with non-method members"
@@ -2084,7 +2095,7 @@ def _proto_hook(other):
2084
2095
raise TypeError ('issubclass() arg 1 must be a class' )
2085
2096
2086
2097
# Second, perform the actual structural compatibility check.
2087
- for attr in _get_protocol_attrs ( cls ) :
2098
+ for attr in protocol_attrs :
2088
2099
for base in other .__mro__ :
2089
2100
# Check if the members appears in the class dictionary...
2090
2101
if attr in base .__dict__ :
0 commit comments