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
Fix crashes and fails in forward references #3952
Changes from 1 commit
45e5931
cb4caa5
1cdc980
260ef02
a58a217
950a022
411b24d
b9b8528
48d6de4
ec45441
ac32ed4
3fb3019
f9b1320
cf014b8
665236b
9a318aa
757fbd9
4502ce2
3b39d40
c8b28fe
9f92b0f
9779103
b914bdb
3568fdb
54d9331
b9ddacc
5bfe9ca
a2912e9
10c65b8
21dfbfe
f2ddbcd
03597ee
649ef32
83f8907
13c7176
79b10d6
321a809
076c909
c1a63ec
97e6f47
8f52654
6edd078
514b8bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4230,6 +4230,14 @@ def visit_assignment_stmt(self, s: AssignmentStmt) -> None: | |
self.analyze(node.type_override, node) | ||
super().visit_assignment_stmt(s) | ||
|
||
def visit_for_stmt(self, s: ForStmt) -> None: | ||
self.analyze(s.index_type, s) | ||
super().visit_for_stmt(s) | ||
|
||
def visit_with_stmt(self, s: WithStmt) -> None: | ||
self.analyze(s.target_type, s) | ||
super().visit_with_stmt(s) | ||
|
||
def visit_cast_expr(self, e: CastExpr) -> None: | ||
self.analyze(e.type, e) | ||
super().visit_cast_expr(e) | ||
|
@@ -4247,6 +4255,14 @@ def visit_type_application(self, e: TypeApplication) -> None: | |
def perform_transform(self, node: Union[Node, SymbolTableNode], | ||
transform: Callable[[Type], Type]) -> None: | ||
"""Apply transform to all types associated with node.""" | ||
if isinstance(node, ForStmt): | ||
node.index_type = transform(node.index_type) | ||
self.transform_types(node.index, transform) | ||
if isinstance(node, WithStmt): | ||
node.target_type = transform(node.target_type) | ||
for n in node.target: | ||
if isinstance(n, NameExpr) and isinstance(n.node, Var) and n.node.type: | ||
n.node.type = transform(n.node.type) | ||
if isinstance(node, (FuncDef, CastExpr, AssignmentStmt, TypeAliasExpr, Var)): | ||
node.type = transform(node.type) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was not able to trigger any errors with this, I will double check. |
||
if isinstance(node, NewTypeExpr): | ||
|
@@ -4275,6 +4291,15 @@ def perform_transform(self, node: Union[Node, SymbolTableNode], | |
new_bases.append(alt_base) | ||
node.bases = new_bases | ||
|
||
def transform_types(self, lvalue: Lvalue, transform: Callable[[Type], Type]) -> None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The name of the method would be more informative as |
||
if isinstance(lvalue, RefExpr): | ||
if isinstance(lvalue.node, Var): | ||
var = lvalue.node | ||
var.type = transform(var.type) | ||
elif isinstance(lvalue, TupleExpr): | ||
for item in lvalue.items: | ||
self.transform_types(item, transform) | ||
|
||
def analyze(self, type: Optional[Type], node: Union[Node, SymbolTableNode], | ||
warn: bool = False) -> None: | ||
# Recursive type warnings are only emitted on type definition 'node's, marked by 'warn' | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1565,25 +1565,51 @@ reveal_type(d['weight0']) # E: Revealed type is 'builtins.float*' | |
|
||
[builtins fixtures/floatdict.pyi] | ||
|
||
[case testForwardRefsInForStatement] | ||
[case testForwardRefsInForStatementImplicit] | ||
from typing import List, NamedTuple | ||
lst: List[N] | ||
|
||
for i in lst: | ||
a: int = i.x | ||
b: str = i[0] # E: Incompatible types in assignment (expression has type "int", variable has type "str") | ||
|
||
N = NamedTuple('N', [('x', int)]) | ||
[builtins fixtures/list.pyi] | ||
[out] | ||
|
||
[case testForwardRefsInForStatement] | ||
from typing import List, NamedTuple | ||
lst: List[M] | ||
|
||
for i in lst: # type: N | ||
a: int = i.x | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, prefer |
||
b: str = i[0] | ||
b: str = i[0] # E: Incompatible types in assignment (expression has type "int", variable has type "str") | ||
|
||
N = NamedTuple('N', [('x', int)]) | ||
class M(N): pass | ||
[builtins fixtures/list.pyi] | ||
[out] | ||
|
||
[case testForwardRefsInWithStatement] | ||
from typing import ContextManager | ||
[case testForwardRefsInWithStatementImplicit] | ||
from typing import ContextManager, Any | ||
from mypy_extensions import TypedDict | ||
cm: ContextManager[N] | ||
|
||
with cm as g: | ||
a: int = g['x'] | ||
|
||
N = TypedDict('N', {'x': int}) | ||
[builtins fixtures/dict.pyi] | ||
[typing fixtures/typing-full.pyi] | ||
[out] | ||
|
||
[case testForwardRefsInWithStatement] | ||
from typing import ContextManager, Any | ||
from mypy_extensions import TypedDict | ||
cm: ContextManager[Any] | ||
|
||
with cm as g: # type: N | ||
a: str = g['x'] | ||
a: str = g['x'] # E: Incompatible types in assignment (expression has type "int", variable has type "str") | ||
|
||
N = TypedDict('N', {'x': int}) | ||
[builtins fixtures/dict.pyi] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
type_vars
ofClassDef
transformed somewhere? What aboutindex_type
ofForStmt
andtarget_type
ofWithStmt
? AndTypeVarExpr
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type_vars
andTypeVarExpr
are probably not needed (I will double-check), but it looks like I just forgot aboutWithStmt
andForStmt
. I will add processing.