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

Nick Coghlan ncoghlan at gmail.com
Sat Feb 21 14:45:09 CET 2015


On 20 February 2015 at 18:40, Martin Teichmann <lkb.teichmann at gmail.com> wrote:
> Hi,
>
>>>> Yes, populating __class__ happens inside the interpreter only after the
>>>> class is fully constructed, so even though the *class* is fully initialised
>>>> at the end of __init__, a reference hasn't been inserted into the cell yet.
>>>> (The __class__ cell doesn't actually live on the class object - it's created
>>>> implicitly by the interpreter and then referenced from the individual
>>>> methods as a closure variable for each method that looks up "__class__" or
>>>> "super")
>>>>
>>>> Python 2 doesn't provide the implicitly populated __class___ cell at all
>>>> though, so you have to refer to the class object by its name - zero argument
>>>> super is a Python 3 only feature.
>>>
>>> In short: PEP 422 in the current form is not back-portable.
>>> With my modifications it is portable all the way down to python 2.7.
>>>
>>> PEP 422 being back-portable => people will immediately start using it.
>>> PEP 422 not back-portable => it won't be used for several years to come.
>>
>> You haven't really explained why you think it's not backportable.
>> You've suggested a backport may require some workarounds in order to
>> handle cooperative multiple inheritance, but that's not even close to
>> being the same thing as not being able to backported at all.
>
> Well, your explanation up there is actually very good at explaining why
> it isn't back portable: at the time of metaclass.__init__ the __class__ has
> not been initialized yet, so cooperative multiple inheritance will never
> work. This holds even true for the two parameter version of super():
> as the __class__ has not yet been bound to anything, there is no way
> to access it from within __class_init__. You say that some workarounds
> would have to be done to handle cooperative multiple inheritance, yet
> given that there is no way to tamper with __class__ I cannot see how
> such a workaround should look like.
>
> I would love to be proven wrong on the above statements, as I
> actually like PEP 422. But back-portability, in my opinion, is actually
> very important. So, maybe someone out there manages to write a
> nice (or even ugly) backport of PEP 422?

Backportability is at best a nice-to-have when it comes to designing
changes to core semantics, and it certainly doesn't justify additional
design complexity.

That's why its better to focus on making actual *usage* simpler, and
it may be that a __subclass_init__ hook is simpler overall than a
__class_init__. Certainly one point in its favour is that opting in to
running the subclass init on the base class with a decorator would be
relatively easy, while opting out of running __class_init__ is likely
to be a bit tricky.

Regards,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-ideas mailing list