mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:25:17 +00:00

## Summary This changeset adds support for precise type-inference and boundness-handling of definitions inside control-flow branches with statically-known conditions, i.e. test-expressions whose truthiness we can unambiguously infer as *always false* or *always true*. This branch also includes: - `sys.platform` support - statically-known branches handling for Boolean expressions and while loops - new `target-version` requirements in some Markdown tests which were now required due to the understanding of `sys.version_info` branches. closes #12700 closes #15034 ## Performance ### `tomllib`, -7%, needs to resolve one additional module (sys) | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | |:---|---:|---:|---:|---:| | `./red_knot_main --project /home/shark/tomllib` | 22.2 ± 1.3 | 19.1 | 25.6 | 1.00 | | `./red_knot_feature --project /home/shark/tomllib` | 23.8 ± 1.6 | 20.8 | 28.6 | 1.07 ± 0.09 | ### `black`, -6% | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | |:---|---:|---:|---:|---:| | `./red_knot_main --project /home/shark/black` | 129.3 ± 5.1 | 119.0 | 137.8 | 1.00 | | `./red_knot_feature --project /home/shark/black` | 136.5 ± 6.8 | 123.8 | 147.5 | 1.06 ± 0.07 | ## Test Plan - New Markdown tests for the main feature in `statically-known-branches.md` - New Markdown tests for `sys.platform` - Adapted tests for `EllipsisType`, `Never`, etc
999 B
999 B
If expression
Union
def _(flag: bool):
reveal_type(1 if flag else 2) # revealed: Literal[1, 2]
Statically known conditions in if-expressions
reveal_type(1 if True else 2) # revealed: Literal[1]
reveal_type(1 if "not empty" else 2) # revealed: Literal[1]
reveal_type(1 if (1,) else 2) # revealed: Literal[1]
reveal_type(1 if 1 else 2) # revealed: Literal[1]
reveal_type(1 if False else 2) # revealed: Literal[2]
reveal_type(1 if None else 2) # revealed: Literal[2]
reveal_type(1 if "" else 2) # revealed: Literal[2]
reveal_type(1 if 0 else 2) # revealed: Literal[2]
Leaked Narrowing Constraint
(issue #14588)
The test inside an if expression should not affect code outside of the expression.
def _(flag: bool):
x: Literal[42, "hello"] = 42 if flag else "hello"
reveal_type(x) # revealed: Literal[42] | Literal["hello"]
_ = ... if isinstance(x, str) else ...
reveal_type(x) # revealed: Literal[42] | Literal["hello"]