Skip to content
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

Fix false negative no-member when the code was a manual augmented assignments #7509

Merged
merged 3 commits into from
Sep 23, 2022

Conversation

clavedeluna
Copy link
Contributor

Type of Changes

Type
βœ“ πŸ› Bug fix

Description

Add code to detect no-member when an augmented assign is done "manually", that is, when a user does this

obj.value = 1 + obj.value
instead of
obj.value += 1

If no-member would be raised in the second case, it should also be raised in the first case, which is why this PR is here!

Closes #4562 (altho I can remove this auto-close if we want to keep it open for the pydantic false positive case, though I Personally think it should be a separate issue)

if not attr:
return False

return binop.op == "+" and attr.attrname == node.attrname
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this entire util func is pretty ugly ... all ears for improvements

@coveralls
Copy link

coveralls commented Sep 21, 2022

Pull Request Test Coverage Report for Build 3112831510

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 95.315%

Totals Coverage Status
Change from base Build 3108882423: 0.0%
Covered Lines: 17109
Relevant Lines: 17950

πŸ’› - Coveralls

Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good already, thank you. I made a small review, there's an issue with the pipeline to fix too.

return False

children = [x for x in parent.get_children()]
binops = [x for x in children if isinstance(x, nodes.BinOp)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As children is only used in the second list comprehension, imbricating both list comprehension would be more efficient.

I'm on mobile so I can't check get_children api but I wouldn't be surprised if you can get all the children of a certain type directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a way to get children of a certain type https://pylint.pycqa.org/projects/astroid/en/latest/api/astroid.nodes.html#astroid.nodes.AugAssign.get_children
but will def combine the list comps

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe node_of_classes but I'm not sure it's only the children that are returned. Sorry for suggesting things that I can't test myself right now, I'm on mobile.


children = [x for x in parent.get_children()]
binops = [x for x in children if isinstance(x, nodes.BinOp)]
if not binops:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can avoid doing the following if in some cases like this:

Suggested change
if not binops:
if not binops or binops[0] ! = "+":

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good thinking!

if not attr:
return False

return binop.op == "+" and attr.attrname == node.attrname
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return binop.op == "+" and attr.attrname == node.attrname
return attr.attrname == node.attrname


binop = binops[0]

attr = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
attr = None

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm much more in favor of

var = None
if ...
   var = 1
elif ...
  var = 2

if not var

but hey I"ll take your suggestion

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not consider the case where var is none from the if, I'm not opinionated about this you asked about possible style fix so I tried :)

Comment on lines 1994 to 1995

if not attr:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if not attr:
else:

@DanielNoord
Copy link
Collaborator

@Pierre-Sassoulas I was thinking: does it make sense to make this a code style check? consider-using-augmented-assign. We would get a nice primer result to check for false positives on this util function.

@Pierre-Sassoulas
Copy link
Member

Sounds good !

@DanielNoord
Copy link
Collaborator

@clavedeluna I'll have a look at converting this into a message tomorrow. You can do so as well if you want to? I'd be happy to guide you in the right direction?

@clavedeluna
Copy link
Contributor Author

clavedeluna commented Sep 21, 2022

@clavedeluna I'll have a look at converting this into a message tomorrow. You can do so as well if you want to? I'd be happy to guide you in the right direction?

go right ahead with adding it, I'll look at Pierre's review. I think doing consider-using-augmented-assign should be a separate PR

@clavedeluna
Copy link
Contributor Author

whoops... broke the tests

@clavedeluna
Copy link
Contributor Author

Alright so maybe I'm missing something obvious but how is
pylint/checkers/utils.py:1996: error: Returning Any from function declared to return "bool
an issue for return attr.attrname == node.attrname

is that not always a bool? do I wrap it in bool??

@DanielNoord
Copy link
Collaborator

Alright so maybe I'm missing something obvious but how is pylint/checkers/utils.py:1996: error: Returning Any from function declared to return "bool an issue for return attr.attrname == node.attrname

is that not always a bool? do I wrap it in bool??

This is because astroid is not typed so you're essentially comparing Any with Any. If you add a disable for this specific error with type: ignore we will remove it after astroid does have typing.

@clavedeluna
Copy link
Contributor Author

we will remove it after astroid does have typing.

ah makes sense! I'm getting more and more familiar with the code base so thanks for the tip.

@Pierre-Sassoulas Pierre-Sassoulas added the False Negative πŸ¦‹ No message is emitted but something is wrong with the code label Sep 22, 2022
@Pierre-Sassoulas Pierre-Sassoulas added this to the 2.16.0 milestone Sep 22, 2022
Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you @clavedeluna !

@Pierre-Sassoulas Pierre-Sassoulas changed the title add case to detect manual augomented assign Add necessary handling to detect manual augmented assignments Sep 22, 2022
@DanielNoord
Copy link
Collaborator

I'm working a PR that incorporates these changes to get a primer result. Should be done in 30 minutes or something like that.

@Pierre-Sassoulas
Copy link
Member

I'll let you merge this one @DanielNoord

@DanielNoord
Copy link
Collaborator

See #7514.

I had to change quite a bit. Preferably we merge that PR first and then use the utility introduced there in this PR. The robustness we get from checking the new checker on the primer is a huge benefit compared to the functional tests we can think of ourselves.

@clavedeluna
Copy link
Contributor Author

See #7514.

I had to change quite a bit. Preferably we merge that PR first and then use the utility introduced there in this PR. The robustness we get from checking the new checker on the primer is a huge benefit compared to the functional tests we can think of ourselves.

I will rebase and re-do this PR once that one is merged

Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for inspiring the work on the augmented assignment checker, and thank you for fixing this !

@Pierre-Sassoulas Pierre-Sassoulas changed the title Add necessary handling to detect manual augmented assignments Fix false negative no-member when the code was a manual augmented assignments Sep 23, 2022
@Pierre-Sassoulas Pierre-Sassoulas merged commit ca6648a into pylint-dev:main Sep 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
False Negative πŸ¦‹ No message is emitted but something is wrong with the code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

False negative and false positive 'no-member' errors with +=
4 participants