A class satisfying a @runtime_checkable Protocol with any class attribute set to None still passes isinstance(), but is orders of magnitude slower, scaling linearly with member count. Best of 5 runs of 20,000 calls, at 5/20/50/110 members: 25x/84x/316x/735x slower.
import timeit
from typing import Protocol, runtime_checkable
@runtime_checkable
class P(Protocol):
@property
def a(self) -> bool: ...
@property
def b(self) -> bool: ...
class Good:
a = b = True
class Bad:
a, b = True, None
for x in (Good(), Bad()):
print(isinstance(x, P), timeit.timeit(lambda: isinstance(x, P), number=100_000))
On 3.13.13: True 0.0121 then True 0.1207. Only the timing differs.
A class satisfying a
@runtime_checkableProtocol with any class attribute set toNonestill passesisinstance(), but is orders of magnitude slower, scaling linearly with member count. Best of 5 runs of 20,000 calls, at 5/20/50/110 members: 25x/84x/316x/735x slower.On 3.13.13:
True 0.0121thenTrue 0.1207. Only the timing differs.