Multiple Inheritance With Same Method Names but Different Arguments Creates TypeError
<p>I have a four distinct classes. There is a main base/parent class, two main classes that inherit from this parent class, and another class that inherits from both of these main classes. If I have a method with the same name but a different number of arguments as a parent class, I get a TypeError.</p>

<pre><code># Example

class Parent(object):
    def check(self, arg):
        tmp = {
            'one': False,
            'two': False
        }

        try:
            if 'one' in arg:
                tmp['one'] = True

            if 'two' in arg:
                tmp['two'] = True
        except TypeError:
            pass

        return tmp

class Child(Parent):
    def check(self, arg):
        return Parent.check(self, arg)['one']

    def method(self, arg):
        if self.check(arg):
            print 'One!'

class ChildTwo(Parent):
    def check(self, arg):
        return Parent.check(self, arg)['two']

    def method(self, arg):
        if self.check(arg):
            print 'Two!'

class ChildThree(Child, ChildTwo):
    def check(self, arg, arg2):
        print arg2
        return Child.check(self, arg)

    def method(self, arg):
        if self.check(arg, 'test'):
            print 'One!'

        ChildTwo.method(self, arg)

test = ChildThree()
test = test.method('one and two')
</code></pre>

<blockquote>
  <p>runfile('untitled6.py', wdir='./Documents')<br>
  test<br>
  One!<br>
  Traceback (most recent call last):<br>
   File "&lt; stdin >", line 1, in &lt; module ><br>
   File "C:\Users\py\AppData\Local\Continuum\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 714, in runfile<br>
     execfile(filename, namespace)<br>
   File "C:\Users\py\AppData\Local\Continuum\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 74, in execfile<br>
     exec(compile(scripttext, filename, 'exec'), glob, loc)<br>
   File "untitled6.py", line 49, in <br>
     test = test.method('one and two')<br>
   File "untitled6.py", line 46, in method<br>
     ChildTwo.method(self, arg)<br>
   File "untitled6.py", line 34, in method<br>
     if self.check(arg):  </p>
  
  <p>TypeError: check() takes exactly 3 arguments (2 given)</p>
</blockquote>

<p>However, when I remove the second argument from the 'check' method in 'ChildThree', it seems to work fine:</p>

<pre><code>class ChildThree(Child, ChildTwo):
    def check(self, arg):
        return Child.check(self, arg)

    def method(self, arg):
        if self.check(arg):
            print 'One!'

        ChildTwo.method(self, arg)
</code></pre>

<blockquote>
  <p>runfile('untitled6.py', wdir='./Documents')<br>
  One!<br>
  Two!</p>
</blockquote>

<p>I am fairly new to classes/inheritance, so I am not sure why an extra argument causes a TypeError even though it calls the parent class method with a single argument.</p>

<p>This type of inheritance is called <a href="https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem" rel="nofollow">"The Diamond Problem"</a>. It is a topic for itself, so I'll explain on a simpler case:</p>

<pre><code>class C1(object):
    def check(self, arg):
        return 1

    def method(self, arg):
        return self.check(arg)

class C2(C1):
    def check(self, arg1, arg2):   # this overrides C1.check!
        return x + C1.check(self, arg1)

c2 = C2()
c2.method(55)   # fails
</code></pre>

<p><code>C2.check</code> overrides <code>C1.check</code> on all C2 instances. Therefore, when <code>self.check(arg)</code> is called from <code>method</code>, it calls <code>C2.check</code> for instances of C2. That will fail because <code>C2.check</code> takes two arguments.</p>

<p>How to resolve that? When overriding methods, do not change their signature (number and type of received arguments and type of return value), or you'll get in trouble.</p>

<p><em>[more advanced]</em> You could have more freedom with functions which take <a href="https://docs.python.org/2/faq/programming.html#how-can-i-pass-optional-or-keyword-parameters-from-one-function-to-another" rel="nofollow"><code>*args</code> and <code>**kwargs</code></a>.</p>

<hr>

<p>Besides that, I see that <code>ChildThree.check</code> calls <code>Child.check</code> which calls <code>Parent.check</code>, but noone calls <code>ChildTwo.check</code>. That cannot be right.
You should either call the method on all base classes (and risk calling the Parent implementation twice, which may even be right here), or use <a href="https://docs.python.org/2/library/functions.html#super" rel="nofollow"><code>super()</code></a>.</p>

python class inheritance typeerror