mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-24 21:43:52 +00:00
2.1 KiB
2.1 KiB
Narrowing in boolean expressions
In or
expressions, the right-hand side is evaluated only if the left-hand side is falsy. So
when the right-hand side is evaluated, we know the left side has failed.
Similarly, in and
expressions, the right-hand side is evaluated only if the left-hand side is
truthy. So when the right-hand side is evaluated, we know the left side has succeeded.
Narrowing in or
def _(flag: bool):
class A: ...
x: A | None = A() if flag else None
isinstance(x, A) or reveal_type(x) # revealed: None
x is None or reveal_type(x) # revealed: A
reveal_type(x) # revealed: A | None
Narrowing in and
def _(flag: bool):
class A: ...
x: A | None = A() if flag else None
isinstance(x, A) and reveal_type(x) # revealed: A
x is None and reveal_type(x) # revealed: None
reveal_type(x) # revealed: A | None
Multiple and
arms
def _(flag1: bool, flag2: bool, flag3: bool, flag4: bool):
class A: ...
x: A | None = A() if flag1 else None
flag2 and isinstance(x, A) and reveal_type(x) # revealed: A
isinstance(x, A) and flag2 and reveal_type(x) # revealed: A
reveal_type(x) and isinstance(x, A) and flag3 # revealed: A | None
Multiple or
arms
def _(flag1: bool, flag2: bool, flag3: bool, flag4: bool):
class A: ...
x: A | None = A() if flag1 else None
flag2 or isinstance(x, A) or reveal_type(x) # revealed: None
isinstance(x, A) or flag3 or reveal_type(x) # revealed: None
reveal_type(x) or isinstance(x, A) or flag4 # revealed: A | None
Multiple predicates
from typing import Literal
def _(flag1: bool, flag2: bool):
class A: ...
x: A | None | Literal[1] = A() if flag1 else None if flag2 else 1
x is None or isinstance(x, A) or reveal_type(x) # revealed: Literal[1]
Mix of and
and or
from typing import Literal
def _(flag1: bool, flag2: bool):
class A: ...
x: A | None | Literal[1] = A() if flag1 else None if flag2 else 1
isinstance(x, A) or x is not None and reveal_type(x) # revealed: Literal[1]