Skip to content

Commit 0da9263

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 2c8a809 commit 0da9263

File tree

4 files changed

+43
-10
lines changed

4 files changed

+43
-10
lines changed

mypy/newsemanal/semanal_namedtuple.py

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

mypy/semanal_namedtuple.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,15 @@ def check_namedtuple(self,
162162
info = self.build_namedtuple_typeinfo(name, [], [], {})
163163
self.store_namedtuple_info(info, name, call, is_typed)
164164
return info
165-
name = cast(Union[StrExpr, BytesExpr, UnicodeExpr], call.args[0]).value
166-
if name != var_name or is_func_scope:
165+
166+
if var_name:
167+
name = var_name
168+
else:
169+
name = cast(Union[StrExpr, BytesExpr, UnicodeExpr], call.args[0]).value
170+
if var_name is None or is_func_scope:
167171
# Give it a unique name derived from the line number.
168172
name += '@' + str(call.line)
173+
169174
if len(defaults) > 0:
170175
default_items = {
171176
arg_name: default

test-data/unit/check-incremental.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4947,7 +4947,7 @@ from typing import NamedTuple
49474947
NT = NamedTuple('BadName', [('x', int)])
49484948
[out]
49494949
[out2]
4950-
tmp/a.py:3: error: Revealed type is 'Tuple[builtins.int, fallback=b.BadName@2]'
4950+
tmp/a.py:3: error: Revealed type is 'Tuple[builtins.int, fallback=b.NT]'
49514951

49524952
[case testNewAnalyzerIncrementalBrokenNamedTupleNested]
49534953
# flags: --new-semantic-analyzer

test-data/unit/fine-grained.test

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8812,3 +8812,25 @@ B().x
88128812
[out]
88138813
==
88148814
==
8815+
8816+
[case testReexportNamedTupleChange]
8817+
from m import M
8818+
8819+
def f(x: M) -> None: ...
8820+
8821+
f(M(0))
8822+
8823+
[file m.py]
8824+
from n import M
8825+
8826+
[file n.py]
8827+
from typing import NamedTuple
8828+
M = NamedTuple('_N', [('x', int)])
8829+
8830+
[file n.py.2]
8831+
# change the line numbers
8832+
from typing import NamedTuple
8833+
M = NamedTuple('_N', [('x', int)])
8834+
8835+
[out]
8836+
==

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy