-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mypy claims compatible types are incompatible when non-related mixin classes are present #12440
Comments
Easier workaround is I will change MixinWDesc alone: class MixinWDesc:
description: Optional[str] |
This error is correct. Your type annotations define a read-write attribute, so a function that gets an object To prevent this error, make the attribute read-only by using a property. |
why does |
also I generally cant use |
nope , it doesn't work: from typing import Optional, TypeVar, Generic, Any, Callable, overload, Union
_T_co = TypeVar("_T_co", covariant=True)
_GFDRO = TypeVar("_GFDRO", bound="generic_ro_descriptor[Any]")
class generic_ro_descriptor(Generic[_T_co]):
fget: Callable[..., _T_co]
__doc__: Optional[str]
__name__: str
def __init__(self, fget: Callable[..., _T_co], doc: Optional[str] = None):
self.fget = fget # type: ignore[assignment]
self.__doc__ = doc or fget.__doc__
self.__name__ = fget.__name__
@overload
def __get__(self: _GFDRO, obj: None, cls: Any) -> _GFDRO:
...
@overload
def __get__(self, obj: object, cls: Any) -> _T_co:
...
def __get__(self: _GFDRO, obj: Any, cls: Any) -> Union[_GFDRO, _T_co]:
raise NotImplementedError()
# whether or not these are here
def __set__(self, instance: Any, value: Any) -> NoReturn:
...
def __delete__(self, instance: Any) -> NoReturn:
...
class Base:
@generic_ro_descriptor
def description(self) -> Optional[str]:
...
class MixinWDesc:
@generic_ro_descriptor
def description(self) -> str:
...
class SubClass(MixinWDesc, Base):
@generic_ro_descriptor
def description(self) -> str:
...
class SomeOtherMixin:
pass
# succeeds
class ImplementsWOMixin(SubClass):
pass
# fails:
# Definition of "description" in base class "MixinWDesc" is incompatible with definition in base class "Base"
class ImplementsWMixin(SomeOtherMixin, SubClass):
pass is |
OK, I guess I will try to use the "tell typing it's |
Good point, it should complain about |
still wondering if there's any way to make my own descriptor that is not I still encounter inconvenient behaviors with |
or otherwise, if the whole "mypy has a special rule that @Property can be used to make a read only field" could be better documented, the only mention I can find for this concept is as a passing phrase here, "You can use @property to make an attribute read-only, but unlike Final, it doesn’t work with module attributes, and it doesn’t prevent overriding in subclasses." that whole concept ("you can use I would gladly contribute this documentation if I myself knew the behaviors well, but I only have a vague concept right now. |
as always, I apologize if this falls into one of the categories of "that's expected, because what if you did this?" and/or "this is a known mypy limitation / issue number", this one does not have a great workaround since I'd have to "type:ignore" the class def itself, or have to add redundant attributes everywhere, and I will likely just re-organize the code to not have this particular issue.
Here's the demo -
ImplementsWOMixin
andImplementsWMixin
are basically the same class except one of them has an extra entry in its__bases__
. mypy then decides that a local attribute that returnsstr
instead ofOptional[str]
is no longer compatible with the base class:output - it complains about
MixinWDesc
, but the line number is that of theImplementsWMixin
class itself, meaning every class that subclassesMixinWDesc
and uses other mixins would need workarounds or type:ignores.The text was updated successfully, but these errors were encountered: