ruff
ruff copied to clipboard
feat(rules): Implement flake8-bugbear B038 rule
Summary
This PR adds the implementation for the current flake8-bugbear's B038 rule. The B038 rule checks for mutation of loop iterators in the body of a for loop and alerts when found.
Rational: Editing the loop iterator can lead to undesired behavior and is probably a bug in most cases.
Closes #9511.
Note there will be a second iteration of B038 implemented in flake8-bugbear soon, and this PR currently only implements the weakest form of the rule.
I'd be happy to also implement the further improvements to B038 here in ruff :slightly_smiling_face:
See https://github.com/PyCQA/flake8-bugbear/issues/454 for more information on the planned improvements.
Test Plan
Re-using the same test file that I've used for flake8-bugbear, which is included in this PR (look for the B038.py file).
Note: this is my first time using rust (beside rustlings) - I'd be very happy about thorough feedback on what I could've done better :slightly_smiling_face: - Bring it on :grinning:
Awesome, thank you! Excited to review, I'll give it a close read per request :)
Thank you! Left some comments -- feel free to ask questions.
Do you have any suggestion on how to set up the work environment?
In general I think rust's incremental builds are a good idea, but damn they eat up like 10+gb for this project :grimacing:
Awesome, I should be able to review and merge this today!
@charliermarsh please hold off from merging, I still want to remote the to_name_str function and use collect_call_path instead.
Also, in flake8-bugbear there is currently the motion going on to make this an optional rule (disabled per default) as there are some false positives stemming from the python standard library - See the discussion in https://github.com/PyCQA/flake8-bugbear/issues/455
@mimre25 - Roger that!
@mimre25 - I'm going to convert to draft for now just to help manage our review workflow.
I close because it is stale. Please re-open if you plan to follow up on the remaining work.
Sorry for leaving this stale for so long.
I was quite busy and had planned to finish this up in the next couple of weeks.
Alright, I finally got around to finish this.
This is now on parity with flake8-bugbear's B909 (it was renamed).
Main new features in the new commits are described in https://github.com/PyCQA/flake8-bugbear/issues/454. Further, the rule now allows mutations before an unconditional break.
Thanks! I'll take a look.
ruff-ecosystem results
Linter (stable)
ℹ️ ecosystem check encountered linter errors. (no lint changes; 1 project error)
Linter (preview)
ℹ️ ecosystem check detected linter changes. (+5 -0 violations, +0 -0 fixes in 3 projects; 1 project error; 40 projects unchanged)
apache/airflow (+2 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL
+ airflow/models/taskinstance.py:3758:17: B909 Mutation to loop iterable `new_dict` during iteration + airflow/providers/openlineage/sqlparser.py:353:13: B909 Mutation to loop iterable `tables` during iteration
python/mypy (+1 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview
+ mypy/build.py:3200:21: B909 Mutation to loop iterable `new` during iteration
scikit-build/scikit-build (+2 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview
+ tests/pytest_helpers.py:49:13: B909 Mutation to loop iterable `expected_content` during iteration + tests/pytest_helpers.py:92:13: B909 Mutation to loop iterable `expected_content` during iteration
pypa/setuptools (error)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview
Cannot overwrite a value (at line 26, column 2)
Changes by rule (1 rules affected)
| code | total | + violation | - violation | + fix | - fix |
|---|---|---|---|---|---|
| B909 | 5 | 5 | 0 | 0 | 0 |
There are some false positives in here. For example:
for auth_method in authentication_methods_dict:
authentication_methods_dict[auth_method] = True
That's probably the most common?