-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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 bug with cell-var-from-loop and kw_defaults #5045
Fix bug with cell-var-from-loop and kw_defaults #5045
Conversation
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.
Thank you for the fix, I have a minor remark about performance but this is a great addition :)
pylint/checkers/utils.py
Outdated
@@ -402,7 +402,10 @@ def is_default_argument( | |||
if not scope: | |||
scope = node.scope() | |||
if isinstance(scope, (nodes.FunctionDef, nodes.Lambda)): | |||
for default_node in scope.args.defaults: | |||
all_defaults = scope.args.defaults + [ | |||
d for d in scope.args.kw_defaults if d is not None |
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.
We're calculating the full list of kwargs here (even if the first element of the list would return True) so we could improve performance by using a generator line 408 in for default_node in all_defaults:
.
pylint/checkers/utils.py
Outdated
@@ -402,7 +402,10 @@ def is_default_argument( | |||
if not scope: | |||
scope = node.scope() | |||
if isinstance(scope, (nodes.FunctionDef, nodes.Lambda)): | |||
for default_node in scope.args.defaults: | |||
all_defaults = scope.args.defaults + [ |
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.
return any(
default_name_node is node
for default_name_node in default_node.nodes_of_class(nodes.Name)
for default_node in scope.args.defaults + d for d in scope.args.kw_defaults if d is not None
)
Maybe something like this would work ? I'm a little rusty with the imbricated for loop.
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.
Nice catch, yeah I was being lazy before. You can't directly concatenate a list and a generator, but I used itertools.chain
to the same effect.
@Pierre-Sassoulas the "Process test coverage" CI test failed, but I don't think that's because of my changes? |
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.
Great ! Don't worry about the coverage, coveralls has been down for a few days we can't do anything about it :)
for default_name_node in default_node.nodes_of_class(nodes.Name): | ||
if default_name_node is node: | ||
return True | ||
all_defaults = itertools.chain( |
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.
π
Type of Changes
Description
The fix in #4827 made use of
pylint.checkers.utils
'sis_default_argument
function, which currently doesn't handle default values for keyword-only parameters:https://github.com/PyCQA/pylint/blob/314cb9ffd369b5ab99688c885eb537c901e861eb/pylint/checkers/utils.py#L396-L409
Default values for keyword-only parameters are stored in a separate
args.kw_defaults
attribute.This led to #5012. I fixed this by modifying the function to check
kw_defaults
as well. Note that since keyword-only parameters can have no default argument, we need to filter outNone
values from this attribute to keep only the astroid nodes representing the actual defaults.Closes #5012.