Skip to content

How should structural subtyping work for objects with slots but no variable declarations? #1367

Closed
@AlexWaygood

Description

@AlexWaygood

Consider the snippet below:

from typing import runtime_checkable, Protocol

@runtime_checkable
class HasX(Protocol):
    x: int

class HasNothingButSlots:
    __slots__ = ("x",)

def requires_object_with_x(obj: HasX) -> None:
    print(obj.x)

requires_object_with_x(HasNothingButSlots())

Mypy does not see HasNothingButSlots as a valid subtype of of HasX, so complains about this code. Pyright, however, does see HasNothingButSlots as a valid subtype of HasX, so has no complaints.

Currently, the runtime agrees with mypy: calling isinstance(HasNothingButSlots(), HasX) evaluates to False (due to the fact that the x variable has not been initialised on the instance). If we implement any of the patches discussed in #1363, this will change, and the runtime will agree with pyright: isinstance(HasNothingButSlots(), HasX) will evaluate to True even if the x variable has not been initialised on the instance.

Who is correct: mypy or pyright?

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: otherOther topics not covered

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions