Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

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

Closed
zunger-humu opened this issue Mar 19, 2019 · 4 comments
Closed
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-2-low topic-type-context Type context / bidirectional inference

Comments

@zunger-humu
Copy link

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.

@ilevkivskyi
Copy link
Member

List[<nothing>] is not a subtype of List[X] because it is invariant, for example

x = []  # mypy would complain here, but assume we ignore it, so 'x' is 'List[<nothing>]'

y: List[str] = x  # this is dangerous
y.append('boom')

z: List[int] = x
z[0] + 42  # TypeError here

Instead mypy should use the outer type context to infer the correct type of an empty collection. I will edit the title accordingly.

@ilevkivskyi ilevkivskyi changed the title mypy doesn't recognize GenType[<nothing>] as a subclass of GenType[X] Use type context to infer type of empty collections in and/or expressions Apr 2, 2019
@ilevkivskyi
Copy link
Member

Also this is low priority since it may be tricky to implement one can instead simply write:

def func(lst: Optional[List[int]] = None) -> None:
    if lst is None:
        lst = []

(which is also more readable IMO)

@JukkaL
Copy link
Collaborator

JukkaL commented Apr 3, 2019

It might be reasonable to make List[<nothing>] a subtype of List[X] though (#6613).

@AlexWaygood
Copy link
Member

Cannot reproduce any of these false-positive errors on mypy 0.941; mypy seems to cope with these fine now.

@AlexWaygood AlexWaygood added bug mypy got something wrong topic-type-context Type context / bidirectional inference labels Mar 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-2-low topic-type-context Type context / bidirectional inference
Projects
None yet
Development

No branches or pull requests

4 participants