-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add new checker kwarg-superseded-by-positional-arg
and fix a false positive
#8644
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
Add new checker kwarg-superseded-by-positional-arg
and fix a false positive
#8644
Conversation
This comment has been minimized.
This comment has been minimized.
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## main #8644 +/- ##
=======================================
Coverage 95.80% 95.80%
=======================================
Files 172 172
Lines 18301 18301
=======================================
Hits 17534 17534
Misses 767 767
|
tests/functional/a/arguments.py
Outdated
def name2(apple, /, orange, **kwargs): | ||
""" | ||
Positional-only parameter with positional-or-keyword parameter and `**kwargs`. | ||
""" | ||
|
||
|
||
# +1:[redundant-keyword-arg] | ||
name2("Red apple", "Green pear", apple="Green apple", orange="Yellow pear") |
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. Wondering why the oranges are actually pears?
pylint/checkers/typecheck.py
Outdated
# Skip if `keyword` is the same name as a positional-only-parameter | ||
# and a `**kwargs` parameter exists. | ||
if called.args.kwarg and keyword in [ | ||
arg.name for arg in called.args.posonlyargs | ||
]: | ||
continue |
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.
What do you think about a followup PR for 3.0 that emits a new message for this scenario? The code works, but it's pretty suspect (it's more likely a user made a mistake than a user is trying to call a signature that intentionally uses this weird semantics).
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.
In that case, we could leave the linked issue open until we create the "lower severity message" it asks for.
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'm open to that. So for now I can use #Refs instead of #Closes in the fragment and we can separately address adding the lower-severity message in a follow-up.
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 your last comment on the issue made me think you were leaning against the idea of adding a new message and were considering this primarily as a false positive @jacobtylerwalls but happy to leave the issue open anyway until we reach a conclusion.
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 your last comment on the issue made me think you were leaning against the idea of adding a new message and were considering this primarily as a false positive @jacobtylerwalls but happy to leave the issue open anyway until we reach a conclusion.
I was extraordinarily indecisive!
But on second thought, yeah, I think a new message would be good. This is such an edge case, though, it doesn't need to take a high priority.
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.
What would the new message be ? It feels like this should be a warning, the value in kwargs is misleading (is it going to be superseded by the one in args ?
My idea was that it needs to be a lower severity message than redundant-keyword-arg because it's a valid language feature, as opposed to something that will raise TypeError when tried, like the other use cases for redundant-keyword-arg.
However, it's a very, very unlikely language feature, and more likely that someone just wrote a bad call to a function that didn't have the kind of signature shown in the test cases. We could in that case emit a lower-severity info message that's like "hey, are you sure you're actually dealing with a function that does this strange thing?"
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.
Maybe hidden-kwarg
?
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.
redundant-keyword-arg
would describes both the error and the warning well imo. In fact redundant-keyword-arg
describes the warning better, while the error would be better described by multiple-value-for-argument
(Like the text for the type error raised by python in this case: got multiple values for argument 'x'
). Our message name need to be unique and retro-compatible so a possible solution would be to rename redundant-keyword-arg
=> multiple-value-for-argument
, and create redundant-keyword-argument
. That's convoluted and confusing in particular for redundant-keyword-arg
/ redundant-keyword-argument
though. Maybe we can live with redundant-keyword-arg
for both ?
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.
There's good reasons for either of the two approaches now mentioned.
How about we: Revert the code-change in this merge-request (i.e. we emit redundant-keyword-arg
for this case) and merge the rest (the test-cases and the updated test output) which can be useful if we re-visit this to add a new low-severity message?
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 could also name the warning kwargs-hidden-by-positional-args
or hidden-kwarg
or something else (?) like @jacobtylerwalls suggested so there's no confusion between the two. (And we can rename the error anyway, or not)
Moving to 2.17.5 because 2.17.4 is already generated in #8664 |
cf6e1ef
to
82068ab
Compare
This comment has been minimized.
This comment has been minimized.
β¦ith a keyword-only-parameter and ``**kwargs``, is called with a positional argument and a keyword argument where the keyword argument has the same name as the positional-only-parameter. Closes pylint-dev#8558
β¦ a new Pylint message in a separate merge request.
82068ab
to
7afec3e
Compare
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.
Let's discuss the name in the next MR then.
I was just about to update with the new checker :D. |
If we want to be able to backport we need to separate the false positive fix and the new messages I think. But this isn't an urgent fix so let's not backport. |
β¦with a keyword argument which shares a name with a positional-only parameter and the function contains a keyword variadic parameter dictionary. It may be surprising behaviour when the keyword argument is added to the keyword variadic parameter dictionary. Closes pylint-dev#8558
12efb00
redundant-keyword-arg
hidden-kwarg
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.
Moved the contents of this module into tests/functional/a/arguments.py
since Python 3.8 is the minimum version on the main branch now; the original reason for having this module was to let the positional-only argument syntax be used which required python 3.8 minimum as configured in the arguments_positional_only.rc
file.
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.
Shamelessly stealing Jacob's examples :D
This comment has been minimized.
This comment has been minimized.
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.
Logic look good π I made suggestion regarding the message name and content.
pylint/checkers/typecheck.py
Outdated
"The keyword argument %r will be added to the keyword variadic " | ||
"parameter dictionary %r since it has the same name as a positional-only parameter", |
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 keyword argument %r will be added to the keyword variadic " | |
"parameter dictionary %r since it has the same name as a positional-only parameter", | |
"%r will be included in %r since a positional-only parameter with this name already exists", |
I think "keyword variadic parameter" is likely to confuse, and I would favor a shorter message.
pylint/checkers/typecheck.py
Outdated
"W1117": ( | ||
"The keyword argument %r will be added to the keyword variadic " | ||
"parameter dictionary %r since it has the same name as a positional-only parameter", | ||
"hidden-kwarg", |
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.
"hidden-kwarg", | |
"duplicated-arg-hidden-in-kwarg", |
"hidden-kwarg", | |
"duplicate-keyword-argument", |
"hidden-kwarg", | |
"kwarg-hidden-by-posarg", |
I'm trying to come up with something more descriptive. We have https://pylint.pycqa.org/en/latest/user_guide/messages/error/duplicate-argument-name.html that is close.
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 thinking along on this @Pierre-Sassoulas. I found it difficult to think of an accurate name :D.
- I think
hidden
may be a bit confusing as a term. - Regarding
duplicate-keyword-argument
; it suggests to me 2 or more keywords were passed to the function call explicitly which isn't the case - also the message is specifically emitted when positional-only parameters are present, so I thought it would be good to make that explicit.
What do you think of this one:
same-keyword-as-positional-with-kwargs
(inspired by the name of a unittest in cpython)
Bit of a mouthful but I like that it uses the words positional and kwargs which are required for the message to be emitted.
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.
Maybe "kwarg-overridden-by-positional-arg", "kwarg-superseded-by-positional-arg" ?
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'd say the latter suggestion, kwarg-superseded-by-positional-arg
, is more accurate; let's try it out.
β¦arg-superseded-by-positional-arg`. Co-authored-by: Pierre Sassoulas <[email protected]>
Co-authored-by: Pierre Sassoulas <[email protected]>
hidden-kwarg
kwarg-superseded-by-positional-arg
and fix a false positive
Great new check, the doc's bad/good example is especially good. |
π€ According to the primer, this change has no effect on the checked open source code. π€π This comment was generated for commit 332363d |
Type of Changes
Description
Add a new checker
kwarg-superseded-by-positional-arg
to warn when a function is called with a keyword argument which shares a name with a positional-only parameter and the function contains a keyword variadic parameter dictionary. It may be surprising behaviour when the keyword argument is added to the keyword variadic parameter dictionary.This prevents a false positive, in the above scenario, for
redundant-keyword-arg
.Closes #8558