Skip to content

Commit d0905a1

Browse files
committed
More testing related improvements and updates
1 parent 6fa04e4 commit d0905a1

3 files changed

Lines changed: 94 additions & 17 deletions

File tree

test-data/unit/check-narrowing.test

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3479,6 +3479,69 @@ def bar(X: type[T]) -> T:
34793479
raise
34803480
[builtins fixtures/type.pyi]
34813481

3482+
[case testNarrowingConstrainedTypeVarType]
3483+
# flags: --strict-equality --warn-unreachable
3484+
from typing import TypeVar, Any, Type
3485+
3486+
TargetType = TypeVar("TargetType", int, float, str)
3487+
3488+
def convert_type(target_type: Type[TargetType]) -> TargetType:
3489+
if target_type == str:
3490+
return str() # E: Incompatible return value type (got "str", expected "int") \
3491+
# E: Incompatible return value type (got "str", expected "float")
3492+
if target_type == int:
3493+
return int() # E: Incompatible return value type (got "int", expected "str")
3494+
if target_type == float:
3495+
return float() # E: Incompatible return value type (got "float", expected "int") \
3496+
# E: Incompatible return value type (got "float", expected "str")
3497+
raise
3498+
[builtins fixtures/primitives.pyi]
3499+
3500+
3501+
[case testNarrowingEqualityWithPromotions]
3502+
# flags: --strict-equality --warn-unreachable
3503+
from __future__ import annotations
3504+
from typing import Literal
3505+
3506+
def f1(number: float, i: int):
3507+
if number == i:
3508+
reveal_type(number) # N: Revealed type is "builtins.float"
3509+
reveal_type(i) # N: Revealed type is "builtins.int"
3510+
3511+
def f2(number: float, five: Literal[5]):
3512+
if number == five:
3513+
reveal_type(number) # E: Statement is unreachable
3514+
reveal_type(five)
3515+
3516+
def f3(number: float | int, five: Literal[5]):
3517+
if number == five:
3518+
reveal_type(number) # N: Revealed type is "Literal[5]"
3519+
reveal_type(five) # N: Revealed type is "Literal[5]"
3520+
3521+
def f4(number: float | None, i: int):
3522+
if number == i:
3523+
reveal_type(number) # N: Revealed type is "builtins.float | None"
3524+
reveal_type(i) # N: Revealed type is "builtins.int"
3525+
3526+
def f5(number: float | int, i: int):
3527+
if number == i:
3528+
reveal_type(number) # N: Revealed type is "builtins.int"
3529+
reveal_type(i) # N: Revealed type is "builtins.int"
3530+
3531+
def f6(number: float | complex, i: int):
3532+
if number == i:
3533+
reveal_type(number) # N: Revealed type is "builtins.float | builtins.complex"
3534+
reveal_type(i) # N: Revealed type is "builtins.int"
3535+
3536+
class Custom:
3537+
def __eq__(self, other: object) -> bool: return True
3538+
3539+
def f7(number: float, x: Custom | int):
3540+
if number == x:
3541+
reveal_type(number) # N: Revealed type is "builtins.float"
3542+
reveal_type(x) # N: Revealed type is "__main__.Custom"
3543+
[builtins fixtures/primitives.pyi]
3544+
34823545
[case testNarrowingAnyNegativeIntersection-xfail]
34833546
# flags: --strict-equality --warn-unreachable
34843547
# https://github.com/python/mypy/issues/20597

test-data/unit/check-python310.test

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,17 @@ match m:
3636
case other:
3737
reveal_type(other) # N: Revealed type is "Any"
3838

39-
[case testMatchLiteralPatternAlreadyNarrower-skip]
40-
m: bool
39+
[case testMatchLiteralPatternBoolIntAlreadyNarrower]
40+
# flags: --strict-equality --warn-unreachable
4141

42-
match m:
43-
case 1:
44-
reveal_type(m) # This should probably be unreachable, but isn't detected as such.
42+
def foo(m: bool, x: int):
43+
match m:
44+
case 1:
45+
reveal_type(m) # N: Revealed type is "Literal[1]"
46+
47+
match m:
48+
case x:
49+
reveal_type(m) # N: Revealed type is "builtins.bool"
4550
[builtins fixtures/primitives.pyi]
4651

4752
[case testMatchLiteralPatternUnreachable]
@@ -402,7 +407,7 @@ match d.tag:
402407
reveal_type(d) # N: Revealed type is "__main__.B"
403408
reveal_type(d.num) # N: Revealed type is "builtins.int"
404409

405-
[case testMatchSequenceUnion-skip]
410+
[case testMatchSequenceUnion]
406411
from typing import List, Union
407412
m: Union[List[List[str]], str]
408413

@@ -1878,7 +1883,8 @@ match m:
18781883
assert_never(unreachable)
18791884
[builtins fixtures/enum.pyi]
18801885

1881-
[case testMatchLiteralPatternEnumCustomEquals-skip]
1886+
[case testMatchLiteralPatternEnumCustomEquals]
1887+
# flags: --strict-equality --warn-unreachable
18821888
from enum import Enum
18831889
class Medal(Enum):
18841890
gold = 1
@@ -1891,9 +1897,9 @@ m: Medal
18911897

18921898
match m:
18931899
case Medal.gold:
1894-
reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.gold]"
1895-
case _:
18961900
reveal_type(m) # N: Revealed type is "__main__.Medal"
1901+
case _:
1902+
reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.silver] | Literal[__main__.Medal.bronze]"
18971903
[builtins fixtures/enum.pyi]
18981904

18991905
[case testMatchNarrowUsingPatternGuardSpecialCase]
@@ -2035,7 +2041,8 @@ match c:
20352041
assert_never(c) # E: Argument 1 to "assert_never" has incompatible type "Literal['red']"; expected "Never"
20362042
[typing fixtures/typing-typeddict.pyi]
20372043

2038-
[case testMatchAsPatternIntersection-skip]
2044+
[case testMatchAsPatternIntersection]
2045+
# flags: --strict-equality --warn-unreachable
20392046
class A: pass
20402047
class B: pass
20412048
class C: pass
@@ -2046,7 +2053,7 @@ def f(x: A) -> None:
20462053
reveal_type(y) # N: Revealed type is "__main__.<subclass of "__main__.A" and "__main__.B">"
20472054
case C() as y:
20482055
reveal_type(y) # N: Revealed type is "__main__.<subclass of "__main__.A" and "__main__.C">"
2049-
reveal_type(y) # N: Revealed type is "Union[__main__.<subclass of "__main__.A" and "__main__.B">, __main__.<subclass of "__main__.A" and "__main__.C">]"
2056+
reveal_type(y) # N: Revealed type is "__main__.<subclass of "__main__.A" and "__main__.B"> | __main__.<subclass of "__main__.A" and "__main__.C">"
20502057

20512058
[case testMatchWithBreakAndContinue]
20522059
def f(x: int | str | None) -> None:

test-data/unit/check-tuples.test

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,17 +1533,24 @@ reveal_type(x) # N: Revealed type is "tuple[builtins.int, builtins.int]"
15331533
[builtins fixtures/tuple.pyi]
15341534

15351535
[case testTupleOverlapDifferentTuples]
1536+
# flags: --warn-unreachable
15361537
from typing import Optional, Tuple
15371538
class A: pass
15381539
class B: pass
15391540

1540-
possibles: Tuple[int, Tuple[A]]
1541-
x: Optional[Tuple[B]]
1541+
def f1(possibles: Tuple[int, Tuple[A]], x: Optional[Tuple[B]]):
1542+
if x in possibles:
1543+
reveal_type(x) # N: Revealed type is "tuple[__main__.B]"
1544+
else:
1545+
reveal_type(x) # N: Revealed type is "tuple[__main__.B] | None"
1546+
1547+
class AA(A): pass
15421548

1543-
if x in possibles:
1544-
reveal_type(x) # N: Revealed type is "tuple[__main__.B]"
1545-
else:
1546-
reveal_type(x) # N: Revealed type is "tuple[__main__.B] | None"
1549+
def f2(possibles: Tuple[int, Tuple[A]], x: Optional[Tuple[AA]]):
1550+
if x in possibles:
1551+
reveal_type(x) # N: Revealed type is "tuple[__main__.AA]"
1552+
else:
1553+
reveal_type(x) # N: Revealed type is "tuple[__main__.AA] | None"
15471554

15481555
[builtins fixtures/tuple.pyi]
15491556

0 commit comments

Comments
 (0)