Skip to content

Commit ab38885

Browse files
authored
Wrap callable in union syntax (#20406)
Follow up to #20332 (comment) Wrap the callable with `( )` if it's within a union to reduce ambiguity. This matches the pyright behavior. ```py def f1() -> int | None: return 1 def f2() -> int: return 1 reveal_type(f1) # def () -> builtins.int | None reveal_type(f2 if int() else None) # (def () -> builtins.int)) | None ```
1 parent 69112dd commit ab38885

11 files changed

+27
-23
lines changed

mypy/types.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4013,7 +4013,11 @@ def list_str(self, a: Iterable[Type], *, use_or_syntax: bool = False) -> str:
40134013
"""
40144014
res = []
40154015
for t in a:
4016-
res.append(t.accept(self))
4016+
s = t.accept(self)
4017+
if use_or_syntax and isinstance(get_proper_type(t), CallableType):
4018+
res.append(f"({s})")
4019+
else:
4020+
res.append(s)
40174021
sep = ", " if not use_or_syntax else " | "
40184022
return sep.join(res)
40194023

test-data/unit/check-classes.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7147,7 +7147,7 @@ def test() -> None:
71477147
x = Other
71487148
else:
71497149
return
7150-
reveal_type(x) # N: Revealed type is "def () -> __main__.One | def () -> __main__.Other"
7150+
reveal_type(x) # N: Revealed type is "(def () -> __main__.One) | (def () -> __main__.Other)"
71517151
reveal_type(x.x) # N: Revealed type is "builtins.int"
71527152
[builtins fixtures/isinstancelist.pyi]
71537153

test-data/unit/check-classvar.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ class C:
344344
def f(self) -> int: ...
345345
g: ClassVar[Union[Callable[[C], int], int]] = f
346346

347-
reveal_type(C().g) # N: Revealed type is "def () -> builtins.int | builtins.int"
347+
reveal_type(C().g) # N: Revealed type is "(def () -> builtins.int) | builtins.int"
348348

349349
[case testGenericSubclassAccessNoLeak]
350350
from typing import ClassVar, Generic, TypeVar

test-data/unit/check-functions.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2293,7 +2293,7 @@ def f() -> None:
22932293
def g(x: int) -> None:
22942294
pass
22952295
h = f if bool() else g
2296-
reveal_type(h) # N: Revealed type is "def () | def (x: builtins.int)"
2296+
reveal_type(h) # N: Revealed type is "(def ()) | (def (x: builtins.int))"
22972297
h(7) # E: Too many arguments for "f"
22982298

22992299
T = TypeVar("T")

test-data/unit/check-inference.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,17 +1467,17 @@ class Wrapper:
14671467

14681468
def f(cond: bool) -> Any:
14691469
f = Wrapper if cond else lambda x: x
1470-
reveal_type(f) # N: Revealed type is "def (x: Any) -> __main__.Wrapper | def (x: Any) -> Any"
1470+
reveal_type(f) # N: Revealed type is "(def (x: Any) -> __main__.Wrapper) | (def (x: Any) -> Any)"
14711471
return f(3)
14721472

14731473
def g(cond: bool) -> Any:
14741474
f = lambda x: x if cond else Wrapper
1475-
reveal_type(f) # N: Revealed type is "def (x: Any) -> Any | def (x: Any) -> __main__.Wrapper"
1475+
reveal_type(f) # N: Revealed type is "def (x: Any) -> Any | (def (x: Any) -> __main__.Wrapper)"
14761476
return f(3)
14771477

14781478
def h(cond: bool) -> Any:
14791479
f = (lambda x: x) if cond else Wrapper
1480-
reveal_type(f) # N: Revealed type is "def (x: Any) -> Any | def (x: Any) -> __main__.Wrapper"
1480+
reveal_type(f) # N: Revealed type is "(def (x: Any) -> Any) | (def (x: Any) -> __main__.Wrapper)"
14811481
return f(3)
14821482

14831483
-- Boolean operators

test-data/unit/check-newsemanal.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1951,7 +1951,7 @@ reveal_type(t1.__iter__) # N: Revealed type is "def () -> typing.Iterator[__main
19511951
t2: NTInt
19521952
reveal_type(t2.__iter__) # N: Revealed type is "def () -> typing.Iterator[builtins.int]"
19531953
nt: Union[NTInt, NTStr]
1954-
reveal_type(nt.__iter__) # N: Revealed type is "def () -> typing.Iterator[builtins.int] | def () -> typing.Iterator[builtins.str]"
1954+
reveal_type(nt.__iter__) # N: Revealed type is "(def () -> typing.Iterator[builtins.int]) | (def () -> typing.Iterator[builtins.str])"
19551955
for nx in nt:
19561956
reveal_type(nx) # N: Revealed type is "builtins.int | builtins.str"
19571957

test-data/unit/check-parameter-specification.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,9 +1509,9 @@ def foo(x: int) -> str: ...
15091509
def foo2(__x: int) -> Callable[[int], str]: ...
15101510

15111511
x: C[[int, str]]
1512-
reveal_type(x) # N: Revealed type is "def (builtins.int, builtins.str) -> builtins.int | ..."
1512+
reveal_type(x) # N: Revealed type is "def (builtins.int, builtins.str) -> builtins.int | (...)"
15131513
y: C[int, str]
1514-
reveal_type(y) # N: Revealed type is "def (builtins.int, builtins.str) -> builtins.int | ..."
1514+
reveal_type(y) # N: Revealed type is "def (builtins.int, builtins.str) -> builtins.int | (...)"
15151515
[builtins fixtures/paramspec.pyi]
15161516

15171517
[case testParamSpecAliasInRuntimeContext]

test-data/unit/check-recursive-types.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ A = Union[B, int]
9595
B = Callable[[C], int]
9696
C = Type[A]
9797
x: A
98-
reveal_type(x) # N: Revealed type is "def (type[def (...) -> builtins.int] | type[builtins.int]) -> builtins.int | builtins.int"
98+
reveal_type(x) # N: Revealed type is "(def (type[def (...) -> builtins.int] | type[builtins.int]) -> builtins.int) | builtins.int"
9999

100100
[case testRecursiveAliasesProhibited-skip]
101101
from typing import Type, Callable, Union

test-data/unit/check-selftype.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,7 +1135,7 @@ class C:
11351135
def same(self: T) -> T: ...
11361136

11371137
x: Union[A, C]
1138-
reveal_type(x.same) # N: Revealed type is "builtins.int | def () -> __main__.C"
1138+
reveal_type(x.same) # N: Revealed type is "builtins.int | (def () -> __main__.C)"
11391139

11401140
[case testSelfTypeOnUnionClassMethod]
11411141
from typing import TypeVar, Union, Type
@@ -1150,7 +1150,7 @@ class C:
11501150
def same(cls: Type[T]) -> T: ...
11511151

11521152
x: Union[A, C]
1153-
reveal_type(x.same) # N: Revealed type is "builtins.int | def () -> __main__.C"
1153+
reveal_type(x.same) # N: Revealed type is "builtins.int | (def () -> __main__.C)"
11541154
[builtins fixtures/classmethod.pyi]
11551155

11561156
[case SelfTypeOverloadedClassMethod]
@@ -1201,7 +1201,7 @@ class B(A): ...
12011201
class C(A): ...
12021202

12031203
t: Type[Union[B, C]]
1204-
reveal_type(t.meth) # N: Revealed type is "def () -> __main__.B | def () -> __main__.C"
1204+
reveal_type(t.meth) # N: Revealed type is "(def () -> __main__.B) | (def () -> __main__.C)"
12051205
x = t.meth()
12061206
reveal_type(x) # N: Revealed type is "__main__.B | __main__.C"
12071207
[builtins fixtures/classmethod.pyi]

test-data/unit/check-unions.test

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,8 @@ reveal_type(u(type, type)) # N: Revealed type is "def (x: builtins.object) -> bu
386386
# One type, other non-type
387387
reveal_type(u(t_s, 1)) # N: Revealed type is "builtins.int | type[builtins.str]"
388388
reveal_type(u(1, t_s)) # N: Revealed type is "type[builtins.str] | builtins.int"
389-
reveal_type(u(type, 1)) # N: Revealed type is "builtins.int | def (x: builtins.object) -> builtins.type"
390-
reveal_type(u(1, type)) # N: Revealed type is "def (x: builtins.object) -> builtins.type | builtins.int"
389+
reveal_type(u(type, 1)) # N: Revealed type is "builtins.int | (def (x: builtins.object) -> builtins.type)"
390+
reveal_type(u(1, type)) # N: Revealed type is "(def (x: builtins.object) -> builtins.type) | builtins.int"
391391
reveal_type(u(t_a, 1)) # N: Revealed type is "builtins.int | type[Any]"
392392
reveal_type(u(1, t_a)) # N: Revealed type is "type[Any] | builtins.int"
393393
reveal_type(u(t_o, 1)) # N: Revealed type is "builtins.int | type[builtins.object]"
@@ -468,19 +468,19 @@ i_C: Callable[[int], C]
468468

469469
reveal_type(u(D_C, D_C)) # N: Revealed type is "def (__main__.D) -> __main__.C"
470470

471-
reveal_type(u(A_C, D_C)) # N: Revealed type is "def (__main__.D) -> __main__.C | def (Any) -> __main__.C"
472-
reveal_type(u(D_C, A_C)) # N: Revealed type is "def (Any) -> __main__.C | def (__main__.D) -> __main__.C"
471+
reveal_type(u(A_C, D_C)) # N: Revealed type is "(def (__main__.D) -> __main__.C) | (def (Any) -> __main__.C)"
472+
reveal_type(u(D_C, A_C)) # N: Revealed type is "(def (Any) -> __main__.C) | (def (__main__.D) -> __main__.C)"
473473

474-
reveal_type(u(D_A, D_C)) # N: Revealed type is "def (__main__.D) -> __main__.C | def (__main__.D) -> Any"
475-
reveal_type(u(D_C, D_A)) # N: Revealed type is "def (__main__.D) -> Any | def (__main__.D) -> __main__.C"
474+
reveal_type(u(D_A, D_C)) # N: Revealed type is "(def (__main__.D) -> __main__.C) | (def (__main__.D) -> Any)"
475+
reveal_type(u(D_C, D_A)) # N: Revealed type is "(def (__main__.D) -> Any) | (def (__main__.D) -> __main__.C)"
476476

477477
reveal_type(u(D_C, C_C)) # N: Revealed type is "def (__main__.D) -> __main__.C"
478478
reveal_type(u(C_C, D_C)) # N: Revealed type is "def (__main__.D) -> __main__.C"
479479

480480
reveal_type(u(D_C, D_D)) # N: Revealed type is "def (__main__.D) -> __main__.C"
481481
reveal_type(u(D_D, D_C)) # N: Revealed type is "def (__main__.D) -> __main__.C"
482482

483-
reveal_type(u(D_C, i_C)) # N: Revealed type is "def (builtins.int) -> __main__.C | def (__main__.D) -> __main__.C"
483+
reveal_type(u(D_C, i_C)) # N: Revealed type is "(def (builtins.int) -> __main__.C) | (def (__main__.D) -> __main__.C)"
484484

485485
[case testUnionOperatorMethodSpecialCase]
486486
from typing import Union
@@ -821,7 +821,7 @@ class NTStr(NamedTuple):
821821
t1: NTInt
822822
reveal_type(t1.__iter__) # N: Revealed type is "def () -> typing.Iterator[builtins.int]"
823823
nt: Union[NTInt, NTStr]
824-
reveal_type(nt.__iter__) # N: Revealed type is "def () -> typing.Iterator[builtins.int] | def () -> typing.Iterator[builtins.str]"
824+
reveal_type(nt.__iter__) # N: Revealed type is "(def () -> typing.Iterator[builtins.int]) | (def () -> typing.Iterator[builtins.str])"
825825
for nx in nt:
826826
reveal_type(nx) # N: Revealed type is "builtins.int | builtins.str"
827827

0 commit comments

Comments
 (0)