Skip to content

Commit

Permalink
fine-grained: Fix stripping of ForStmt.index_type (python#5245)
Browse files Browse the repository at this point in the history
`index_type` was populated during parsing, so stripping it
causes trouble. This changed the original type to be kept
in a new attribute.

Also *do* strip `inferred_iterator_type`, which is populated during
checking.
  • Loading branch information
msullivan authored and JukkaL committed Jun 22, 2018
1 parent 94fc51f commit ab2fb7b
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
3 changes: 3 additions & 0 deletions mypy/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,8 @@ class ForStmt(Statement):
index = None # type: Lvalue
# Type given by type comments for index, can be None
index_type = None # type: Optional[mypy.types.Type]
# Original, not semantically analyzed type in annotation (used for reprocessing)
unanalyzed_index_type = None # type: Optional[mypy.types.Type]
# Inferred iterable item type
inferred_item_type = None # type: Optional[mypy.types.Type]
# Inferred iterator type
Expand All @@ -975,6 +977,7 @@ def __init__(self,
super().__init__()
self.index = index
self.index_type = index_type
self.unanalyzed_index_type = index_type
self.expr = expr
self.body = body
self.else_body = else_body
Expand Down
3 changes: 2 additions & 1 deletion mypy/server/aststrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,9 @@ def visit_import_all(self, node: ImportAll) -> None:
node.imported_names = []

def visit_for_stmt(self, node: ForStmt) -> None:
node.index_type = None
node.index_type = node.unanalyzed_index_type
node.inferred_item_type = None
node.inferred_iterator_type = None
super().visit_for_stmt(node)

def visit_name_expr(self, node: NameExpr) -> None:
Expand Down
31 changes: 31 additions & 0 deletions test-data/unit/fine-grained.test
Original file line number Diff line number Diff line change
Expand Up @@ -7218,3 +7218,34 @@ x = [] # type: List
[builtins fixtures/list.pyi]
[out]
==

[case testRefreshForWithTypeComment1]
[file a.py]
from typing import List
import b
def foo(l: List[int]) -> None:
for x in l: # type: object
pass
x = object()
b.x
[file b.py]
x = 1
[file b.py.2]
x = '1'
[builtins fixtures/list.pyi]
[out]
==

[case testRefreshForWithTypeComment2]
from typing import List, Any
import m
def f(x: List[Any]) -> None:
for a in x: # type: m.A
pass
[file m.py]
class A: pass
[file m.py.2]
[builtins fixtures/list.pyi]
[out]
==
main:4: error: Name 'm.A' is not defined

0 comments on commit ab2fb7b

Please sign in to comment.