Skip to content

Commit 25b1c4d

Browse files
authored
Fix 0.750 regression: union (non-)simplification should not affect inference (#8077)
Fixes #8051 The fix is as discussed in the issue. I didn't find a test case for the union `actual`, but I think it makes sense to simplify it as well. Note: I add the `pythoneval` test just as a regression test, if you think it is not worth it, I can remove it.
1 parent 07d1681 commit 25b1c4d

File tree

4 files changed

+32
-2
lines changed

4 files changed

+32
-2
lines changed

mypy/constraints.py

+6
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ def _infer_constraints(template: Type, actual: Type,
108108
template = get_proper_type(template)
109109
actual = get_proper_type(actual)
110110

111+
# Type inference shouldn't be affected by whether union types have been simplified.
112+
if isinstance(template, UnionType):
113+
template = mypy.typeops.make_simplified_union(template.items)
114+
if isinstance(actual, UnionType):
115+
actual = mypy.typeops.make_simplified_union(actual.items)
116+
111117
# Ignore Any types from the type suggestion engine to avoid them
112118
# causing us to infer Any in situations where a better job could
113119
# be done otherwise. (This can produce false positives but that

test-data/unit/check-inference.test

+15
Original file line numberDiff line numberDiff line change
@@ -2924,3 +2924,18 @@ reveal_type(q2(z)) # N: Revealed type is '__main__.B*'
29242924
reveal_type(q1(Z(b))) # N: Revealed type is '__main__.B*'
29252925
reveal_type(q2(Z(b))) # N: Revealed type is '__main__.B*'
29262926
[builtins fixtures/isinstancelist.pyi]
2927+
2928+
[case testUnionInvariantSubClassAndCovariantBase]
2929+
from typing import Union, Generic, TypeVar
2930+
2931+
T = TypeVar('T')
2932+
T_co = TypeVar('T_co', covariant=True)
2933+
2934+
class Cov(Generic[T_co]): ...
2935+
class Inv(Cov[T]): ...
2936+
2937+
X = Union[Cov[T], Inv[T]]
2938+
2939+
def f(x: X[T]) -> T: ...
2940+
x: Inv[int]
2941+
reveal_type(f(x)) # N: Revealed type is 'builtins.int*'

test-data/unit/check-overloading.test

+2-2
Original file line numberDiff line numberDiff line change
@@ -3646,7 +3646,7 @@ def test_narrow_none() -> None:
36463646
a: Optional[int]
36473647
if int():
36483648
a = narrow_none(a)
3649-
reveal_type(a) # N: Revealed type is 'Union[builtins.int, None]'
3649+
reveal_type(a) # N: Revealed type is 'builtins.int'
36503650

36513651
b: int
36523652
if int():
@@ -3710,7 +3710,7 @@ def test_narrow_none_v2() -> None:
37103710
a: Optional[int]
37113711
if int():
37123712
a = narrow_none_v2(a)
3713-
reveal_type(a) # N: Revealed type is 'Union[builtins.int, None]'
3713+
reveal_type(a) # N: Revealed type is 'builtins.int'
37143714

37153715
b: int
37163716
if int():

test-data/unit/pythoneval.test

+9
Original file line numberDiff line numberDiff line change
@@ -1490,3 +1490,12 @@ reveal_type(A().b)
14901490
[out]
14911491
_testNamedTupleAtRunTime.py:5: error: NamedTuple type as an attribute is not supported
14921492
_testNamedTupleAtRunTime.py:7: note: Revealed type is 'Any'
1493+
1494+
[case testAsyncioFutureWait]
1495+
# mypy: strict-optional
1496+
from asyncio import Future, wait
1497+
from typing import List
1498+
1499+
async def foo() -> None:
1500+
f = [] # type: List[Future[None]]
1501+
await wait(f)

0 commit comments

Comments
 (0)