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.
 
> - Would it make any sense to require that __init_class__ *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 __decorate_class__?  And in that event the
standard usage would look like:

    def __decorate_class__(cls):
        cls = super().__decorate_class__(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 __decorate_class__ method would
work out better.

Half-baked idea: Maybe the base class __decorate_class__ would call the class decorators? Or does that not make sense?

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