[ty] Simplify union lower bounds and intersection upper bounds in constraint sets by dcreager · Pull Request #21871 · astral-sh/ruff (original) (raw)

@dcreager

@dcreager dcreager added internal

An internal refactor or improvement

ty

Multi-file analysis & type inference

labels

Dec 9, 2025

@dcreager

@dcreager

@dcreager

@dcreager dcreager deleted the dcreager/die-die-intersections branch

December 10, 2025 00:49

dcreager added a commit that referenced this pull request

Dec 10, 2025

@dcreager

sharkdp

dcreager added a commit that referenced this pull request

Dec 10, 2025

@dcreager

This fixes the logic error that @sharkdp [found](#21871 (comment)) in the constraint set upper bound normalization logic I introduced in #21871.

I had originally claimed that (T ≤ α & ~β) should simplify into (T ≤ α) ∧ ¬(T ≤ β). But that also suggests that T ≤ ~β should simplify to ¬(T ≤ β) on its own, and that's not correct.

The correct simplification is that is an "atomic" type, not an "intersection" for the purposes of our upper bound simplifcation. So (T ≤ α & ~β) should simplify to (T ≤ α) ∧ (T ≤ ~β). That is, break apart the elements of a (proper) intersection, regardless of whether each element is negated or not.

This PR fixes the logic, adds a test case, and updates the comments to be hopefully more clear and accurate.

KotlinIsland pushed a commit to KotlinIsland/basedpython that referenced this pull request

May 1, 2026

@dcreager

This fixes the logic error that @sharkdp [found](astral-sh/ruff#21871 (comment)) in the constraint set upper bound normalization logic I introduced in #21871.

I had originally claimed that (T ≤ α & ~β) should simplify into (T ≤ α) ∧ ¬(T ≤ β). But that also suggests that T ≤ ~β should simplify to ¬(T ≤ β) on its own, and that's not correct.

The correct simplification is that is an "atomic" type, not an "intersection" for the purposes of our upper bound simplifcation. So (T ≤ α & ~β) should simplify to (T ≤ α) ∧ (T ≤ ~β). That is, break apart the elements of a (proper) intersection, regardless of whether each element is negated or not.

This PR fixes the logic, adds a test case, and updates the comments to be hopefully more clear and accurate.

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})