On Mon, Feb 11, 2013 at 2:29 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:

On 12 Feb 2013 07:44, "Guido van Rossum" <guido@python.org> wrote:
> On Mon, Feb 11, 2013 at 12:57 PM, PJ Eby <pje@telecommunity.com> wrote:
>> On Mon, Feb 11, 2013 at 12:44 PM, Guido van Rossum <guido@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 __init_class__ 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().__init_class__() 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 :)

Heh. :-)

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.

Fair enough.

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.

Also fair enough.

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)").

So where is it not bound when a metaclass runs? I guess in the metaclass's __new__()? Because in the metaclass's __init__() it should exist IIUC.

5. 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)


--Guido van Rossum (python.org/~guido)