python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.34k stars 2.81k forks source link

assignment to `_` inside a function incorrectly becomes `Any` #17697

Open DetachHead opened 2 months ago

DetachHead commented 2 months ago
def foo() -> None:
    _ = [1] # error: no-any-expr

playground

brianschubert commented 3 weeks ago

To my understanding, this is caused by:

  1. Definitions of _ are treated as having an implicit type of Any (per here).
  2. mypy treats [1] as a call to a hidden def [T] (*T) -> list[T] function, where the type variable T needs to be resolved using the ordinary type inference rules.
  3. When inferring the type of a function, mypy prioritizes information from the type context. Here the type context says that the return type of the function needs to be compatible with Any. This ultimately causes mypy to prematurely resolve the type of the list constructor from def [T] (*T) -> list[T] to def (*Any) -> list[Any] on this line. Hence [1] is inferred to have type list[Any], cue the error.

I think this is the same underlying issue as #14664. In both cases, mypy infers the type of a callable to something overly broad when a type context is present, and infers a stricter type when the type context is removed.

brianschubert commented 2 weeks ago

Possible duplicate of #15253