Search code examples
pythonnew-operatormultiple-inheritance

How do I override `__new__` with multiple inheritance?


How can I write a default __new__ with some small changes like this:

class A:
    def __new__(cls, *args, **kwargs):
        retval = super().__new__(cls, *args, **kwargs)
        retval.tree_parent = None
        return retval

class B(A):
    def __init__(self, x):
        self.x = x

b = B(1)

Because of other classes in the polymorphic chain, I get errors for arguments passed up that are not in this class's control:

TypeError: object() takes no parameters

Solution

  • A default __new__ can be written like it is in the traitlets module:

    def __new__(cls, *args, **kwargs):
        # This is needed because object.__new__ only accepts
        # the cls argument.
        new_meth = super(HasDescriptors, cls).__new__
        if new_meth is object.__new__:
            inst = new_meth(cls)
        else:
            inst = new_meth(cls, *args, **kwargs)
        # Do something with inst.
        return inst