Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 0 additions & 123 deletions test-data/unit/check-isinstance.test
Original file line number Diff line number Diff line change
Expand Up @@ -2699,129 +2699,6 @@ else:
reveal_type(x) # N: Revealed type is "type[__main__.A]"
[builtins fixtures/isinstance.pyi]

[case testTypeEqualsCheck]
from typing import Any

y: Any
if type(y) == int:
reveal_type(y) # N: Revealed type is "builtins.int"


[case testMultipleTypeEqualsCheck]
from typing import Any

x: Any
y: Any
if type(x) == type(y) == int:
reveal_type(y) # N: Revealed type is "builtins.int"
reveal_type(x) # N: Revealed type is "builtins.int"

[case testTypeEqualsCheckUsingIs]
from typing import Any

y: Any
if type(y) is int:
reveal_type(y) # N: Revealed type is "builtins.int"

[case testTypeEqualsCheckUsingIsNonOverlapping]
# flags: --warn-unreachable
from typing import Union

y: str
if type(y) is int: # E: Subclass of "str" and "int" cannot exist: would have incompatible method signatures
y # E: Statement is unreachable
else:
reveal_type(y) # N: Revealed type is "builtins.str"
[builtins fixtures/isinstance.pyi]

[case testTypeEqualsCheckUsingIsNonOverlappingChild-xfail]
# flags: --warn-unreachable
from typing import Union

class A: ...
class B: ...
class C(A): ...
x: Union[B, C]
# C instance cannot be exactly its parent A, we need reversed subtyping relationship
# here (type(parent) is Child).
if type(x) is A:
reveal_type(x) # E: Statement is unreachable
else:
reveal_type(x) # N: Revealed type is "Union[__main__.B, __main__.C]"
[builtins fixtures/isinstance.pyi]

[case testTypeEqualsNarrowingUnionWithElse]
from typing import Union

x: Union[int, str]
if type(x) is int:
reveal_type(x) # N: Revealed type is "builtins.int"
else:
reveal_type(x) # N: Revealed type is "builtins.int | builtins.str"

[case testTypeEqualsMultipleTypesShouldntNarrow]
# flags: --warn-unreachable
# make sure we don't do any narrowing if there are multiple types being compared

from typing import Union

x: Union[int, str]
if type(x) == int == str:
reveal_type(x) # E: Statement is unreachable
else:
reveal_type(x) # N: Revealed type is "builtins.int | builtins.str"

# mypy thinks int isn't defined unless we include this
[builtins fixtures/primitives.pyi]

[case testTypeNotEqualsCheck]
from typing import Union

x: Union[int, str]
if type(x) != int:
reveal_type(x) # N: Revealed type is "builtins.int | builtins.str"
else:
reveal_type(x) # N: Revealed type is "builtins.int"

# mypy thinks int isn't defined unless we include this
[builtins fixtures/primitives.pyi]

[case testTypeNotEqualsCheckUsingIsNot]
from typing import Union

x: Union[int, str]
if type(x) is not int:
reveal_type(x) # N: Revealed type is "builtins.int | builtins.str"
else:
reveal_type(x) # N: Revealed type is "builtins.int"

[case testNarrowInElseCaseIfFinal]
from typing import final, Union
@final
class C:
pass
class D:
pass

x: Union[C, D]
if type(x) is C:
reveal_type(x) # N: Revealed type is "__main__.C"
else:
reveal_type(x) # N: Revealed type is "__main__.D"
[case testNarrowInIfCaseIfFinalUsingIsNot]
from typing import final, Union
@final
class C:
pass
class D:
pass

x: Union[C, D]
if type(x) is not C:
reveal_type(x) # N: Revealed type is "__main__.D"
else:
reveal_type(x) # N: Revealed type is "__main__.C"

[case testHasAttrExistingAttribute]
class C:
x: int
Expand Down
130 changes: 130 additions & 0 deletions test-data/unit/check-narrowing.test
Original file line number Diff line number Diff line change
Expand Up @@ -2920,3 +2920,133 @@ def f2(x: Any) -> None:
return
reveal_type(x) # N: Revealed type is "Any"
[builtins fixtures/tuple.pyi]

[case testTypeEqualsCheck]
# flags: --strict-equality --warn-unreachable
from typing import Any

y: Any
if type(y) == int:
reveal_type(y) # N: Revealed type is "builtins.int"

[case testMultipleTypeEqualsCheck]
# flags: --strict-equality --warn-unreachable
from typing import Any

x: Any
y: Any
if type(x) == type(y) == int:
reveal_type(y) # N: Revealed type is "builtins.int"
reveal_type(x) # N: Revealed type is "builtins.int"

[case testTypeEqualsCheckUsingIs]
# flags: --strict-equality --warn-unreachable
from typing import Any

y: Any
if type(y) is int:
reveal_type(y) # N: Revealed type is "builtins.int"

[case testTypeEqualsCheckUsingIsNonOverlapping]
# flags: --strict-equality --warn-unreachable
from typing import Union

y: str
if type(y) is int: # E: Non-overlapping identity check (left operand type: "type[str]", right operand type: "type[int]") \
# E: Subclass of "str" and "int" cannot exist: would have incompatible method signatures
y # E: Statement is unreachable
else:
reveal_type(y) # N: Revealed type is "builtins.str"
[builtins fixtures/isinstance.pyi]

[case testTypeEqualsCheckUsingIsNonOverlappingChild-xfail]
# flags: --strict-equality --warn-unreachable
from typing import Union

class A: ...
class B: ...
class C(A): ...
def main(x: Union[B, C]):
# C instance cannot be exactly its parent A, we need reversed subtyping relationship
# here (type(parent) is Child).
if type(x) is A:
reveal_type(x) # E: Statement is unreachable
else:
reveal_type(x) # N: Revealed type is "Union[__main__.B, __main__.C]"
[builtins fixtures/isinstance.pyi]

[case testTypeEqualsNarrowingUnionWithElse]
# flags: --strict-equality --warn-unreachable
from typing import Union

x: Union[int, str]
if type(x) is int:
reveal_type(x) # N: Revealed type is "builtins.int"
else:
reveal_type(x) # N: Revealed type is "builtins.int | builtins.str"

[case testTypeEqualsMultipleTypesShouldntNarrow]
# flags: --strict-equality --warn-unreachable

from typing import Union

x: Union[int, str]
if type(x) == int == str: # E: Non-overlapping equality check (left operand type: "type[int]", right operand type: "type[str]")
reveal_type(x) # E: Statement is unreachable
else:
reveal_type(x) # N: Revealed type is "builtins.int | builtins.str"

[builtins fixtures/primitives.pyi]

[case testTypeNotEqualsCheck]
# flags: --strict-equality --warn-unreachable
from typing import Union

x: Union[int, str]
if type(x) != int:
reveal_type(x) # N: Revealed type is "builtins.int | builtins.str"
else:
reveal_type(x) # N: Revealed type is "builtins.int"

# mypy thinks int isn't defined unless we include this
[builtins fixtures/primitives.pyi]

[case testTypeNotEqualsCheckUsingIsNot]
# flags: --strict-equality --warn-unreachable
from typing import Union

x: Union[int, str]
if type(x) is not int:
reveal_type(x) # N: Revealed type is "builtins.int | builtins.str"
else:
reveal_type(x) # N: Revealed type is "builtins.int"

[case testNarrowInElseCaseIfFinal]
# flags: --strict-equality --warn-unreachable
from typing import final, Union
@final
class C:
pass
class D:
pass

x: Union[C, D]
if type(x) is C:
reveal_type(x) # N: Revealed type is "__main__.C"
else:
reveal_type(x) # N: Revealed type is "__main__.D"

[case testNarrowInIfCaseIfFinalUsingIsNot]
# flags: --strict-equality --warn-unreachable
from typing import final, Union
@final
class C:
pass
class D:
pass

x: Union[C, D]
if type(x) is not C:
reveal_type(x) # N: Revealed type is "__main__.D"
else:
reveal_type(x) # N: Revealed type is "__main__.C"