diff options
author | Mark Byrne <31762852+mbyrnepr2@users.noreply.github.com> | 2023-05-16 10:34:47 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-16 10:34:47 +0200 |
commit | d392ea5d8a11049a275207cf18e488bf19a57c69 (patch) | |
tree | af336aaa260297d971ed5fbf16acbb32c9dde8c2 /pylint/checkers/typecheck.py | |
parent | 0a6c21bfab8237431c9f5198068451b243e91448 (diff) | |
download | pylint-git-d392ea5d8a11049a275207cf18e488bf19a57c69.tar.gz |
Add new checker `kwarg-superseded-by-positional-arg` and fix a false positive (#8644)
* Fix a false positive for ``redundant-keyword-arg`` when a function, with 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.
* Add new checker ``kwarg-superseded-by-positional-arg`` which emits a warning message for the above scenario.
Closes #8558
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
Diffstat (limited to 'pylint/checkers/typecheck.py')
-rw-r--r-- | pylint/checkers/typecheck.py | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py index 97a7460a8..767f4ef32 100644 --- a/pylint/checkers/typecheck.py +++ b/pylint/checkers/typecheck.py @@ -399,6 +399,13 @@ MSGS: dict[str, MessageDefinitionTuple] = { "isinstance-second-argument-not-valid-type", "Emitted when the second argument of an isinstance call is not a type.", ), + "W1117": ( + "%r will be included in %r since a positional-only parameter with this name already exists", + "kwarg-superseded-by-positional-arg", + "Emitted when a function is called with a keyword argument that has the " + "same name as a positional-only parameter and the function contains a " + "keyword variadic parameter dict.", + ), } # builtin sequence types in Python 2 and 3. @@ -1548,6 +1555,18 @@ accessed. Python regular expressions are accepted.", # 2. Match the keyword arguments. for keyword in keyword_args: + # 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 + ]: + self.add_message( + "kwarg-superseded-by-positional-arg", + node=node, + args=(keyword, f"**{called.args.kwarg}"), + confidence=HIGH, + ) + continue if keyword in parameter_name_to_index: i = parameter_name_to_index[keyword] if parameters[i][1]: @@ -1564,11 +1583,6 @@ accessed. Python regular expressions are accepted.", node=node, args=(keyword, callable_name), ) - elif ( - keyword in [arg.name for arg in called.args.posonlyargs] - and called.args.kwarg - ): - pass else: parameters[i] = (parameters[i][0], True) elif keyword in kwparams: |