-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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 astroid error for custom next
method
#7622
Conversation
6de523d
to
50a11a1
Compare
Pull Request Test Coverage Report for Build 3377462790
π - Coveralls |
This comment has been minimized.
This comment has been minimized.
bc28896
to
4882213
Compare
This comment has been minimized.
This comment has been minimized.
@@ -1130,8 +1130,8 @@ def _looks_like_infinite_iterator(param: nodes.NodeNG) -> bool: | |||
return inferred.qname() in KNOWN_INFINITE_ITERATORS | |||
return False | |||
|
|||
if isinstance(node.func, nodes.Attribute): | |||
# A next() method, which is now what we want. | |||
if isinstance(node.func, nodes.Attribute) or not node.args: |
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.
Why don't we fix L1142? That if seem to disregard the len(args) == 0
case?
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.
The way the code is written is pretty subtle.. let me reproduce and explain:
has_sentinel_value = len(node.args) > 1
if (
isinstance(frame, nodes.FunctionDef)
and frame.is_generator()
and not has_sentinel_value
and not utils.node_ignores_exception(node, StopIteration)
and not _looks_like_infinite_iterator(node.args[0])
):
has_sentinel_value
would be true if there are 2+ args, and False if there are 0 or 1 args. In our specific case of args 0, because this check and not has_sentinel_value
is True, then we continue on to check the other two checks of the if statement and hit and not _looks_like_infinite_iterator(node.args[0])
, which will fail because we just said args is len 0.
Adding or not node.args:
higher up just short circuits everything cleanly.
If you have nicer code that would perform the same thing, do let me know.
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.
Okay, but this changes still doesn't really fix the issue that is described. It just prevents the issue from happening by checking for another heuristic.
Why don't we actually check the qname
of inferred
to be builtins.next
? That seems much more robust?
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.
Because I hadn't thought of it :)
Good point! Seems doable, no?
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.
Yeah I think an isinstance
check and then a qname
call on that line should be doable!
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.
I thought it was impossible to do that because of this: #7622 (comment)
4882213
to
cfe371b
Compare
return | ||
|
||
inferred = utils.safe_infer(node.func) | ||
if getattr(inferred, "name", "") == "next": | ||
if inferred.qname() == "builtins.next": |
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.
I think we should use an isinstance
as well, to make sure the qname
method actually exists.
@@ -1131,11 +1131,11 @@ def _looks_like_infinite_iterator(param: nodes.NodeNG) -> bool: | |||
return False | |||
|
|||
if isinstance(node.func, nodes.Attribute): | |||
# A next() method, which is now what we want. | |||
# Only want the builtin next method. |
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.
This can be reverted.
260f13e
to
abfd9ee
Compare
π€ Effect of this PR on checked open source code: π€ Effect on pytest:
This comment was generated for commit abfd9ee |
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.
LGTM π
Type of Changes
Description
#7610 provided code that shows an edge case. When someone writes a method called
def next()
:, pylint assumed this func will always have args.Closes #7610