Skip to content

Commit 3c311c2

Browse files
authored
Fix crash when reveal_locals() encounters a class definition (#5920)
The root cause were some improper casts when creating the `local_nodes` list. These were easy to fix by adding `isinstance(node, Var)` checks to the list comprehensions. Fixes #5915
1 parent c960463 commit 3c311c2

File tree

3 files changed

+22
-17
lines changed

3 files changed

+22
-17
lines changed

mypy/semanal.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2880,23 +2880,24 @@ def visit_call_expr(self, expr: CallExpr) -> None:
28802880
# Each SymbolTableNode has an attribute node that is nodes.Var
28812881
# look for variable nodes that marked as is_inferred
28822882
# Each symboltable node has a Var node as .node
2883-
local_nodes = cast(
2884-
List[Var],
2885-
[
2886-
n.node for name, n in self.globals.items()
2887-
if getattr(n.node, 'is_inferred', False)
2888-
]
2889-
)
2883+
local_nodes = [n.node
2884+
for name, n in self.globals.items()
2885+
if getattr(n.node, 'is_inferred', False)
2886+
and isinstance(n.node, Var)]
28902887
elif self.is_class_scope():
28912888
# type = None # type: Optional[TypeInfo]
28922889
if self.type is not None:
2893-
local_nodes = cast(List[Var], [st.node for st in self.type.names.values()])
2890+
local_nodes = [st.node
2891+
for st in self.type.names.values()
2892+
if isinstance(st.node, Var)]
28942893
elif self.is_func_scope():
28952894
# locals = None # type: List[Optional[SymbolTable]]
28962895
if self.locals is not None:
28972896
symbol_table = self.locals[-1]
28982897
if symbol_table is not None:
2899-
local_nodes = cast(List[Var], [st.node for st in symbol_table.values()])
2898+
local_nodes = [st.node
2899+
for st in symbol_table.values()
2900+
if isinstance(st.node, Var)]
29002901
expr.analyzed = RevealExpr(kind=REVEAL_LOCALS, local_nodes=local_nodes)
29012902
expr.analyzed.line = expr.line
29022903
expr.analyzed.column = expr.column

test-data/unit/check-classes.test

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4940,12 +4940,13 @@ class D(B, C):
49404940
class C1(object):
49414941
t = 'a'
49424942
y = 3.0
4943+
class Inner(object): pass
49434944
reveal_locals()
49444945

49454946
[out]
4946-
main:4: error: Revealed local types are:
4947-
main:4: error: t: builtins.str
4948-
main:4: error: y: builtins.float
4947+
main:5: error: Revealed local types are:
4948+
main:5: error: t: builtins.str
4949+
main:5: error: y: builtins.float
49494950

49504951
[case testAbstractClasses]
49514952
import a

test-data/unit/check-functions.test

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2301,23 +2301,26 @@ main:2: error: Revealed type is 'def () -> builtins.int'
23012301
[case testRevealLocalsFunction]
23022302
a = 1.0
23032303

2304+
class A: pass
2305+
23042306
def f(a: int, b: int) -> int:
23052307
reveal_locals()
23062308
c = a + b
2309+
class C: pass
23072310
reveal_locals()
23082311
return c
23092312

23102313
reveal_locals()
23112314
[out]
2312-
main:4: error: Revealed local types are:
2313-
main:4: error: a: builtins.int
2314-
main:4: error: b: builtins.int
23152315
main:6: error: Revealed local types are:
23162316
main:6: error: a: builtins.int
23172317
main:6: error: b: builtins.int
2318-
main:6: error: c: builtins.int
23192318
main:9: error: Revealed local types are:
2320-
main:9: error: a: builtins.float
2319+
main:9: error: a: builtins.int
2320+
main:9: error: b: builtins.int
2321+
main:9: error: c: builtins.int
2322+
main:12: error: Revealed local types are:
2323+
main:12: error: a: builtins.float
23212324

23222325
[case testNoComplainOverloadNone]
23232326
# flags: --no-strict-optional

0 commit comments

Comments
 (0)