[Python-3000] PEP for Metaclasses in Python 3000

Josiah Carlson jcarlson at uci.edu
Wed Mar 14 18:51:34 CET 2007


Jack Diederich <jackdied at jackdied.com> wrote:
[snip]
> I don't understand the keyword args other than 'metaclass.'
> If class D inherits from class C does it also get passed the 'Implements'
> keyword?  If it does the same effect could be acheived by making a metaclass
> maker function and just using the metaclass keyword.

The keyword arguments to the class ( implements=(I1,I2) ) get passed as
as the **kwargs in meta.__prepare__ (..., **kwargs), as well as the
**kwargs in meta.__new__(..., **kwargs) (though the metaclass= keyword
is removed when calling meta.__new__ ).


>   class C(metaclass=Implements(I1, I2)):
>     ...
> 
> If D doesn't get the 'Implements' keyword then the one-off behavior
> would be easier to put in a class decorator than a metaclass.
> Keywords also strike me as hard to stack.  If a class has two keywords
> defining unrelated behaviors the metaclass would have to be a library-like
> thing that understood both of them.  Mixing metaclasses from two seperate
> metaclass libraries would be hard - no harder than it currently is but
> keywords will invite more use.

As you say, stacking metaclasses is already hard and this would make
them no more difficult.  Combining metaclasses is not a stated purpose
of this particular PEP (at least according to my reading), so I don't
see as how that is in any way a strike against it.


[snip]
> is preferable to this
> 
>   @seal
>   @implements(I1, I2)
>   class C():
>     ...

It's pre-creation vs. post-creation.  As defined, decorators are applied
after the class creation, whereas meta.__prepare__ and meta.__new__
occur before.  Note that one of the driving use-cases for
meta.__prepare__, which is called prior to meta.__new__, is to offer
ordered dictionary availability for things like...

    class mystruct(structbase):
        field1 = int4
        field2 = uint8

Or even...

    class Contact(row):
        _if_not_exists_create = True
        firstname = text
        middlename = text
        lastname = text

The point of offering metaclass=meta is to make it unambiguous what the
metaclass is going to be.  As it stands, a user is free to do any of the
following things.

    class foo(object):
        a = 8
        __metaclass__ = True
        ...
        __metaclass__ = fcn(a, __metaclass__)
        ...
        del __metaclass__
        __metaclass__ = ...
        ...

However, because we need the metaclass to be able to call
metaclass.__prepare__, and to discover the metaclass we would have to
emulate the above, we get to a chicken and egg issue.  So we pull them
out of the body and define it in the class header.


> or even this
> 
>   class C(metaclass=meta_library(sealed=True, implements=(I1, I2))):
>     ...

If one is allowing metaclass=, I see no point in disallowing other
keywords.

 - Josiah



More information about the Python-3000 mailing list