[Python-Dev] super() does not work during class initialization

Martin Teichmann lkb.teichmann at gmail.com
Fri Mar 20 15:03:05 CET 2015


Hi list,

while a class is being initialized in a metaclass, it is not always possible to
call classmethods of the class, as they might use super(), which in turn uses
__class__, which is not initialized yet.

I know that this is a known issue, but well, sometimes it even makes sense
to fix already known issues... so I wrote a patch that moves the initialization
of __class__ into type.__new__, so that one may use super() in a class
once it starts existing. It's issue 23722 on the issue tracker.

To illustrate what the problem is, the following code raises a RuntimeError:

class Meta(type):
    def __init__(self, name, bases, dict):
        super().__init__(name, bases, dict)
        self.f()

class A(metaclass=Meta):
    @classmethod
    def f(self):
        super()

it works fine with my patch applied.

Technically, my patch slightly changes the semantics of python if a metaclass
returns something different in its __new__ than what type.__new__ returns.
But I could not find any documentation of the current behavior, and also the
tests don't test for it, and I consider the current behavior actually buggy.
As an example let me give the following simple Singleton metaclass:

class Singleton(type):
    def __new__(cls, name, bases, dict):
        return super().__new__(cls, name, bases, dict)()

class A(metaclass=Singleton):
    def test(self):
        assert(isinstance(__class__, type))

A.test()

The current python fails the assertion, while with my patch everything is fine,
and I personally think __class__ should always actually refer to the class being
defined, which means at the minimum that it is actually, well, a class.

Greetings

Martin


More information about the Python-Dev mailing list