== Why is this an issue?

``++*++`` and ``++**++``, conventionally known as ``++*args++`` and ``++**kwargs++`` (although any names can be used), can be used in either a function definition or in a function call. In a function definition, they allow a variable number of arguments to be passed. In a function call, they simply obscure the actual values being used in the call.


=== Noncompliant code example

[source,python]
----
my_arg_list = ("yellow", "green", 42)
my_arg_dictionary = {"first" : "Sam", "next": 4, "last": my_obj}
# many lines of code...

function_with_args(*my_arg_list) #Noncompliant
function_with_named_args(**my_arg_dictionary) #Noncompliant
----


=== Compliant solution

[source,python]
----
function_with_args("yellow", "green", 42)
function_with_named_args(first = "Sam", next = 4, last = my_obj)
----



ifdef::env-github,rspecator-view[]
'''
== Comments And Links
(visible only on this page)

=== on 21 Nov 2019, 18:13:10 Nicolas Harraudeau wrote:
Closing this rule as it would raise many False Positives. I see multiple cases where passing ``++**kwargs++`` or ``++*args++`` is perfectly fine:

1/ building an argument list on the fly. Example:

----
options = {}
if condition:
    options[key] = value
myfunction(**options)

# One could argue that this is equivalent:
key = default
if condition:
   key = value
myfunction(key = value)
# But actually this overrides the default value of "key" set in myfunction.
----

2/ It is very common to forward arguments you don't know much about from a caller to another method/function.


----
def myfilter(func):
    def decorator(*args, c=None, **kwargs):
        if c is None or c < 0:
            return None
        return func(c=c, *args, **kwargs)
    return decorator

@myfilter
def myfunction(a, b, *args, c=None):
    return 42
print(myfunction(1,2,c=-1))
----

endif::env-github,rspecator-view[]
