Skip to content

Infer variable type if initializer is an empty collection #1055

@JukkaL

Description

@JukkaL

Code like this is one of the most common cases where we need a variable annotation (DONE):

def f() -> None:
    x = []   # mypy insists on annotation (such as List[int]) here
    for i in range(5):
        x.append(i * 2)

Mypy could do a better job of inferring types in cases like these:

  • Variable is initialized with an empty collection (or more generally, a generic type where the type argument values are indeterminate using only local statement context).
  • The first reference to the variable after initialization (in the same scope) mutates the collection and allows us to infer the item types.

These cases would still require an annotation:

  • Collection is read after initialization and before mutation (this happens sometimes but not too often).
  • The variable is not mutated in the scope that initializes it. For example, an attribute is initialized in __init__ and mutated in another method.

This is related to #254.

More common examples where this should work:

(1) DONE

x = {}
x['key'] = 2

(2) DONE

x = set()
x.add(2)

Additional, less common examples (not done):

(3) [postponed -- too rare and complicated]

x = {}
x.setdefault('key', []).append(1)   # this is harder than most examples

(4) DONE

x = {}
x.update({'x': 1})

(5) [rejected -- too rare]

x = set()
x |= {1, 2}

(6) DONE (#8036)

if cond():
    x = []
else:
    x = [1]

(7) DONE (#8167 and #8039)

Similar to above but with a user-defined generic type or a standard library generic type that is not list, dict or set.

Update: After some more analysis, only defaultdict and OrderedDict seem common enough to support.

Not sure about this:

(8) [rejected idea]

x = []
foo(x)  # Should we infer type of x from the argument type? Probably not.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy