-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Extending redefined-outer-name check to cover the case of loop variables #8663
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
Extending redefined-outer-name check to cover the case of loop variables #8663
Conversation
3a5dc28
to
a1ce31f
Compare
There is a case that I have trouble to handle / ignore : #--- Notable cases where redefined-outer-name should NOT be raised:
# When a similarly named loop variable is assigned in another loop:
for n in range(10):
n += 1
for n in range(10):
n += 1 Would you have suggestions on how to NOT raise |
Don't bother answering, I found a solution 😊 Now this is the case I'm wondering about: for value in range(10):
pass
value = 42 The current version of the checker will raise a
(edit: I'm working on a potential solution...) |
It seems like it's more of a redefined-inner-name (or predefined-outer-name) in this case 😄 Potentially problematic but does not feel like the same issue. |
I think this PR is ready for review! 😊 |
The
Related code (line 3395 in the number comparison): for node in assign.node_ancestors():
if node is for_node.parent:
return assign.lineno > for_node.lineno
return False |
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## main #8663 +/- ##
==========================================
- Coverage 95.76% 95.76% -0.01%
==========================================
Files 173 173
Lines 18616 18663 +47
==========================================
+ Hits 17827 17872 +45
- Misses 789 791 +2
|
astroid is not officially typed so |
It look like I already linked to this mypy issue , one year and one day ago. Guess I never learn. |
Interesting. What do you recommend in that case? Adding |
Yeah, |
OK, done |
For reference, with this change Pylint now raises several extra issues on its own code:
I can do the job of fixing all those warnings, Basically, I don't want to spend a few more hours on this PR to then discover that it is not really welcome, |
Yes, it seems like a risk. I think we need the pylint check to be green in order to see the primer result, could you add a disable for redefined-outer-name in our pylintrc so the pylint test is green and we can see the result of the primer on more packages please ? |
Sure, done |
Hi |
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
2a961c2
to
30e74e2
Compare
We now need to use repr_name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your patience with the review. I pushed some temporary changes that should get the primer to finish. We're generating so many messages (in general, but also with this PR in particular) that the job could never finish. Obviously this is a symptom of needing to parallelize our testing tool, but it's also a symptom that a lot of messages will be emitted.
I'll circle back when the primer tool posts its comment. In the meantime, found one bug ⬇️
for target in targets: | ||
if isinstance(target, nodes.Starred): | ||
target = target.value | ||
for ref in node.scope().locals.get(target.name, []): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
name
might not exist. See test case:
class A:
def go(self):
for self.current in range(5):
pass
Gives:
File "/Users/.../pylint/pylint/checkers/variables.py", line 1306, in visit_for
for ref in node.scope().locals.get(target.name, []):
^^^^^^^^^^^
AttributeError: 'AssignAttr' object has no attribute 'name'
You could use repr_name()
(new in astroid 3.0 alpha, so you'll want to rebase on pylint-dev@upgrade-astroid) EDIT: my pushes did that for you! (but you can remove the bleeding-edge commit)
If there's so much messages that it's crashing the primer we probably can't just extend an existing message, we'd need a new one (if we even want to add the message, because if a construct is used extensively in popular project it's probably not a code smell ?). There's a lot of violations in pylint's as we saw previously. |
I can just stop fiddling with the primer and run it manually. Here are the five results from linting astroid:
1 diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py
index 55fce29d3..ca73a5182 100644
--- a/pylint/checkers/variables.py
+++ b/pylint/checkers/variables.py
@@ -1306,6 +1306,8 @@ class VariablesChecker(BaseChecker):
for ref in node.scope().locals.get(target.name, []):
if ref == target:
continue
+ if astroid.nodes.node_classes.are_exclusive(ref, target): # with a better import...
+ continue
if isinstance(ref.parent, nodes.Arguments):
continue # ignoring case covered by redefined-argument-from-local
if self._dummy_rgx and self._dummy_rgx.match(target.name): 2-5 It's possible that would get the number of new messages down to an acceptable level, but I can't guarantee it until seeing the results (sorry!) |
This PR needs take over because because it has been open 8 weeks with no activity. |
This PR needs take over because because it has been open 8 weeks with no activity. |
Hi @Lucas-C 👋 |
Feel free to reopen if you return to this 👍 |
Type of Changes
Description
Extend the rule
redefined-outer-name
to cover the case of loop variables shadowing previously defined variables.Closes #8646