Skip to content

Commit

Permalink
Fix type of conditional statement to Union and not Join (#5041)
Browse files Browse the repository at this point in the history
Fixes #3487
  • Loading branch information
MentalMegalodon authored and msullivan committed May 14, 2018
1 parent 1dbe724 commit 532f3fb
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 6 deletions.
4 changes: 2 additions & 2 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1328,9 +1328,9 @@ def check_protocol_variance(self, defn: ClassDef) -> None:
tvars = info.defn.type_vars
for i, tvar in enumerate(tvars):
up_args = [object_type if i == j else AnyType(TypeOfAny.special_form)
for j, _ in enumerate(tvars)]
for j, _ in enumerate(tvars)] # type: List[Type]
down_args = [UninhabitedType() if i == j else AnyType(TypeOfAny.special_form)
for j, _ in enumerate(tvars)]
for j, _ in enumerate(tvars)] # type: List[Type]
up, down = Instance(info, up_args), Instance(info, down_args)
# TODO: add advanced variance checks for recursive protocols
if is_subtype(down, up, ignore_declared_variance=True):
Expand Down
2 changes: 1 addition & 1 deletion mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -2342,7 +2342,7 @@ def visit_conditional_expr(self, e: ConditionalExpr) -> Type:
# branch's type.
else_type = self.analyze_cond_branch(else_map, e.else_expr, context=if_type)

res = join.join_types(if_type, else_type)
res = UnionType.make_simplified_union([if_type, else_type])

return res

Expand Down
22 changes: 22 additions & 0 deletions test-data/unit/check-expressions.test
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,28 @@ x = [1]
x = ['x'] # E: List item 0 has incompatible type "str"; expected "int"
[builtins fixtures/list.pyi]

[case testConditionalExpressionUnion]
reveal_type(1 if bool() else 2) # E: Revealed type is 'builtins.int'
reveal_type(1 if bool() else '') # E: Revealed type is 'Union[builtins.int, builtins.str]'
class A:
pass
class B(A):
pass
class C:
pass
class D(A):
pass
a = A()
b = B()
c = C()
d = D()
reveal_type(a if bool() else b) # E: Revealed type is '__main__.A'
reveal_type(b if bool() else c) # E: Revealed type is 'Union[__main__.B, __main__.C]'
reveal_type(c if bool() else b) # E: Revealed type is 'Union[__main__.C, __main__.B]'
reveal_type(c if bool() else a) # E: Revealed type is 'Union[__main__.C, __main__.A]'
reveal_type(d if bool() else b) # E: Revealed type is 'Union[__main__.D, __main__.B]'
[builtins fixtures/bool.pyi]


-- Special cases
-- -------------
Expand Down
4 changes: 2 additions & 2 deletions test-data/unit/check-functions.test
Original file line number Diff line number Diff line change
Expand Up @@ -2064,8 +2064,8 @@ def f() -> None:
def g(x: int) -> None:
pass
h = f if bool() else g
reveal_type(h) # E: Revealed type is 'builtins.function'
h(7) # E: Cannot call function of unknown type
reveal_type(h) # E: Revealed type is 'Union[def (), def (x: builtins.int)]'
h(7) # E: Too many arguments for "f"
[builtins fixtures/bool.pyi]

-- Positional-only arguments
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-optional.test
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ def lookup_field(name, obj):
attr = None

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

[case testListWithNone]
Expand Down

0 comments on commit 532f3fb

Please sign in to comment.