[Python-Dev] Submitting PEP 422 (Simple class initialization hook) for pronouncement (original) (raw)

Nick Coghlan ncoghlan at gmail.com
Mon Feb 11 23:29:00 CET 2013


On 12 Feb 2013 07:44, "Guido van Rossum" <guido at python.org> wrote:

On Mon, Feb 11, 2013 at 12:57 PM, PJ Eby <pje at telecommunity.com> wrote:

On Mon, Feb 11, 2013 at 12:44 PM, Guido van Rossum <guido at python.org> wrote: > Hi Nick, > > I think this will make a fine addition to the language. I agree that > it is superior to the alternatives and fulfills a real (if rare) need. > > I only have a few nits/questions/suggestions. > > - With PJE, I think initclass should automatically be a class > method. Actually, I didn't say that as such, because I'm not sure how the heck we'd implement that. ;-) For example, at what point is it converted to a classmethod? Is it going to be a slot method with special C-level handling? Handled by the compiler? What happens if somebody makes it a > The same way that new is automatically a class method. Actually, isn't it automatically a staticmethod? Oh crap. Now that I'm thinking about it, doesn't this have to be a static method, explicitly passing in the class? I mean, otherwise, won't calling super().initclass() invoke it on the base class, rather than the current class? ISTM that EIBTI argues for the new/staticmethod approach, especially if you're returning the class (per below) Let's see what Nick and the implementer say.

I think these are some interesting ideas and it's going to take me a while to digest them and update the PEP :)

A few random thoughts:

  1. I like the idea of a metaprogramming "howto" that provides advice on choosing a suitable level of metaprogramming (with the default choice being "use existing decorators", then escalating through creating custom decorators all the way to creating custom metaclasses). I don't think the PEP needs to be conditional on writing that, but I will at least add PJE's list to the PEP itself.

  2. I see the new method as more analogous to__init__ than to__new__, so the decorate_class idea makes me nervous, as it's closer to a new method. Composition gets a lot harder when your parent class can switch out the object on you.

  3. I'm trying to avoid any custom magic specific to this method, but making it implicitly a static or class method is fairly easy if we so choose - the standard retrieval code during class creation can just bypass the descriptor machinery, and wrap it in staticmethod or classmethod if it isn't already. Given that new is already implicitly static, it may be easier to follow that precedent here rather than trying to explain why an explicit @classmethod is needed in one case but not the other.

4.class is already bound as soon as we have a class object to bind it to, so we can't move it any earlier. However, it's already early enough to let references to it from the new method (including the implied one in zero-arg super) work properly. The black magic that is zero-arg super also deals with PJE's concern about propagating the actual class up the MRO (as it is equivalent to "super(class, first_argument)").

  1. Implicitly walking the MRO bothers me, as it becomes a special case for people to learn. We don't do that for init or new, so I don't think it makes sense to do it here. We can include a recommended structure in the docs, where the first step is calling the parent through. As PJE suggested, a no-op method on type will make that simple and fairly safe (people using a metaclass hierarchy not anchored on type can figure out their own equivalent)

Cheers, Nick.

> - Would it make any sense to require that initclass returns the > new class object (to complete the similarity with class decorators)? It would certainly be quite useful to do so, but in that case, perhaps the method should be named decorateclass? And in that event the standard usage would look like: def decorateclass(cls): cls = super().decorateclass(cls) # do stuff return cls On the other hand, one could just drop the super() requirement and make the usage even simpler by having the class machinery walk the MRO and pass each method the result of invoking the previous one. Then the methods are short and sweet, and super() and class don't come into it. (Though I guess the class machinery could keep setting class to whatever the last-returned class was.) In his first draft, Nick implemented inheritable decorators instead, using a decorators attribute in the class body, or something like that. While that approach had an issue or two of its own, it's possible that just going with a single decorateclass method would work out better. Half-baked idea: Maybe the base class decorateclass would call the class decorators? Or does that not make sense? -- --Guido van Rossum (python.org/~guido) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20130212/d0954576/attachment-0001.html>



More information about the Python-Dev mailing list