B909 misses dict.keys() deletion
- Dominant language
- Rust
- Stars
- 49.6k
- Forks
- 2.4k
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 458
Description
### Summary
Using this file:
```python
import typing as t
d: t.Dict[str, int] = {
"a": 1,
"b": 2,
}
for key in d.keys():
del d[key]
```
When I run this command:
```
ruff check --preview --select B909 testruff.py
```
I expect to see a B909 failure, but instead all tests pass. I feel like B909 should be able to catch this, especially because running this code raises a RuntimeError:
```
RuntimeError: dictionary changed size during iteration
```
For what it's worth, `flake8-bugbear` also fails to catch this problem.
Modifying the test code to this causes Ruff to correctly point out the B909 error:
```python
import typing as t
d: t.Dict[str, int] = {
"a": 1,
"b": 2,
}
for key in d:
del d[key]
```
### Version
ruff 0.11.0 (2cd25ef64 2025-03-14)
Contributor guide
Research direction
Start with the B909 rule and reproduce the reported command using the `d.keys()` example, then compare it with the working direct-iteration example. Done means B909 reports the unsafe deletion through `dict.keys()` and tests cover both forms.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100