This rule raises an issue when a special method is defined with an unexpected number of parameters.

== Why is this an issue?

Python allows developers to customize how code is interpreted by defining special methods (also called magic methods). For example, it is possible to override how the multiplication operator (``++a * b++``) will apply to instances of a class by defining in this class the ``++__mul__++`` and ``++__rmul__++`` methods. Whenever a multiplication operation is performed with this class, the Python interpreter will call one of these methods instead of performing the default multiplication.

Each special method expects a specific number of parameters. The Python interpreter will call these methods with those parameters. Calls to a special method will throw a ``++TypeError++`` if it is defined with an incorrect number of parameters.

== How to fix it

Make sure to use the same signature defined in the Python documentation for each special methods.

=== Code examples

==== Noncompliant code example

[source,python,diff-id=1,diff-type=noncompliant]
----
class A:
    def __mul__(self, other, unexpected):  # Noncompliant: too many parameters
        return 42

    def __add__(self):  # Noncompliant: missing one parameter
        return 42

A() * 3  # TypeError: __mul__() missing 1 required positional argument: 'unexpected'
A() + 3  # TypeError: __add__() takes 1 positional argument but 2 were given
----

==== Compliant solution 

[source,python,diff-id=1,diff-type=compliant]
----
class A:
    def __mul__(self, other):
        return 42

    def __add__(self, other):
        return 42

A() * 3
A() + 3
----

== Resources

=== Documentation

* https://docs.python.org/3/reference/datamodel.html#special-method-names[Special method names] - Python special methods 
* https://docs.python.org/3/library/copy.html[Copy module] - Documentation of ``++__copy__++`` and ``++__deepcopy__++``


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

'''
== Implementation Specification
(visible only on this page)

=== Message

* Add XXX parameters. Method YYY should have ZZZ parameters.
* Remove XXX parameters. Method YYY should have ZZZ parameters.


=== Highlighting

Primary: The method signature.

Secondary: The unexpected parameters if there are too many parameters.


'''
== Comments And Links
(visible only on this page)

=== deprecates: S2733

=== on 11 Feb 2020, 17:22:41 Nicolas Harraudeau wrote:
Special methods which are out of scope for this rule: ++__new__++, ++__init__++, ++__call__++

These methods have no maximum number of parameters and require at minimum a "self" parameter. Missing a "self" parameter is already covered by RSPEC-5720.

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