A Protocol with @runtime_checkable is classified as either Data or non-Data Protocol, with the former not being allowed for use in issubclass checks. A Data Protocol is any Protocol that “contains at least one non-method member” as per the typing spec. There is some ambiguity with this formulation (see a recent PyRight issue of mine):
Is this a strict definition, in that literally any non-method member of the Protocol makes it a Data Protocol? Or are there certain things that are technically non-method members of the Protocol itself, but don’t count for the classification?
I am specifically wondering about __slots__ = () here. While it itself is a non-method member (it is after all a regular attribute) the meaning is that there are no attributes. Should this be considered a Data Protocol or not?
from typing import Protocol, runtime_checkable
@runtime_checkable
class DataOrNonData(Protocol):
__slots__ = ()
def just_some_method(self) -> int: ...
- PyRight (v1.1.406, possibly since v1.1.345) considers this a Data Protocol and rejects its use in
issubclass. MyPy (v1.18.2) accepts its use inissubclass. typesheduses this pattern fortyping.SupportsXYZandcontextlib.Abstract(Async)ContextManager.