[Python-Dev] PEP 487 vs 422 (dynamic class decoration) (original) (raw)

Martin Teichmann lkb.teichmann at gmail.com
Fri Apr 3 14:44:18 CEST 2015


When I first wrote PEP 422 I was of the view that "Python 2 allows class definition postprocessing injection, we should allow it in Python 3 as well". I've since changed my view to "Having to declare post-processing of a class definition up front as a decorator, base class or metaclass is a good thing for readability, as otherwise there's nothing obvious when reading a class definition that tells you whether or not postprocessing may happen, so you have to assume its possible for every class definition".

Nick, I couldn't agree more with you, yet I think PJ actually brought up a very interesting point. Post-processing is a very common thing these days, and has been re-written so many times that I think it is about time that something like it should be in the standard library.

I'm less thinking about decorated methods, more about descriptors. They always have the problem that they don't know which attribute they belong to, so every author of a framework that defines descriptors writes a metaclass which goes through all the descriptors and tells them their attribute name.

I propose to have some metaclass in the standard library that does that. I think it would fit nicely in my metaclass module proposed in PEP 487.

It would basically do the following:

class Metaclass(type): def init(self, name, bases, dict): super().init(name, bases, dict) for k, v in dict.items(): if hasattr(v, "post_process"): v.post_process(k, self)

So each descriptor could define a post_process hook that tells it the attribute name and also the class it belongs to. This would for sure also work for decorated methods.

This should mature on PyPI, then introduced into the standard library, and if demand is really that high, maybe even be introduced into type.init. It should be noted that this can also be easily written as a PEP 487 class using subclass_init, I just used the classical metaclass notion as I guess people are more used to that.

This proposal can actually be seen as an extension to the class and super() mechanism of normal methods: methods currently have the priviledge to know which classes they are defined in, while descriptors don't. So we could unify all this by giving functions a post_process method which sets the class in the function body. This is about the same as what happened when functions got a get method to turn them into object methods.

While this all is in the making, PJ could monkey-patch build_class to do the steps described above, until it gets accepted into cpython. So I pose the question to PJ: would such an approach solve the problems you have?

Greetings

Martin



More information about the Python-Dev mailing list