You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
are inferred as the mixin class when added to a list
To Reproduce
This works:
class SuperDuperClass: ...
class MixinClass: ...
class ConcreteWorkerClass(SuperDuperClass, MixinClass):
...
class ConcreteWorkerClass2(SuperDuperClass, MixinClass):
...
def do_stuff_with_workers(workers: list[SuperDuperClass]):
...
concrete_workers = [ConcreteWorkerClass(), ConcreteWorkerClass2()]
do_stuff_with_workers(concrete_workers)
On the last line, this raises the error error: Argument 1 to "do_stuff_with_workers" has incompatible type "list[MixinClass]"; expected "list[SuperDuperClass[Any]]" [arg-type]:
from typing import Generic, TypeVar
T = TypeVar('T')
class SuperDuperClass(Generic[T]): ...
class MixinClass: ...
class ConcreteWorkerClass(SuperDuperClass[int], MixinClass):
...
class ConcreteWorkerClass2(SuperDuperClass[float], MixinClass):
...
def do_stuff_with_workers(workers: list[SuperDuperClass]):
...
concrete_workers = [ConcreteWorkerClass(), ConcreteWorkerClass2()]
do_stuff_with_workers(concrete_workers)
I think this is just join-v-union. I recommend explicitly telling mypy what type to use via a type hint like concrete_workers: ... = ....
(join-v-union just being "should mypy try to come up with a short description that all the classes match? or should mypy just be lazy and say it's just the union of the types")
Thanks for the quick response! concrete_workers: list[SuperDuperClass] = [ConcreteWorkerClass(), ConcreteWorkerClass2()] does suppress the mypy error. I think I understand why it happens based on your explanation.
This is for a library API, so we would be asking users of our package to do that. We can help the situation with API documentation, but at the end of the day I'm still hoping there is something that can be done on the mypy side.
You could add an intermediate class (ie class IntermediateClass(SuperDuperClass[T], MixinClass)) that both workers inherit from. I think mypy should choose that (if not then I don't know another way). Then do_stuff_with_workers would need to take a Sequence due to variance.
Otherwise mypy's behavior is generally switching to prefer unions so you could wait for this issue to be solved (but it may take a while).
Adding the intermediate class doesn't really work for my use case given that the generic typevar can be almost anything. It's being used to narrow a type from Any. We would be asking implementers to add that intermediate class for most classes they write. I think we will document it and hope this issue is solved eventually.
Bug Report
Subclasses of 2 classes:
are inferred as the mixin class when added to a
list
To Reproduce
This works:
On the last line, this raises the error
error: Argument 1 to "do_stuff_with_workers" has incompatible type "list[MixinClass]"; expected "list[SuperDuperClass[Any]]" [arg-type]
:Expected Behavior
No type error
Actual Behavior
Type error
Your Environment
1.13.0
--disallow-untyped-decorators
3.11
The text was updated successfully, but these errors were encountered: