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

Nick Coghlan ncoghlan at gmail.com
Sat Feb 21 14:56:11 CET 2015


On 21 February 2015 at 23:45, Nick Coghlan <ncoghlan at gmail.com> wrote:
> 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.

*sigh* I'm already seeing a definite problem with remembering whether
its init_class vs class_init, especially since the older Zope version
uses the latter name :P

Cheers,
Nick.

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


More information about the Python-ideas mailing list