[Python-ideas] A way out of Meta-hell (was: A (meta)class algebra)

Martin Teichmann lkb.teichmann at gmail.com
Wed Feb 18 09:50:43 CET 2015


> Zope already implements __classinit__ via a metaclass, so I'm not clear on
> how this addition would help with a backport of the __init_class__ spelling
> to Python 2.

Well, there is just a small issue in the zope implementation. They don't
support super(). So you cannot write:

    from ExtensionClass import Base
    class Spam(Base):
        def __class_init__(self):
            super().__class_init__(self)  # this line raises RuntimeError
            # do something here

The precise error is: RuntimeError: super(): empty __class__ cell

My pure python implementation with __init_subclass__ support
super() without problems.

The problem is that at the point they call __class_init__ (at the end
of ExtensionClass.__new__) the __class__ in the methods is not
initialized yet. Interestingly, it also doesn't help to move that call
into __init__, which is still a mystery to me, I was under the
assumtion that at the point of __init__ the class should be fully
initialized. Interestingly, type manages to set the __class__ of the
methods AFTER __init__ has finished. How it manages to do so
I don't know, but probably that's special-cased in C.

> I agree a clean idiom for detecting whether you're in the base class or not
> might be useful, but even without specific support in the PEP you'll at
> least be able to do that either by inspecting the MRO, or else by assuming
> that the class name not being bound yet means you're still in the process of
> creating it.

That sounds very complicated to me. Could you please give me an
example how I am supposed to do that?

Greetings

Martin


More information about the Python-ideas mailing list