ruff PLR1733: fix changes program behavior
Hypothesis Nemotron 3 Super predicted to fire fired 1×
In async context, replacing d[k] with v alters await timing if d[k] is awaitable.
Program
Output
(no stdout)
(no stdout) TypeError: object int can't be used in 'await' expression
- fired
- 1 before · 0 after
- runs
- each version twice, same file name, no network
Judge Nemotron 3 Ultra advisory real · high
The rule assumes that the value yielded by .items() is identical to the value returned by __getitem__, but the program uses a custom dict subclass where __getitem__ returns an awaitable while the stored value is an int. The rewrite changes await d[k] (which awaits the async result) to await v (which tries to await an int), causing a TypeError.
Explanation Nemotron 3 Super unverified
The original code awaits `d[k]`, which invokes `__getitem__` returning `get_val(k)`—a coroutine that yields the integer value of `k`. After rewriting to `await v`, it attempts to await the loop variable `v`, which is the actual dictionary value (an integer), not a coroutine. Since integers are not awaitable, this raises a TypeError, changing behavior from successful execution to failure.
Reproduce
- file
prog.py(the before program)- minimized program
- r1-p007.py
- evidence sheet
- r1-p007.md
- regression fixture
- r1-p007.py the minimized program with a header stating the observed change, for the tool's test suite
python3 prog.py ruff check --preview --isolated --select PLR1733 --fix prog.py python3 prog.py
Upstream search GitHub issues Tavily Nemotron 3 Super + Ultra
PLR1733 fix · PLR1733 dict items loop · await expression optimization · ruff autofix await variable
- related astral-sh/ruff/issues/25182 same rule PLR1733 but different construct (else-clause dictionary access vs for-loop items iteration)
- related astral-sh/ruff/issues/29422 same rule PLR1733 mentioned among other fix bugs but no detail on this construct
- related astral-sh/ruff/issues/25150 same rule PLR1733 false positive but different construct (else-clause vs for-loop items iteration)
Details
- program
- Async Def/Await Ordering
- hazard
- In async context, replacing d[k] with v alters await timing if d[k] is awaitable.
- oracle
exit 0 → 1 stderr before: (none) stderr after: TypeError: object int can't be used in 'await' expression- run
- 2026-10-17T21-02-04-500Z-1p30-ruff-PLR1733
generated program (17 lines) and the fix's diff
--- orig.py 2026-10-17 17:02:19.745168460 -0400 +++ fixed.py 2026-10-17 17:02:20.064172249 -0400 @@ -9,7 +9,7 @@ trace = [] for k, v in d.items(): trace.append('before') - x = await d[k] # triggers PLR1733: would become await v — but v is int, not awaitable + x = await v # triggers PLR1733: would become await v — but v is int, not awaitable trace.append(('after', x)) return trace import asyncio
rule documentation given to the models
# unnecessary-dict-index-lookup (PLR1733)
Derived from the **Pylint** linter.
Fix is always available.
## What it does
Checks for key-based dict accesses during `.items()` iterations.
## Why is this bad?
When iterating over a dict via `.items()`, the current value is already
available alongside its key. Using the key to look up the value is
unnecessary.
## Example
```python
FRUITS = {"apple": 1, "orange": 10, "berry": 22}
for fruit_name, fruit_count in FRUITS.items():
print(FRUITS[fruit_name])
```
Use instead:
```python
FRUITS = {"apple": 1, "orange": 10, "berry": 22}
for fruit_name, fruit_count in FRUITS.items():
print(fruit_count)
```