-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Closed
Description
Sorry this issue has such an odd title, but I was about to report a mypy bug based on the following code:
from typing import List, Union
from enum import Enum
class Boop(Enum):
FOO = 1
BAR = 2
def do_thing_with_enums(enums: Union[List[Enum], Enum]) -> None:
if isinstance(enums, Enum):
enums = list([enums])
for thing in enums:
thing.value
class Funky:
boop: List[Boop]
def boop_it_up(self) -> None:
do_thing_with_enums(self.boop)The mypy error output for the following code is:
boop.py:21: error: Argument 1 to "do_thing_with_enums" has incompatible type "List[Boop]"; expected "Union[List[Enum], Enum]"
I found this quite confusing since List[Boop] is also a List[Enum], which I thought was a mypy bug.
However, after a lot of tinkering, I simplified the do_thing_with_enums signature to be:
def do_thing_with_enums(enums: List[Enum]) -> None:at this point mypy still failed, but it gave me much better error feedback:
boop.py:21: error: Argument 1 to "do_thing_with_enums" has incompatible type "List[Boop]"; expected "List[Enum]"
boop.py:21: note: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance
boop.py:21: note: Consider using "Sequence" instead, which is covariant
After converting the type annotation to use Sequence instead of List, everything worked fine. I just wished it had given me such excellent advice for my original type annotation, rather than requiring me to simplify it, if that makes sense.