Skip to content

Commit 7de40fa

Browse files
authored
Fixes to AST merge of named tuples and callables (#4457)
Some parts of the AST were not handled in AST merge, resulting in old AST nodes leaking and causing trouble. Added a test case that depends on the fix to the named tuple fallback. Not sure if the other changes fix user-visible bugs.
1 parent 63920b1 commit 7de40fa

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

mypy/server/astmerge.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ def visit_ref_expr(self, node: RefExpr) -> None:
203203

204204
def visit_namedtuple_expr(self, node: NamedTupleExpr) -> None:
205205
super().visit_namedtuple_expr(node)
206+
node.info = self.fixup(node.info)
206207
self.process_type_info(node.info)
207208

208209
def visit_super_expr(self, node: SuperExpr) -> None:
@@ -300,7 +301,9 @@ def visit_callable_type(self, typ: CallableType) -> None:
300301
if typ.definition:
301302
# No need to fixup since this is just a cross-reference.
302303
typ.definition = self.replacements.get(typ.definition, typ.definition)
303-
# TODO: typ.fallback
304+
# Fallback can be None for callable types that haven't been semantically analyzed.
305+
if typ.fallback is not None:
306+
typ.fallback.accept(self)
304307
for tv in typ.variables:
305308
tv.upper_bound.accept(self)
306309
for value in tv.values:
@@ -309,6 +312,7 @@ def visit_callable_type(self, typ: CallableType) -> None:
309312
def visit_overloaded(self, t: Overloaded) -> None:
310313
for item in t.items():
311314
item.accept(self)
315+
t.fallback.accept(self)
312316

313317
def visit_deleted_type(self, typ: DeletedType) -> None:
314318
pass
@@ -319,6 +323,7 @@ def visit_partial_type(self, typ: PartialType) -> None:
319323
def visit_tuple_type(self, typ: TupleType) -> None:
320324
for item in typ.items:
321325
item.accept(self)
326+
typ.fallback.accept(self)
322327

323328
def visit_type_type(self, typ: TypeType) -> None:
324329
typ.item.accept(self)

test-data/unit/fine-grained.test

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,3 +1495,42 @@ def f(o: object) -> None:
14951495
[builtins fixtures/callable.pyi]
14961496
[out]
14971497
==
1498+
1499+
[case testRefreshFunctionalNamedTuple]
1500+
import a
1501+
1502+
[file a.py]
1503+
from typing import NamedTuple
1504+
from b import L
1505+
1506+
A = NamedTuple('A', [])
1507+
a: A
1508+
1509+
def g() -> None:
1510+
x = L(A())
1511+
x.f(a)
1512+
1513+
[file b.pyi]
1514+
from typing import TypeVar, Generic, overload
1515+
1516+
T = TypeVar('T')
1517+
1518+
class L(Generic[T]):
1519+
def __init__(self, x: T) -> None: pass
1520+
@overload
1521+
def f(self) -> None: pass
1522+
@overload
1523+
def f(self, a: T) -> None: pass
1524+
1525+
[file a.py.2]
1526+
from typing import NamedTuple
1527+
from b import L
1528+
1529+
A = NamedTuple('A', [])
1530+
a: A
1531+
1532+
def g() -> None:
1533+
x = L(A())
1534+
x.f(a)
1535+
[out]
1536+
==

0 commit comments

Comments
 (0)