[New-bugs-announce] [issue36827] Overriding __new__ method with itself changes behaviour of the class

Alexey Muranov report at bugs.python.org
Tue May 7 07:42:08 EDT 2019


New submission from Alexey Muranov <alexey.muranov at gmail.com>:

I expect that overriding methods with themselves like in the following example should not change the behaviour of the class:

    class C:
        a = 1

        def __init__(self, b):
            self.b = b

        def f(self, x):
            return x*self.a + self.b + 1

        @classmethod
        def g(cls, y):
            return y*cls.a + 2

        @staticmethod
        def h(z):
            return z + 3

    class D(C):
        def f(self, *args, **kwargs):
            return super(__class__, self).f(*args, **kwargs)

        @classmethod
        def g(cls, *args, **kwargs):
            return super(__class__, cls).g(*args, **kwargs)

        @staticmethod
        def h(*args, **kwargs):
            return super(__class__, __class__).h(*args, **kwargs)

    c = C(7)
    d = D(7)
    assert c.f(42) == d.f(42)
    assert c.g(42) == d.g(42)
    assert c.h(42) == d.h(42)

(Moreover, I expect to be able to extend superclass method this way.)

However, this does not work with `__new__`:

    class C:
        def __init__(self, x):
            self.x = x
            print(x)

    class D(C):
        @staticmethod
        def __new__(*args, **kwargs):
            return super(__class__, __class__).__new__(*args, **kwargs)

    C(7) # fine
    D(7) # TypeError: object.__new__() takes exactly one argument

I think this is not a desirable feature.  I would call it a bug.

By the way, I understand why `object`'s `__init__` can complain about a wrong number of arguments, but I do not see a point in making `object`'s `__new__` complain about it.

Here is my current workaround:

    class T:
        @staticmethod
        def __new__(cls, *_args, **_kwargs):
            return object.__new__(cls)

    class E(C, T):
        @staticmethod
        def __new__(*args, **kwargs):
            return super(__class__, __class__).__new__(*args, **kwargs)

    C(42) # fine
    E(42) # fine

A possibly related issue: #32768 (https://bugs.python.org/issue32768)

----------
components: Interpreter Core
messages: 341705
nosy: alexey-muranov
priority: normal
severity: normal
status: open
title: Overriding __new__ method with itself changes behaviour of the class
type: behavior
versions: Python 3.7, Python 3.8

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue36827>
_______________________________________


More information about the New-bugs-announce mailing list