Skip to content

How should subtyping work with respect to properties? #1364

Closed as not planned
@AlexWaygood

Description

@AlexWaygood

Consider the following snippet:

from abc import abstractmethod
from typing import Protocol

class HasX(Protocol):
    @property
    @abstractmethod
    def x(self) -> int: ...

class Nominal(HasX):
    @property
    def x(self) -> int:
        raise AttributeError

class Structural:
    @property
    def x(self) -> int:
        raise AttributeError

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

needs_obj_with_x(Nominal())
needs_obj_with_x(Structural())

This snippet will fail at runtime, as accessing the x attribute on either an instance of Nominal or an instance of Structural will result in AttributeError being raised. However, neither mypy nor pyright sees any issue with this code, which surprises me. I would have expected a type checker to complain about the Nominal.x property and the Structural.x property, since they are both annotated as returning int yet neither of them will ever return an int. I would have expected a type checker to demand that the x property on both Nominal and Structural should either have at least one return statement (that returns an int), or should be explicitly decorated with @abstractmethod.

Is this a missing feature from mypy and pyright? Or is there a reason for this not to be implemented?

(I haven't checked the behaviour of other type checkers.)

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