122 lines
3.2 KiB
Plaintext
122 lines
3.2 KiB
Plaintext
== Why is this an issue?
|
||
|
||
Functions, methods, or lambdas with a long parameter list are difficult to use, as maintainers must figure out the role of each parameter and keep track of their position.
|
||
|
||
[source,python]
|
||
----
|
||
def set_coordinates(x1, y1, z1, x2, y2, z2): # Noncompliant
|
||
# ...
|
||
----
|
||
|
||
The solution can be to:
|
||
|
||
* Split the function, method, or lambda into smaller ones
|
||
|
||
[source,python]
|
||
----
|
||
# Each function does a part of what the original set_coordinates function was doing, so confusion risks are lower
|
||
def set_origin(x, y, z):
|
||
# ...
|
||
|
||
def set_size(width, height, depth):
|
||
# ...
|
||
----
|
||
|
||
* Find a better data structure for the parameters that group data in a way that makes sense for the specific application domain
|
||
|
||
[source,python]
|
||
----
|
||
@dataclass
|
||
class Point: # In geometry, Point is a logical structure to group data
|
||
x: int
|
||
y: int
|
||
z: int
|
||
|
||
def set_coordinates(p1: Point, p2: Point):
|
||
# ...
|
||
----
|
||
|
||
This rule raises an issue when a function, a method, or a lambda has more parameters than the provided threshold.
|
||
|
||
=== Exceptions
|
||
|
||
The first argument of non-static methods, i.e., `self` or `cls`, is not counted as it is mandatory and passed automatically.
|
||
|
||
ifdef::env-github,rspecator-view[]
|
||
|
||
'''
|
||
== Implementation Specification
|
||
(visible only on this page)
|
||
|
||
include::../message.adoc[]
|
||
|
||
=== Parameters
|
||
|
||
.max
|
||
****
|
||
|
||
----
|
||
13
|
||
----
|
||
|
||
Maximum authorized number of parameters
|
||
****
|
||
|
||
|
||
'''
|
||
== Comments And Links
|
||
(visible only on this page)
|
||
|
||
=== on 15 May 2019, 12:21:20 Marcel Vingerling wrote:
|
||
In my opinion this rule should ignore mandatory named arguments that have been separated in the function definition by a {color:#FF0000}``++*++``{color} in the argument list.
|
||
|
||
|
||
|
||
=== Noncompliant code example
|
||
|
||
With a maximum number of 4 parameters:
|
||
|
||
[source,python]
|
||
----
|
||
def do_something(param1, param2, param3, param4, param5='default value'):
|
||
...
|
||
----
|
||
{color:#172b4d}This is non-compliant because the function can still be called like this:{color}
|
||
|
||
[source,python]
|
||
----
|
||
do_something(1, 2, 3, 4, 5){code}
|
||
h2. Compliant Solution
|
||
----
|
||
def do_something(param1, param2, param3, param4, *, param5='default value'):
|
||
|
||
...
|
||
|
||
[source,python]
|
||
----
|
||
In this case the {{*}} marker in the function definition dictates that the param5 parameter should always be passed as a named argument. Therefore the maximum number of positional parameters for this function is 4 and should be compliant as named parameters self document the method call and cause less brain-overload.
|
||
This should be compliant because the function can only be called like this:
|
||
----
|
||
do_something(1, 2, 3, 4, param5=5){code}
|
||
|
||
|
||
|
||
|
||
This could either be implemented in this rule or added as an additional rule, then the maximum total number of parameters can also still be validated. Maybe it makes sense to also limit the maximum number of mandatory named arguments using a rule configuration setting.
|
||
|
||
|
||
|
||
|
||
=== on 9 Mar 2020, 13:55:53 Nicolas Harraudeau wrote:
|
||
Hi [~sjaak],
|
||
|
||
|
||
Thank you for your suggestion, and sorry for the late reply. Could you post it on https://community.sonarsource.com/c/bug/fp/7[the community forum] please? This will enable other people to contribute to this discussion more easily.
|
||
|
||
|
||
Thanks
|
||
|
||
include::../comments-and-links.adoc[]
|
||
|
||
endif::env-github,rspecator-view[]
|