Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[ty] Preserve short-circuit bindings in all condition consumers#25160

Merged
charliermarsh merged 1 commit into
mainfrom
charlie/neg-condition
May 18, 2026
Merged

[ty] Preserve short-circuit bindings in all condition consumers#25160
charliermarsh merged 1 commit into
mainfrom
charlie/neg-condition

Conversation

@charliermarsh

@charliermarsh charliermarsh commented May 14, 2026

Copy link
Copy Markdown
Member

Summary

We already compute precise truthy and falsy flow snapshots for short-circuiting boolean expressions, so walrus bindings are only visible on paths where the right-hand side actually ran. Prior to this change, we mostly used those snapshots for if conditions, and not (e.g.) in the following case:

def f(flag: bool):
    assert flag and (x := 1)
    reveal_type(x)

This PR generalizes that logic into condition-flow snapshots and applies it anywhere we evaluate a condition before
continuing under its truthy or falsy outcome: assert, while, match guards, conditional expressions, and comprehension filters.

@astral-sh-bot astral-sh-bot Bot added the ty Multi-file analysis & type inference label May 14, 2026
@astral-sh-bot

astral-sh-bot Bot commented May 14, 2026

Copy link
Copy Markdown

Typing conformance results

No changes detected ✅

Current numbers
The percentage of diagnostics emitted that were expected errors held steady at 89.36%. The percentage of expected errors that received a diagnostic held steady at 85.49%. The number of fully passing files held steady at 88/134.

@astral-sh-bot

astral-sh-bot Bot commented May 14, 2026

Copy link
Copy Markdown

Memory usage report

Memory usage unchanged ✅

@astral-sh-bot

astral-sh-bot Bot commented May 14, 2026

Copy link
Copy Markdown

ecosystem-analyzer results

Lint rule Added Removed Changed
possibly-unresolved-reference 0 54 0
Total 0 54 0
Raw diff (54 changes)
CPython (peg_generator) (https://github.com/python/cpython)
- Tools/peg_generator/pegen/grammar_parser.py:685:29 warning[possibly-unresolved-reference] Name `elem` used when possibly not defined

Tanjun (https://github.com/FasterSpeeding/Tanjun)
- tanjun/_internal/__init__.py:370:26 warning[possibly-unresolved-reference] Name `first_option` used when possibly not defined
- tanjun/_internal/__init__.py:371:65 warning[possibly-unresolved-reference] Name `first_option` used when possibly not defined

core (https://github.com/home-assistant/core)
- homeassistant/components/bthome/event.py:113:27 warning[possibly-unresolved-reference] Name `address_event_class` used when possibly not defined
- homeassistant/components/bthome/event.py:113:51 warning[possibly-unresolved-reference] Name `address_event_class` used when possibly not defined
- homeassistant/components/esphome/ffmpeg_proxy.py:240:34 warning[possibly-unresolved-reference] Name `chunk` used when possibly not defined
- homeassistant/components/esphome/ffmpeg_proxy.py:315:20 warning[possibly-unresolved-reference] Name `chunk` used when possibly not defined
- homeassistant/components/xiaomi_ble/event.py:192:27 warning[possibly-unresolved-reference] Name `address_event_class` used when possibly not defined
- homeassistant/components/xiaomi_ble/event.py:192:51 warning[possibly-unresolved-reference] Name `address_event_class` used when possibly not defined
- homeassistant/helpers/integration_platform.py:134:9 warning[possibly-unresolved-reference] Name `future` used when possibly not defined
- homeassistant/helpers/translation.py:79:20 warning[possibly-unresolved-reference] Name `category_strings` used when possibly not defined
- homeassistant/components/habitica/sensor.py:363:40 warning[possibly-unresolved-reference] Name `k` used when possibly not defined
- homeassistant/components/habitica/util.py:122:17 warning[possibly-unresolved-reference] Name `stats` used when possibly not defined
- homeassistant/components/habitica/util.py:129:17 warning[possibly-unresolved-reference] Name `stats` used when possibly not defined
- homeassistant/components/habitica/util.py:217:13 warning[possibly-unresolved-reference] Name `collect` used when possibly not defined
- homeassistant/components/habitica/util.py:217:39 warning[possibly-unresolved-reference] Name `collect` used when possibly not defined
- homeassistant/components/home_connect/select.py:434:24 warning[possibly-unresolved-reference] Name `event_value` used when possibly not defined
- homeassistant/components/igloohome/lock.py:39:27 warning[possibly-unresolved-reference] Name `bridge` used when possibly not defined
- homeassistant/components/mqtt/siren.py:341:28 warning[possibly-unresolved-reference] Name `data_attr` used when possibly not defined
- homeassistant/components/notion/binary_sensor.py:118:17 warning[possibly-unresolved-reference] Name `sensor` used when possibly not defined
- homeassistant/components/notion/binary_sensor.py:119:17 warning[possibly-unresolved-reference] Name `sensor` used when possibly not defined
- homeassistant/components/notion/sensor.py:56:17 warning[possibly-unresolved-reference] Name `sensor` used when possibly not defined
- homeassistant/components/notion/sensor.py:57:17 warning[possibly-unresolved-reference] Name `sensor` used when possibly not defined
- homeassistant/components/portainer/sensor.py:133:14 warning[possibly-unresolved-reference] Name `total_delta` used when possibly not defined
- homeassistant/components/portainer/sensor.py:133:28 warning[possibly-unresolved-reference] Name `system_delta` used when possibly not defined
- homeassistant/components/recorder/core.py:829:43 warning[possibly-unresolved-reference] Name `task_or_event` used when possibly not defined
- homeassistant/components/shelly/config_flow.py:641:13 warning[possibly-unresolved-reference] Name `mac` used when possibly not defined
- homeassistant/components/tplink/entity.py:432:29 warning[possibly-unresolved-reference] Name `desc` used when possibly not defined
- homeassistant/components/xbox/coordinator.py:263:13 warning[possibly-unresolved-reference] Name `prev_data` used when possibly not defined
- homeassistant/components/xbox/entity.py:88:13 warning[possibly-unresolved-reference] Name `entity_picture` used when possibly not defined
- homeassistant/components/xbox/media_player.py:178:22 warning[possibly-unresolved-reference] Name `image` used when possibly not defined
- homeassistant/components/xiaomi_miio/sensor.py:881:19 warning[possibly-unresolved-reference] Name `value` used when possibly not defined

dd-trace-py (https://github.com/DataDog/dd-trace-py)
- ddtrace/debugging/_session.py:117:46 warning[possibly-unresolved-reference] Name `context` used when possibly not defined

hydpy (https://github.com/hydpy-dev/hydpy)
- hydpy/core/importtools.py:819:35 warning[possibly-unresolved-reference] Name `frame2` used when possibly not defined
- hydpy/core/modeltools.py:2219:25 warning[possibly-unresolved-reference] Name `frame3` used when possibly not defined
- hydpy/core/parametertools.py:142:45 warning[possibly-unresolved-reference] Name `frame` used when possibly not defined
- hydpy/core/parametertools.py:144:31 warning[possibly-unresolved-reference] Name `frame` used when possibly not defined
- hydpy/core/parametertools.py:148:38 warning[possibly-unresolved-reference] Name `frame` used when possibly not defined
- hydpy/core/parametertools.py:1341:19 warning[possibly-unresolved-reference] Name `frame` used when possibly not defined
- hydpy/core/parametertools.py:1342:29 warning[possibly-unresolved-reference] Name `frame` used when possibly not defined
- hydpy/core/parametertools.py:1347:29 warning[possibly-unresolved-reference] Name `frame` used when possibly not defined

mkdocs (https://github.com/mkdocs/mkdocs)
- mkdocs/utils/rendering.py:34:36 warning[possibly-unresolved-reference] Name `end` used when possibly not defined
- mkdocs/utils/rendering.py:37:36 warning[possibly-unresolved-reference] Name `end` used when possibly not defined

mkosi (https://github.com/systemd/mkosi)
- mkosi/config.py:1565:17 warning[possibly-unresolved-reference] Name `p` used when possibly not defined
- mkosi/config.py:1570:30 warning[possibly-unresolved-reference] Name `p` used when possibly not defined
- mkosi/config.py:1571:17 warning[possibly-unresolved-reference] Name `p` used when possibly not defined
- mkosi/config.py:1572:17 warning[possibly-unresolved-reference] Name `p` used when possibly not defined

mypy (https://github.com/python/mypy)
- mypyc/irbuild/specialize.py:928:46 warning[possibly-unresolved-reference] Name `first` used when possibly not defined
- mypyc/irbuild/specialize.py:928:54 warning[possibly-unresolved-reference] Name `second` used when possibly not defined

openlibrary (https://github.com/internetarchive/openlibrary)
- openlibrary/coverstore/code.py:514:10 warning[possibly-unresolved-reference] Name `cover` used when possibly not defined

rotki (https://github.com/rotki/rotki)
- rotkehlchen/api/services/assets.py:561:24 warning[possibly-unresolved-reference] Name `historical_oracle` used when possibly not defined
- rotkehlchen/chain/evm/decoding/curve/decoder.py:401:17 warning[possibly-unresolved-reference] Name `withdrawn_asset` used when possibly not defined

sympy (https://github.com/sympy/sympy)
- sympy/simplify/_cse_diff.py:152:21 warning[possibly-unresolved-reference] Name `diff_value` used when possibly not defined
- sympy/simplify/_cse_diff.py:169:46 warning[possibly-unresolved-reference] Name `diff_value` used when possibly not defined

Full report with detailed diff (timing results)

@charliermarsh charliermarsh force-pushed the charlie/neg-condition branch from 52d298f to bcbf261 Compare May 14, 2026 14:51
@charliermarsh charliermarsh changed the title [ty] Preserve walrus bindings from truthy short-circuit conditions [ty] Preserve short-circuit bindings in all condition consumers May 14, 2026
@charliermarsh charliermarsh marked this pull request as ready for review May 14, 2026 15:50
@charliermarsh charliermarsh merged commit ab1e16d into main May 18, 2026
59 checks passed
@charliermarsh charliermarsh deleted the charlie/neg-condition branch May 18, 2026 13:13
thejchap pushed a commit to thejchap/ruff that referenced this pull request May 23, 2026
…al-sh#25160)

## Summary

We already compute precise truthy and falsy flow snapshots for
short-circuiting boolean expressions, so walrus bindings are only
visible on paths where the right-hand side actually ran. Prior to this
change, we mostly used those snapshots for `if` conditions, and not
(e.g.) in the following case:

```python
def f(flag: bool):
    assert flag and (x := 1)
    reveal_type(x)
```

This PR generalizes that logic into condition-flow snapshots and applies
it anywhere we evaluate a condition before
continuing under its truthy or falsy outcome: `assert`, `while`, `match`
guards, conditional expressions, and comprehension filters.
anishgirianish pushed a commit to anishgirianish/ruff that referenced this pull request May 28, 2026
…al-sh#25160)

## Summary

We already compute precise truthy and falsy flow snapshots for
short-circuiting boolean expressions, so walrus bindings are only
visible on paths where the right-hand side actually ran. Prior to this
change, we mostly used those snapshots for `if` conditions, and not
(e.g.) in the following case:

```python
def f(flag: bool):
    assert flag and (x := 1)
    reveal_type(x)
```

This PR generalizes that logic into condition-flow snapshots and applies
it anywhere we evaluate a condition before
continuing under its truthy or falsy outcome: `assert`, `while`, `match`
guards, conditional expressions, and comprehension filters.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants