Open sterliakov opened 2 years ago
Same thing with unsafe variance in protocol inheritance:
from typing import Protocol, _T_co as T_co
class A(Protocol[T_co]): # type: ignore
def foo(self, t: T_co) -> None: ... # type: ignore
class B(A[T_co], Protocol): # ERROR! using covariant type variable where invariant one expected!!!
def bar(self) -> T_co: ...
For some reason this is allowed for attrbutes. Seems inconsistent:
https://gist.github.com/b092b7a5ac44a8e25950c810b4c7678e
class A:
attr: int
class B(A):
attr: str # type: ignore
class C(B): # This is considered OK
attr: str
Feature
When a subclass is implemented with unsafe method override, error can be suppressed with
# type: ignore[override]
comment. However, further subclassing requires this comment to be present in subclasses too.Pitch
Suppose we have the following structure:
Currently
mypy
complains:But in reality we do expect that all
B
subclasses should implementfoo
with signature() -> str
. For instance, it is useful whenB
is replacement forA
with slightly different usage (when we don't want to replicate all internal logic - e.g. if it comes from third-party package). It takes care to override all methods that became incompatible after this change, and nowB
is consistent. Then we want to add some feature toB
via subclassing while preserving its interface. All signatures are preserved, butmypy
complains that we are incompatible with old base (A
). I think that when unsafe override is explicitly ignored once,mypy
should check new implementation against definitions inB
, not inA
, ignoring the fact thatB
has unsafe overrides. Actually now the checker reports errors that are explicitly ignored: we already took care toignore
that errors insideB
.Real world example:
ModelChoiceField
in Django inherits fromChoiceField
(yeah, that's bad design decision, but I'm working on stubs and can't change the source). Incompatible part:When end Django user tries to subclass
ModelChoiceField
and implementsto_python
with same signature, user receivesmypy
error. However, this implementation is perfectly valid as long as direct superclass already defines that incompatible change.