Skip to content

Use type context to infer type of empty collections in and/or expressions #6572

Closed
@zunger-humu

Description

@zunger-humu

Underlying issue: for any generic type, mypy considers GenType[] and GenType[X] to be incompatible classes. These should instead be considered to be of type GenType[X]. (Observed with mypy 0.670 / Python 3.6, no flags passed to mypy)

To illustrate why, consider two common Python idioms where this happens. One is in a function declaration, where None is passed as a default value rather than a class-scoped mutable variable:

def fn(arg: Set[str] = None) -> None:
    arg = arg or set()
    ...

This is reported as an error, "Incompatible types in assignment (expression has type "Union[Set[str], Set[]]", variable has type "Optional[Set[str]]")"

Likewise, if an abstract superclass declares a method which yields an iterator,

def abstractMethod(self) -> Iterator[...]:
    pass

Because the abstract declaration passes, it is actually returning an optional iterator (which mypy correctly understands). Callers of the abstract method then cope with this easily:

for value in (thing.abstractMethod() or []):
   ...

which yields the same error as above, or

yield from (thing.abstractMethod() or [])

which fails with "error: "yield from" can't be applied to "Union[Iterator[type], List[]]".

The expected behavior in all cases is no error: empty iterables should be considered to be valid instances of iterables of any type, without further annotation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions