-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
B909 improvements #454
Comments
Thanks for writing this up. Assign and AnnAssign can be ignored, since they just rebind the name, they do not mutate the container. ( |
A good catch with Regarding the syntax errors: you're right - What do you think about |
We should catch |
Sounds good to me. I'll implement these improvements some time next week 🙂 |
## Summary This PR adds the implementation for the current [flake8-bugbear](https://github.com/PyCQA/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 🙂 See PyCQA/flake8-bugbear#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:
…l-sh#9578) ## Summary This PR adds the implementation for the current [flake8-bugbear](https://github.com/PyCQA/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 astral-sh#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 🙂 See PyCQA/flake8-bugbear#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:
Note Rule B909 originally was B038, but after some discussion, it was decided that we make it optional and it's B909 now (see #456).
I have not updated the content of this issue, so please read "B038" as "B909".
Description
With the introduction of B038 (#445), I initially introduced a bug causing many false positives, which should be fixed with #453.
#453 implements a check for the methods listed in Python Builit-in Mutable Sequence Types documentation, but not the operators.
However, #453 left out some mutations for the sake of getting a fix to the flood of false positives (#451) out asap.
In this issue, I will propose further changes to harder B038, to detect more (hopefully all) mutations to iterables that the python builtins allow.
Assignment Operations
This is a very obvious one that was not implemented yet, and I wonder how I could've overseen it.
This part will cover the following operations:
The implementation will check if any
ast.Assign
andast.AugAssign
have the name or a subscript of the name of the iterable as target.Further, to also check for annotated assignments, the plan is to inspect
ast.AnnAssign
nodes that are not simple (ie havesimple = 0
).simple = 1
are nodes of the formfoo: bar
, whereassimple = 0
have any of the following forms:I'm not sure if all of the above are legal syntax, but the implementation will likely look very similar and thus would cover all those cases out of the box.
Further, everything of the above also applies to object attributes, ie, we'd also cover
foo.bar =
-esque assignments iffoo.bar
is the loop iterable.Container-Specific Operations
#451 already implements a check for 2 container specific operations:
list.sort()
anddict.popitem()
.Further operations are missing:
dict.setdefault
dict.update
set.update
set.intersection_update
set.difference_update
set.symmetric_difference_update
set.add
set.discard
object.__setrattr__
object.__delrattr__
These all can be implemented similarly to the ones in #451 by adding them to the
MUTATING_FUNCTIONS
list of theB038Checker
.The nasty ones
These are functions that are not used often, or just don't fall into the scheme of the ones listed above:
delattr
setattr
These will need special handling in
visit_Call
of theB038Checker
, but shouldn't be too complicated.Discussion
I hope my proposal covers all the mutations that are doable with the python built-ins.
If not please let me know.
One special mention goes to
del x
- this is actually not mutating the iterable itself and only deletes the reference to the iterator.The following snippet runs without problems
However,
def x[y]
does mutatex
.Should this case distinction be made? Currently both would be reported.
I also would like to refactor the code for B038 a bit to just make it far more readable, currently it's a bit messy 😅
Please let me know what you think about the proposed changes and whether I should go ahead and implement them 🙂
The text was updated successfully, but these errors were encountered: