Skip to content

Commit 0650548

Browse files
authored
Display ellipsis when formatting variadic tuple[T, ...] (#11857)
Previously variadic tuples were displayed as `builtins.tuple[T]`, which is misleading. That syntax ordinarily indicates a tuple with a single element. This change adds the `...` ellipsis when formatting. The formatting of non-variadic tuples is unchanged (e.g. `Tuple[T, U]`). Fixes #9522
1 parent 3d20576 commit 0650548

17 files changed

+83
-79
lines changed

mypy/types.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,7 @@ class TupleType(ProperType):
14851485
Instance variables:
14861486
items: Tuple item types
14871487
partial_fallback: The (imprecise) underlying instance type that is used
1488-
for non-tuple methods. This is generally builtins.tuple[Any] for
1488+
for non-tuple methods. This is generally builtins.tuple[Any, ...] for
14891489
regular tuples, but it's different for named tuples and classes with
14901490
a tuple base class. Use mypy.typeops.tuple_fallback to calculate the
14911491
precise fallback type derived from item types.
@@ -2203,7 +2203,11 @@ def visit_instance(self, t: Instance) -> str:
22032203
if t.erased:
22042204
s += '*'
22052205
if t.args:
2206-
s += '[{}]'.format(self.list_str(t.args))
2206+
if t.type.fullname == 'builtins.tuple':
2207+
assert len(t.args) == 1
2208+
s += '[{}, ...]'.format(self.list_str(t.args))
2209+
else:
2210+
s += '[{}]'.format(self.list_str(t.args))
22072211
if self.id_mapper:
22082212
s += '<{}>'.format(self.id_mapper.id(t.type))
22092213
return s

test-data/unit/check-annotated.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ from typing import Tuple
8787
from typing_extensions import Annotated
8888
Alias = Annotated[Tuple[int, ...], ...]
8989
x: Alias
90-
reveal_type(x) # N: Revealed type is "builtins.tuple[builtins.int]"
90+
reveal_type(x) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
9191
[builtins fixtures/tuple.pyi]
9292

9393
[case testAnnotatedAliasTypeVar]

test-data/unit/check-fastparse.test

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def f(a, # type: A
154154
):
155155
reveal_type(a) # N: Revealed type is "__main__.A"
156156
reveal_type(b) # N: Revealed type is "Union[__main__.B, None]"
157-
reveal_type(args) # N: Revealed type is "builtins.tuple[__main__.C]"
157+
reveal_type(args) # N: Revealed type is "builtins.tuple[__main__.C, ...]"
158158
reveal_type(d) # N: Revealed type is "Union[__main__.D, None]"
159159
reveal_type(e) # N: Revealed type is "__main__.E"
160160
reveal_type(kwargs) # N: Revealed type is "builtins.dict[builtins.str, __main__.F]"
@@ -179,7 +179,7 @@ def f(a, # type: A
179179
# type: (...) -> int
180180
reveal_type(a) # N: Revealed type is "__main__.A"
181181
reveal_type(b) # N: Revealed type is "Union[__main__.B, None]"
182-
reveal_type(args) # N: Revealed type is "builtins.tuple[__main__.C]"
182+
reveal_type(args) # N: Revealed type is "builtins.tuple[__main__.C, ...]"
183183
reveal_type(d) # N: Revealed type is "Union[__main__.D, None]"
184184
reveal_type(e) # N: Revealed type is "__main__.E"
185185
reveal_type(kwargs) # N: Revealed type is "builtins.dict[builtins.str, __main__.F]"
@@ -221,7 +221,7 @@ def f(a, # type: A
221221
):
222222
reveal_type(a) # N: Revealed type is "__main__.A"
223223
reveal_type(b) # N: Revealed type is "Union[__main__.B, None]"
224-
reveal_type(args) # N: Revealed type is "builtins.tuple[__main__.C]"
224+
reveal_type(args) # N: Revealed type is "builtins.tuple[__main__.C, ...]"
225225
[builtins fixtures/dict.pyi]
226226
[out]
227227

@@ -239,7 +239,7 @@ def f(a, # type: A
239239
# type: (...) -> int
240240
reveal_type(a) # N: Revealed type is "__main__.A"
241241
reveal_type(b) # N: Revealed type is "Union[__main__.B, None]"
242-
reveal_type(args) # N: Revealed type is "builtins.tuple[__main__.C]"
242+
reveal_type(args) # N: Revealed type is "builtins.tuple[__main__.C, ...]"
243243
return "not an int" # E: Incompatible return value type (got "str", expected "int")
244244
[builtins fixtures/dict.pyi]
245245
[out]

test-data/unit/check-generic-alias.test

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@ t11: type[int]
101101
reveal_type(t1) # N: Revealed type is "builtins.list[Any]"
102102
reveal_type(t2) # N: Revealed type is "builtins.list[builtins.int]"
103103
reveal_type(t3) # N: Revealed type is "builtins.list[builtins.str]"
104-
reveal_type(t4) # N: Revealed type is "builtins.tuple[Any]"
104+
reveal_type(t4) # N: Revealed type is "builtins.tuple[Any, ...]"
105105
# TODO: ideally these would reveal builtins.tuple
106106
reveal_type(t5) # N: Revealed type is "Tuple[builtins.int]"
107107
reveal_type(t6) # N: Revealed type is "Tuple[builtins.int, builtins.str]"
108108
# TODO: this is incorrect, see #9522
109-
reveal_type(t7) # N: Revealed type is "builtins.tuple[builtins.int]"
109+
reveal_type(t7) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
110110
reveal_type(t8) # N: Revealed type is "builtins.dict[Any, Any]"
111111
reveal_type(t9) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]"
112112
reveal_type(t10) # N: Revealed type is "builtins.type"
@@ -252,13 +252,13 @@ B = tuple[int, str]
252252
x: B = (1, 'x')
253253
y: B = ('x', 1) # E: Incompatible types in assignment (expression has type "Tuple[str, int]", variable has type "Tuple[int, str]")
254254

255-
reveal_type(tuple[int, ...]()) # N: Revealed type is "builtins.tuple[builtins.int*]"
255+
reveal_type(tuple[int, ...]()) # N: Revealed type is "builtins.tuple[builtins.int*, ...]"
256256
[builtins fixtures/tuple.pyi]
257257

258258
[case testTypeAliasWithBuiltinTupleInStub]
259259
# flags: --python-version 3.6
260260
import m
261-
reveal_type(m.a) # N: Revealed type is "builtins.tuple[builtins.int]"
261+
reveal_type(m.a) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
262262
reveal_type(m.b) # N: Revealed type is "Tuple[builtins.int, builtins.str]"
263263

264264
[file m.pyi]

test-data/unit/check-generics.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,9 +2073,9 @@ class Base(Generic[T]):
20732073
return (cls(item),)
20742074
return cls(item)
20752075

2076-
reveal_type(Base.make_some) # N: Revealed type is "Overload(def [T] (item: T`1) -> __main__.Base[T`1], def [T] (item: T`1, n: builtins.int) -> builtins.tuple[__main__.Base[T`1]])"
2076+
reveal_type(Base.make_some) # N: Revealed type is "Overload(def [T] (item: T`1) -> __main__.Base[T`1], def [T] (item: T`1, n: builtins.int) -> builtins.tuple[__main__.Base[T`1], ...])"
20772077
reveal_type(Base.make_some(1)) # N: Revealed type is "__main__.Base[builtins.int*]"
2078-
reveal_type(Base.make_some(1, 1)) # N: Revealed type is "builtins.tuple[__main__.Base[builtins.int*]]"
2078+
reveal_type(Base.make_some(1, 1)) # N: Revealed type is "builtins.tuple[__main__.Base[builtins.int*], ...]"
20792079

20802080
class Sub(Base[str]): ...
20812081
Sub.make_some(1) # E: No overload variant of "make_some" of "Base" matches argument type "int" \
@@ -2183,7 +2183,7 @@ class C(Generic[T]):
21832183
class D(C[str]): ...
21842184

21852185
reveal_type(D.get()) # N: Revealed type is "builtins.str*"
2186-
reveal_type(D.get(42)) # N: Revealed type is "builtins.tuple[builtins.str*]"
2186+
reveal_type(D.get(42)) # N: Revealed type is "builtins.tuple[builtins.str*, ...]"
21872187
[builtins fixtures/classmethod.pyi]
21882188

21892189
[case testGenericClassMethodAnnotation]

test-data/unit/check-namedtuple.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ Node = NamedTuple('Node', [
673673
('children', Tuple['Node', ...]), # E: Cannot resolve name "Node" (possible cyclic definition)
674674
])
675675
n: Node
676-
reveal_type(n) # N: Revealed type is "Tuple[builtins.str, builtins.tuple[Any], fallback=__main__.Node]"
676+
reveal_type(n) # N: Revealed type is "Tuple[builtins.str, builtins.tuple[Any, ...], fallback=__main__.Node]"
677677
[builtins fixtures/tuple.pyi]
678678

679679
[case testSelfRefNT2]
@@ -689,7 +689,7 @@ class B(NamedTuple):
689689
y: int
690690

691691
n: A
692-
reveal_type(n) # N: Revealed type is "Tuple[builtins.str, builtins.tuple[Any], fallback=__main__.A]"
692+
reveal_type(n) # N: Revealed type is "Tuple[builtins.str, builtins.tuple[Any, ...], fallback=__main__.A]"
693693
[builtins fixtures/tuple.pyi]
694694

695695
[case testSelfRefNT3]

test-data/unit/check-overloading.test

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,12 +2589,12 @@ def f(*args): pass
25892589
i: int
25902590
reveal_type(f(i)) # N: Revealed type is "Tuple[builtins.int]"
25912591
reveal_type(f(i, i)) # N: Revealed type is "Tuple[builtins.int, builtins.int]"
2592-
reveal_type(f(i, i, i)) # N: Revealed type is "builtins.tuple[builtins.int]"
2592+
reveal_type(f(i, i, i)) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
25932593

2594-
reveal_type(f(*[])) # N: Revealed type is "builtins.tuple[builtins.int]"
2595-
reveal_type(f(*[i])) # N: Revealed type is "builtins.tuple[builtins.int]"
2596-
reveal_type(f(*[i, i])) # N: Revealed type is "builtins.tuple[builtins.int]"
2597-
reveal_type(f(*[i, i, i])) # N: Revealed type is "builtins.tuple[builtins.int]"
2594+
reveal_type(f(*[])) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
2595+
reveal_type(f(*[i])) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
2596+
reveal_type(f(*[i, i])) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
2597+
reveal_type(f(*[i, i, i])) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
25982598
[builtins fixtures/list.pyi]
25992599

26002600
[case testOverloadVarargsSelectionWithTuples]
@@ -2608,10 +2608,10 @@ def f(*xs: int) -> Tuple[int, ...]: ...
26082608
def f(*args): pass
26092609

26102610
i: int
2611-
reveal_type(f(*())) # N: Revealed type is "builtins.tuple[builtins.int]"
2611+
reveal_type(f(*())) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
26122612
reveal_type(f(*(i,))) # N: Revealed type is "Tuple[builtins.int]"
26132613
reveal_type(f(*(i, i))) # N: Revealed type is "Tuple[builtins.int, builtins.int]"
2614-
reveal_type(f(*(i, i, i))) # N: Revealed type is "builtins.tuple[builtins.int]"
2614+
reveal_type(f(*(i, i, i))) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
26152615
[builtins fixtures/tuple.pyi]
26162616

26172617
[case testOverloadVarargsSelectionWithNamedTuples]
@@ -2631,7 +2631,7 @@ b: B
26312631
c: C
26322632
reveal_type(f(*a)) # N: Revealed type is "Tuple[builtins.int, builtins.int]"
26332633
reveal_type(f(*b)) # N: Revealed type is "Tuple[builtins.int, builtins.int]"
2634-
reveal_type(f(*c)) # N: Revealed type is "builtins.tuple[builtins.int]"
2634+
reveal_type(f(*c)) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
26352635
[builtins fixtures/tuple.pyi]
26362636

26372637
[case testOverloadKwargsSelectionWithDict]
@@ -2645,10 +2645,10 @@ def f(**xs: int) -> Tuple[int, ...]: ...
26452645
def f(**kwargs): pass
26462646

26472647
empty: Dict[str, int]
2648-
reveal_type(f(**empty)) # N: Revealed type is "builtins.tuple[builtins.int]"
2649-
reveal_type(f(**{'x': 4})) # N: Revealed type is "builtins.tuple[builtins.int]"
2650-
reveal_type(f(**{'x': 4, 'y': 4})) # N: Revealed type is "builtins.tuple[builtins.int]"
2651-
reveal_type(f(**{'a': 4, 'b': 4, 'c': 4})) # N: Revealed type is "builtins.tuple[builtins.int]"
2648+
reveal_type(f(**empty)) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
2649+
reveal_type(f(**{'x': 4})) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
2650+
reveal_type(f(**{'x': 4, 'y': 4})) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
2651+
reveal_type(f(**{'a': 4, 'b': 4, 'c': 4})) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
26522652
[builtins fixtures/dict.pyi]
26532653

26542654
[case testOverloadKwargsSelectionWithTypedDict]
@@ -2672,7 +2672,7 @@ c: C
26722672

26732673
reveal_type(f(**a)) # N: Revealed type is "Tuple[builtins.int]"
26742674
reveal_type(f(**b)) # N: Revealed type is "Tuple[builtins.int, builtins.int]"
2675-
reveal_type(f(**c)) # N: Revealed type is "builtins.tuple[builtins.int]"
2675+
reveal_type(f(**c)) # N: Revealed type is "builtins.tuple[builtins.int, ...]"
26762676
[builtins fixtures/dict.pyi]
26772677

26782678
[case testOverloadVarargsAndKwargsSelection]

test-data/unit/check-selftype.test

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -555,9 +555,9 @@ reveal_type(P) # N: Revealed type is "Overload(def [T] (use_str: Literal[True])
555555
reveal_type(P(use_str=True)) # N: Revealed type is "lib.P[builtins.str]"
556556
reveal_type(P(use_str=False)) # N: Revealed type is "lib.P[builtins.int]"
557557

558-
reveal_type(C) # N: Revealed type is "Overload(def [T] (item: T`1, use_tuple: Literal[False]) -> lib.C[T`1], def [T] (item: T`1, use_tuple: Literal[True]) -> lib.C[builtins.tuple[T`1]])"
558+
reveal_type(C) # N: Revealed type is "Overload(def [T] (item: T`1, use_tuple: Literal[False]) -> lib.C[T`1], def [T] (item: T`1, use_tuple: Literal[True]) -> lib.C[builtins.tuple[T`1, ...]])"
559559
reveal_type(C(0, use_tuple=False)) # N: Revealed type is "lib.C[builtins.int*]"
560-
reveal_type(C(0, use_tuple=True)) # N: Revealed type is "lib.C[builtins.tuple[builtins.int*]]"
560+
reveal_type(C(0, use_tuple=True)) # N: Revealed type is "lib.C[builtins.tuple[builtins.int*, ...]]"
561561

562562
T = TypeVar('T')
563563
class SubP(P[T]):
@@ -949,9 +949,9 @@ class Other(Base): ...
949949
class Double(Sub): ...
950950

951951
reveal_type(Other.make()) # N: Revealed type is "__main__.Other*"
952-
reveal_type(Other.make(3)) # N: Revealed type is "builtins.tuple[__main__.Other*]"
952+
reveal_type(Other.make(3)) # N: Revealed type is "builtins.tuple[__main__.Other*, ...]"
953953
reveal_type(Double.make()) # N: Revealed type is "__main__.Sub"
954-
reveal_type(Double.make(3)) # N: Revealed type is "builtins.tuple[__main__.Sub]"
954+
reveal_type(Double.make(3)) # N: Revealed type is "builtins.tuple[__main__.Sub, ...]"
955955
[file lib.pyi]
956956
from typing import overload, TypeVar, Type, Tuple
957957

test-data/unit/check-serialize.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,8 +1030,8 @@ x: Tuple[int, ...]
10301030
y: tuple
10311031
[builtins fixtures/tuple.pyi]
10321032
[out2]
1033-
tmp/a.py:2: note: Revealed type is "builtins.tuple[builtins.int]"
1034-
tmp/a.py:3: note: Revealed type is "builtins.tuple[Any]"
1033+
tmp/a.py:2: note: Revealed type is "builtins.tuple[builtins.int, ...]"
1034+
tmp/a.py:3: note: Revealed type is "builtins.tuple[Any, ...]"
10351035

10361036
[case testSerializeNone]
10371037
import a

0 commit comments

Comments
 (0)