Skip to content

Error feedback for unions of lists that should be unions of sequences is not as helpful as it could be #5895

@toolness

Description

@toolness

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.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions