diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test index e10f858ff15b..87aad505d119 100644 --- a/test-data/unit/check-narrowing.test +++ b/test-data/unit/check-narrowing.test @@ -3439,6 +3439,69 @@ def bar(X: type[T]) -> T: raise [builtins fixtures/type.pyi] +[case testNarrowingConstrainedTypeVarType] +# flags: --strict-equality --warn-unreachable +from typing import TypeVar, Any, Type + +TargetType = TypeVar("TargetType", int, float, str) + +def convert_type(target_type: Type[TargetType]) -> TargetType: + if target_type == str: + return str() # E: Incompatible return value type (got "str", expected "int") \ + # E: Incompatible return value type (got "str", expected "float") + if target_type == int: + return int() # E: Incompatible return value type (got "int", expected "str") + if target_type == float: + return float() # E: Incompatible return value type (got "float", expected "int") \ + # E: Incompatible return value type (got "float", expected "str") + raise +[builtins fixtures/primitives.pyi] + + +[case testNarrowingEqualityWithPromotions] +# flags: --strict-equality --warn-unreachable +from __future__ import annotations +from typing import Literal + +def f1(number: float, i: int): + if number == i: + reveal_type(number) # N: Revealed type is "builtins.float" + reveal_type(i) # N: Revealed type is "builtins.int" + +def f2(number: float, five: Literal[5]): + if number == five: + reveal_type(number) # E: Statement is unreachable + reveal_type(five) + +def f3(number: float | int, five: Literal[5]): + if number == five: + reveal_type(number) # N: Revealed type is "Literal[5]" + reveal_type(five) # N: Revealed type is "Literal[5]" + +def f4(number: float | None, i: int): + if number == i: + reveal_type(number) # N: Revealed type is "builtins.float | None" + reveal_type(i) # N: Revealed type is "builtins.int" + +def f5(number: float | int, i: int): + if number == i: + reveal_type(number) # N: Revealed type is "builtins.int" + reveal_type(i) # N: Revealed type is "builtins.int" + +def f6(number: float | complex, i: int): + if number == i: + reveal_type(number) # N: Revealed type is "builtins.float | builtins.complex" + reveal_type(i) # N: Revealed type is "builtins.int" + +class Custom: + def __eq__(self, other: object) -> bool: return True + +def f7(number: float, x: Custom | int): + if number == x: + reveal_type(number) # N: Revealed type is "builtins.float" + reveal_type(x) # N: Revealed type is "__main__.Custom" +[builtins fixtures/primitives.pyi] + [case testNarrowingAnyNegativeIntersection-xfail] # flags: --strict-equality --warn-unreachable # https://github.com/python/mypy/issues/20597 diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index 7482836b9730..1bd106e67d9b 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -36,12 +36,17 @@ match m: case other: reveal_type(other) # N: Revealed type is "Any" -[case testMatchLiteralPatternAlreadyNarrower-skip] -m: bool +[case testMatchLiteralPatternBoolIntAlreadyNarrower] +# flags: --strict-equality --warn-unreachable -match m: - case 1: - reveal_type(m) # This should probably be unreachable, but isn't detected as such. +def foo(m: bool, x: int): + match m: + case 1: + reveal_type(m) # N: Revealed type is "Literal[1]" + + match m: + case x: + reveal_type(m) # N: Revealed type is "builtins.bool" [builtins fixtures/primitives.pyi] [case testMatchLiteralPatternUnreachable] @@ -402,7 +407,7 @@ match d.tag: reveal_type(d) # N: Revealed type is "__main__.B" reveal_type(d.num) # N: Revealed type is "builtins.int" -[case testMatchSequenceUnion-skip] +[case testMatchSequenceUnion] from typing import List, Union m: Union[List[List[str]], str] @@ -1878,7 +1883,8 @@ match m: assert_never(unreachable) [builtins fixtures/enum.pyi] -[case testMatchLiteralPatternEnumCustomEquals-skip] +[case testMatchLiteralPatternEnumCustomEquals] +# flags: --strict-equality --warn-unreachable from enum import Enum class Medal(Enum): gold = 1 @@ -1891,9 +1897,9 @@ m: Medal match m: case Medal.gold: - reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.gold]" - case _: reveal_type(m) # N: Revealed type is "__main__.Medal" + case _: + reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.silver] | Literal[__main__.Medal.bronze]" [builtins fixtures/enum.pyi] [case testMatchNarrowUsingPatternGuardSpecialCase] @@ -2035,7 +2041,8 @@ match c: assert_never(c) # E: Argument 1 to "assert_never" has incompatible type "Literal['red']"; expected "Never" [typing fixtures/typing-typeddict.pyi] -[case testMatchAsPatternIntersection-skip] +[case testMatchAsPatternIntersection] +# flags: --strict-equality --warn-unreachable class A: pass class B: pass class C: pass @@ -2046,7 +2053,7 @@ def f(x: A) -> None: reveal_type(y) # N: Revealed type is "__main__." case C() as y: reveal_type(y) # N: Revealed type is "__main__." - reveal_type(y) # N: Revealed type is "Union[__main__., __main__.]" + reveal_type(y) # N: Revealed type is "__main__. | __main__." [case testMatchWithBreakAndContinue] def f(x: int | str | None) -> None: diff --git a/test-data/unit/check-tuples.test b/test-data/unit/check-tuples.test index 9633aae0dba0..5dcc34027c70 100644 --- a/test-data/unit/check-tuples.test +++ b/test-data/unit/check-tuples.test @@ -1533,17 +1533,24 @@ reveal_type(x) # N: Revealed type is "tuple[builtins.int, builtins.int]" [builtins fixtures/tuple.pyi] [case testTupleOverlapDifferentTuples] +# flags: --warn-unreachable from typing import Optional, Tuple class A: pass class B: pass -possibles: Tuple[int, Tuple[A]] -x: Optional[Tuple[B]] +def f1(possibles: Tuple[int, Tuple[A]], x: Optional[Tuple[B]]): + if x in possibles: + reveal_type(x) # N: Revealed type is "tuple[__main__.B]" + else: + reveal_type(x) # N: Revealed type is "tuple[__main__.B] | None" + +class AA(A): pass -if x in possibles: - reveal_type(x) # N: Revealed type is "tuple[__main__.B]" -else: - reveal_type(x) # N: Revealed type is "tuple[__main__.B] | None" +def f2(possibles: Tuple[int, Tuple[A]], x: Optional[Tuple[AA]]): + if x in possibles: + reveal_type(x) # N: Revealed type is "tuple[__main__.AA]" + else: + reveal_type(x) # N: Revealed type is "tuple[__main__.AA] | None" [builtins fixtures/tuple.pyi]