2.8 KiB
2.8 KiB
Statically-known branches
Always false
If
x = 1
if False:
x = 2
reveal_type(x) # revealed: Literal[1]
Else
x = 1
if True:
pass
else:
x = 2
reveal_type(x) # revealed: Literal[1]
Always true
If
x = 1
if True:
x = 2
reveal_type(x) # revealed: Literal[2]
Else
x = 1
if False:
pass
else:
x = 2
reveal_type(x) # revealed: Literal[2]
Combination
x = 1
if True:
x = 2
else:
x = 3
reveal_type(x) # revealed: Literal[2]
Nested
x = 1
if True:
if True:
x = 2
else:
x = 3
else:
x = 4
reveal_type(x) # revealed: Literal[2]
x = 1
if True:
if False:
x = 2
else:
x = 3
else:
x = 4
reveal_type(x) # revealed: Literal[3]
def flag() -> bool: ...
x = 1
if True:
if flag():
x = 2
else:
x = 3
else:
x = 4
reveal_type(x) # revealed: Literal[2, 3]
def flag() -> bool: ...
x = 1
if flag():
if True:
x = 2
else:
x = 3
else:
x = 4
reveal_type(x) # revealed: Literal[2, 4]
x = 1
if False:
x = 2
else:
if True:
x = 3
else:
x = 4
reveal_type(x) # revealed: Literal[3]
x = 1
if False:
x = 2
else:
if False:
x = 3
else:
x = 4
reveal_type(x) # revealed: Literal[4]
def flag() -> bool: ...
x = 1
if False:
x = 2
else:
if flag():
x = 3
else:
x = 4
reveal_type(x) # revealed: Literal[3, 4]
If-expressions
Always true
x = 1 if True else 2
reveal_type(x) # revealed: Literal[1]
Always false
x = 1 if False else 2
reveal_type(x) # revealed: Literal[2]
Boolean expressions
Always true
(x := 1) == 1 or (x := 2)
reveal_type(x) # revealed: Literal[1]
Always false
(x := 1) == 0 or (x := 2)
reveal_type(x) # revealed: Literal[2]
Conditionally defined functions
def f() -> int: ...
def g() -> int: ...
if True:
def f() -> str: ...
else:
def g() -> str: ...
reveal_type(f()) # revealed: str
reveal_type(g()) # revealed: int
Conditionally defined class attributes
class C:
if True:
x: int = 1
else:
x: str = "a"
# TODO
reveal_type(C.x) # revealed: int | str
TODO
- boundness
- conditional imports
- conditional class definitions
- compare with tests in if.md=>Statically known branches
- is the change here correct: https://github.com/astral-sh/ruff/pull/14590/files