[Python-3000] PEP for Metaclasses in Python 3000 (original) (raw)

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=metalibrary(sealed=True, implements=(I1, I2))): ...

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



More information about the Python-3000 mailing list