Skip to content

Commit 532f3fb

Browse files
MentalMegalodonmsullivan
authored andcommitted
Fix type of conditional statement to Union and not Join (#5041)
Fixes #3487
1 parent 1dbe724 commit 532f3fb

File tree

5 files changed

+28
-6
lines changed

5 files changed

+28
-6
lines changed

mypy/checker.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,9 +1328,9 @@ def check_protocol_variance(self, defn: ClassDef) -> None:
13281328
tvars = info.defn.type_vars
13291329
for i, tvar in enumerate(tvars):
13301330
up_args = [object_type if i == j else AnyType(TypeOfAny.special_form)
1331-
for j, _ in enumerate(tvars)]
1331+
for j, _ in enumerate(tvars)] # type: List[Type]
13321332
down_args = [UninhabitedType() if i == j else AnyType(TypeOfAny.special_form)
1333-
for j, _ in enumerate(tvars)]
1333+
for j, _ in enumerate(tvars)] # type: List[Type]
13341334
up, down = Instance(info, up_args), Instance(info, down_args)
13351335
# TODO: add advanced variance checks for recursive protocols
13361336
if is_subtype(down, up, ignore_declared_variance=True):

mypy/checkexpr.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2342,7 +2342,7 @@ def visit_conditional_expr(self, e: ConditionalExpr) -> Type:
23422342
# branch's type.
23432343
else_type = self.analyze_cond_branch(else_map, e.else_expr, context=if_type)
23442344

2345-
res = join.join_types(if_type, else_type)
2345+
res = UnionType.make_simplified_union([if_type, else_type])
23462346

23472347
return res
23482348

test-data/unit/check-expressions.test

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,28 @@ x = [1]
14481448
x = ['x'] # E: List item 0 has incompatible type "str"; expected "int"
14491449
[builtins fixtures/list.pyi]
14501450

1451+
[case testConditionalExpressionUnion]
1452+
reveal_type(1 if bool() else 2) # E: Revealed type is 'builtins.int'
1453+
reveal_type(1 if bool() else '') # E: Revealed type is 'Union[builtins.int, builtins.str]'
1454+
class A:
1455+
pass
1456+
class B(A):
1457+
pass
1458+
class C:
1459+
pass
1460+
class D(A):
1461+
pass
1462+
a = A()
1463+
b = B()
1464+
c = C()
1465+
d = D()
1466+
reveal_type(a if bool() else b) # E: Revealed type is '__main__.A'
1467+
reveal_type(b if bool() else c) # E: Revealed type is 'Union[__main__.B, __main__.C]'
1468+
reveal_type(c if bool() else b) # E: Revealed type is 'Union[__main__.C, __main__.B]'
1469+
reveal_type(c if bool() else a) # E: Revealed type is 'Union[__main__.C, __main__.A]'
1470+
reveal_type(d if bool() else b) # E: Revealed type is 'Union[__main__.D, __main__.B]'
1471+
[builtins fixtures/bool.pyi]
1472+
14511473

14521474
-- Special cases
14531475
-- -------------

test-data/unit/check-functions.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,8 +2064,8 @@ def f() -> None:
20642064
def g(x: int) -> None:
20652065
pass
20662066
h = f if bool() else g
2067-
reveal_type(h) # E: Revealed type is 'builtins.function'
2068-
h(7) # E: Cannot call function of unknown type
2067+
reveal_type(h) # E: Revealed type is 'Union[def (), def (x: builtins.int)]'
2068+
h(7) # E: Too many arguments for "f"
20692069
[builtins fixtures/bool.pyi]
20702070

20712071
-- Positional-only arguments

test-data/unit/check-optional.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ def lookup_field(name, obj):
385385
attr = None
386386

387387
[case testTernaryWithNone]
388-
reveal_type(None if bool() else 0) # E: Revealed type is 'Union[builtins.int, builtins.None]'
388+
reveal_type(None if bool() else 0) # E: Revealed type is 'Union[builtins.None, builtins.int]'
389389
[builtins fixtures/bool.pyi]
390390

391391
[case testListWithNone]

0 commit comments

Comments
 (0)