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.
|
|
||
| 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.
Why don't we fix L1142? That if seem to disregard the len(args) == 0 case?
There was a problem hiding this comment.
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.
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.
Because I hadn't thought of it :)
Good point! Seems doable, no?
There was a problem hiding this comment.
Yeah I think an isinstance check and then a qname call on that line should be doable!
There was a problem hiding this comment.
I thought it was impossible to do that because of this: #7622 (comment)
4882213 to
cfe371b
Compare
|
|
||
| inferred = utils.safe_infer(node.func) | ||
| if getattr(inferred, "name", "") == "next": | ||
| if inferred.qname() == "builtins.next": |
There was a problem hiding this comment.
I think we should use an isinstance as well, to make sure the qname method actually exists.
|
|
||
| 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.
This can be reverted.
260f13e to
abfd9ee
Compare
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