@@ -1935,9 +1935,9 @@ def _get_protocol_attrs(cls):
1935
1935
return attrs
1936
1936
1937
1937
1938
- def _is_callable_members_only (cls , protocol_attrs ):
1938
+ def _is_callable_members_only (cls ):
1939
1939
# PEP 544 prohibits using issubclass() with protocols that have non-method members.
1940
- return all (callable (getattr (cls , attr , None )) for attr in protocol_attrs )
1940
+ return all (callable (getattr (cls , attr , None )) for attr in cls . __protocol_attrs__ )
1941
1941
1942
1942
1943
1943
def _no_init_or_replace_init (self , * args , ** kwargs ):
@@ -2016,20 +2016,19 @@ def __instancecheck__(cls, instance):
2016
2016
if not is_protocol_cls and issubclass (instance .__class__ , cls ):
2017
2017
return True
2018
2018
2019
- protocol_attrs = _get_protocol_attrs (cls )
2019
+ if not hasattr (cls , "__protocol_attrs__" ):
2020
+ cls .__protocol_attrs__ = _get_protocol_attrs (cls )
2021
+ cls .__callable_proto_members_only__ = _is_callable_members_only (cls )
2020
2022
2021
- if (
2022
- _is_callable_members_only (cls , protocol_attrs )
2023
- and issubclass (instance .__class__ , cls )
2024
- ):
2023
+ if cls .__callable_proto_members_only__ and issubclass (instance .__class__ , cls ):
2025
2024
return True
2026
2025
2027
2026
if is_protocol_cls :
2028
2027
if all (hasattr (instance , attr ) and
2029
2028
# All *methods* can be blocked by setting them to None.
2030
2029
(not callable (getattr (cls , attr , None )) or
2031
2030
getattr (instance , attr ) is not None )
2032
- for attr in protocol_attrs ):
2031
+ for attr in cls . __protocol_attrs__ ):
2033
2032
return True
2034
2033
return super ().__instancecheck__ (instance )
2035
2034
@@ -2087,9 +2086,11 @@ def _proto_hook(other):
2087
2086
raise TypeError ("Instance and class checks can only be used with"
2088
2087
" @runtime_checkable protocols" )
2089
2088
2090
- protocol_attrs = _get_protocol_attrs (cls )
2089
+ if not hasattr (cls , "__protocol_attrs__" ):
2090
+ cls .__protocol_attrs__ = _get_protocol_attrs (cls )
2091
+ cls .__callable_proto_members_only__ = _is_callable_members_only (cls )
2091
2092
2092
- if not _is_callable_members_only ( cls , protocol_attrs ) :
2093
+ if not cls . __callable_proto_members_only__ :
2093
2094
if _allow_reckless_class_checks ():
2094
2095
return NotImplemented
2095
2096
raise TypeError ("Protocols with non-method members"
@@ -2099,7 +2100,7 @@ def _proto_hook(other):
2099
2100
raise TypeError ('issubclass() arg 1 must be a class' )
2100
2101
2101
2102
# Second, perform the actual structural compatibility check.
2102
- for attr in protocol_attrs :
2103
+ for attr in cls . __protocol_attrs__ :
2103
2104
for base in other .__mro__ :
2104
2105
# Check if the members appears in the class dictionary...
2105
2106
if attr in base .__dict__ :
0 commit comments