[Python-3000] Metaclasses in Py3K

Steven Bethard steven.bethard at gmail.com
Sat Dec 16 22:39:59 CET 2006

Phillip J. Eby wrote:
> There's mine, where you simply create mcls(name, bases, {}) and then map
> locals operations to get/set/delattr operations on the class.  This
> would presumably be done using a simple mapping proxy, but it would be a
> built-in type rather than the user having to implement their own mapping
> type.

I think this is probably the right way to go.  So a class statement like::

    class <name>(<bases>, metaclass=<metaclass>):

would get translated to::

    cls = <metaclass>(<name>, <bases>)

followed by the execution of <block> where XXX_NAME (x) is changed to
LOAD_FAST (cls) followed by XXX_ATTR (x), e.g. STORE_NAME (x) is
changed to::

    LOAD_FAST     (cls)
    STORE_ATTR     (x)

I didn't see the point of passing in an empty dict as the third
argument to the metaclass.  I think we could just drop that argument
in Python 3.0, and if you wanted to write metaclasses that were
compatible with Python 2.X and 3.0, you'd write them like this::

    class metaclass(type):
        def __init__(cls, name, bases, bodydict=None):
            # only perform operations on cls;
            # make no assumptions about bodydict being there

If people were no longer concerned with 2.X compatibility, they could
just drop the extra bodydict parameter.

It gets a little messier if you need to call the super-metaclass,
since you should only pass on the ``bodydict`` attribute if it's
Python 2.X.  But hopefully that's uncommon enough that we don't have
to mess up the normal Python 3.0 API for it. If someone absolutely has
to do it, and has to have their code work in both 2.X and 3.0, they
could do it like::

    if bodydict is None:
        super(metaclass, cls).__init__(name, bases)
        super(metaclass, cls).__init__(name, bases, bodydict)

> The main issue for me is that I think that its important to distinguish
> between get/set operations that are done at class definition time, and
> get/set operations that are done later, after the class is created.

Why?  Can you explain your use case?  Everything I'd care to do would
treat later get/set operations on the class in the same way.

I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy

More information about the Python-3000 mailing list