[Python-Dev] Possible rough edges in Python 3 metaclasses (was Re: Language reference updated for metaclasses)

Nick Coghlan ncoghlan at gmail.com
Tue Jun 5 14:24:05 CEST 2012


On Tue, Jun 5, 2012 at 8:25 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> On Tue, Jun 5, 2012 at 7:11 PM, Michael Foord <fuzzyman at voidspace.org.uk> wrote:
>>
>> On 5 Jun 2012, at 08:53, Nick Coghlan wrote:
>>
>>> [snip...]
>>>
>>> Now, one minor annoyance with current class decorators is that they're
>>> *not* inherited. This is sometimes what you want, but sometimes you
>>> would prefer to automatically decorate all subclasses as well.
>>> Currently, that means writing a custom metaclass to automatically
>>> apply the decorators. This has all the problems you have noted with
>>> composability.
>>>
>>> It seems then, that a potentially clean solution may be found by
>>> adding a *dynamic* class decoration hook. As a quick sketch of such a
>>> scheme, add the following step to the class creation process (between
>>> the current class creation process, but before the execution of
>>> lexical decorators):
>>>
>>>    for mro_cls in cls.mro():
>>>        decorators = mro_cls.__dict__.get("__decorators__", ())
>>>        for deco in reversed(decorators):
>>>            cls = deco(cls)
>>>
>>> Would such a dynamic class decoration hook meet your use case? Such a
>>> hook has use cases (specifically involving decorator inheritance) that
>>> *don't* require the use of sys._getframes(), so is far more likely to
>>> achieve the necessary level of consensus.
>>>
>>> As a specific example, the unittest module could use it to provide
>>> test parameterisation without needing a custom metaclass.
>>
>>
>> Heh, you're effectively restoring the old Python 2 metaclass machinery with a slightly-less-esoteric mechanism. That aside I really like it.
>
> Yup, writing a PEP now - I'm mostly interested in the inheritance
> aspects, but providing PJE with a way to get the effect he wants
> without monkeypatching undocumented builtins at runtime and
> effectively forking CPython's runtime behaviour is a useful bonus.
>
> Metaclasses *do* have a problem with composition and lexical
> decorators don't play nicely with inheritance, but a dynamic decorator
> system modelled to some degree on the old __metaclass__ mechanics
> could fill the gap nicely.

PEP written and posted: http://www.python.org/dev/peps/pep-0422/
More toy examples here:
https://bitbucket.org/ncoghlan/misc/src/default/pep422.py

Yes, it means requiring the use of a specific metaclass in 3.2 (either
directly or via inheritance), but monkeypatching an undocumented
builtin is going to pathological lengths just to avoid requiring that
people explicitly interoperate with your particular metaclass
mechanisms.

Regards,
Nick.

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


More information about the Python-Dev mailing list