[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