Skip to content

Commit 1c08006

Browse files
committed
Use variable name to determined NamedTuple class name
This lets us avoid inserting line numbers into the name when the variable name and argument to NamedTuple disagree. This is good, because the line numbers are ugly and when combined with bug #6548 causes problems when a namedtuple is reexported.
1 parent 345134e commit 1c08006

File tree

3 files changed

+36
-8
lines changed

3 files changed

+36
-8
lines changed

mypy/semanal_namedtuple.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,20 @@ def check_namedtuple(self,
178178
info = self.build_namedtuple_typeinfo(name, [], [], {}, node.line)
179179
self.store_namedtuple_info(info, name, call, is_typed)
180180
return True, info
181-
name = cast(Union[StrExpr, BytesExpr, UnicodeExpr], call.args[0]).value
182-
if name != var_name or is_func_scope:
183-
# There are three special cases where need to give it a unique name derived
181+
182+
# We use the variable name as the class name if it exists. If
183+
# it doesn't, we use the name passed as an argument. We prefer
184+
# the variable name because it should be unique inside a
185+
# module, and so we don't need to disambiguate it with a line
186+
# number.
187+
if var_name:
188+
name = var_name
189+
else:
190+
name = cast(Union[StrExpr, BytesExpr, UnicodeExpr], call.args[0]).value
191+
192+
if var_name is None or is_func_scope:
193+
# There are two special cases where need to give it a unique name derived
184194
# from the line number:
185-
# * There is a name mismatch with l.h.s., therefore we need to disambiguate
186-
# situations like:
187-
# A = NamedTuple('Same', [('x', int)])
188-
# B = NamedTuple('Same', [('y', str)])
189195
# * This is a base class expression, since it often matches the class name:
190196
# class NT(NamedTuple('NT', [...])):
191197
# ...

test-data/unit/check-incremental.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5036,7 +5036,7 @@ NT = NamedTuple('BadName', [('x', int)])
50365036
[builtins fixtures/tuple.pyi]
50375037
[out]
50385038
[out2]
5039-
tmp/a.py:3: note: Revealed type is 'Tuple[builtins.int, fallback=b.BadName@2]'
5039+
tmp/a.py:3: note: Revealed type is 'Tuple[builtins.int, fallback=b.NT]'
50405040

50415041
[case testNewAnalyzerIncrementalBrokenNamedTupleNested]
50425042

test-data/unit/fine-grained.test

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9572,3 +9572,25 @@ c.py:2: note: Revealed type is 'a.A'
95729572
==
95739573
c.py:2: note: Revealed type is 'a.<subclass of "A" and "B">'
95749574

9575+
[case testReexportNamedTupleChange]
9576+
from m import M
9577+
9578+
def f(x: M) -> None: ...
9579+
9580+
f(M(0))
9581+
9582+
[file m.py]
9583+
from n import M
9584+
9585+
[file n.py]
9586+
from typing import NamedTuple
9587+
M = NamedTuple('_N', [('x', int)])
9588+
9589+
[file n.py.2]
9590+
# change the line numbers
9591+
from typing import NamedTuple
9592+
M = NamedTuple('_N', [('x', int)])
9593+
9594+
[builtins fixtures/tuple.pyi]
9595+
[out]
9596+
==

0 commit comments

Comments
 (0)