From d392ea5d8a11049a275207cf18e488bf19a57c69 Mon Sep 17 00:00:00 2001 From: Mark Byrne <31762852+mbyrnepr2@users.noreply.github.com> Date: Tue, 16 May 2023 10:34:47 +0200 Subject: 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 --- pylint/checkers/typecheck.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'pylint') 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: -- cgit v1.2.1