I’m running into a problem using multiple inheritance in Python. In my code, Child class, A, inherits from two Parent classes B and C–both abstract base classes, and each of the Parent classes, B and C, inherit from a common Parent (Grandparent) class D–also an abstract base class.
Instantiating my Child class generates the following error:
TypeError: __main__.D.__init__() got multiple values for keyword argument '_D__arg_0'
This looks to me like an example of the classic diamond problem.
class D
/
class B class C
/
class A
But as I understand it, Python’s Method Resolution Order is supposed to address this problem.
Displaying the MRO for each class:
print(f"MRO: {[x.__name__ for x in A.__mro__]}")
print(f"MRO: {[x.__name__ for x in B.__mro__]}")
print(f"MRO: {[x.__name__ for x in C.__mro__]}")
print(f"MRO: {[x.__name__ for x in D.__mro__]}")
returns exactly what I would expect to see:
MRO: ['A', 'B', 'C', 'D', 'ABC', 'object']
MRO: ['B', 'D', 'ABC', 'object']
MRO: ['C', 'D', 'ABC', 'object']
MRO: ['D', 'ABC', 'object']
This minimal-ish code block reproduces the issue:
from abc import ABC, abstractmethod
class D(ABC,):
def __init__( self, _D__arg_0=None, *args, **kwargs,):
self.arg_0 = _D__arg_0
super(D, self).__init__(*args, **kwargs,)
@abstractmethod
def d_abstract_base_class(self):
pass
class C(D, ABC,):
def __init__( self, _C__arg_0=None, *args, **kwargs,):
self.arg_0 = _C__arg_0
super(C, self).__init__( _D__arg_0=self.arg_0, *args, **kwargs,)
def d_abstract_base_class(self):
return True
@abstractmethod
def c_abstract_base_class(self):
pass
class B(D, ABC,):
def __init__( self, _B__arg_0=None, *args, **kwargs,):
self.arg_0 = _B__arg_0
super(B, self).__init__( _D__arg_0=self.arg_0, *args, **kwargs,)
def d_abstract_base_class(self):
return True
@abstractmethod
def b_abstract_base_class(self):
pass
class A(B,C,):
def __init__( self, _A__arg_0=2, *args, **kwargs,):
self.arg_0 = _A__arg_0
super(A, self).__init__( _B__arg_0=self.arg_0, _C__arg_0=self.arg_0, *args, **kwargs,)
def b_abstract_base_class(self):
return True
def c_abstract_base_class(self):
return True
e = A(_A__arg_0=1,)
print(f"A: ${A}")
Similar questions referencing this error in SO do not appear to be addressing multiple inheritance as a root cause.
The code block above, doesn’t appear to have any of the common issues addressed in related questions including: missing “self” argument in method definitions, positional / keyword argument collisions, out of order positional args, etc.
Am I misunderstanding multiple inheritance in Python? Or some more general Pythonic concept?
If it helps:
Python 3.11.6
Ubuntu 24.04 LTS
Kernel 6.8.0-31-generic