-
Couldn't load subscription status.
- Fork 275
Description
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.)