Skip to content

typing: one None-valued member makes isinstance() on a runtime_checkable Protocol O(N) per call #156413

Description

@adamtheturtle

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions