[Python-3000] Metaclasses in Py3K

Steven Bethard steven.bethard at gmail.com
Fri Dec 8 19:48:54 CET 2006


At 08:53 AM 12/8/2006 -0600, Guido van Rossum wrote:
> I've been thinking about this too, and I think it's reasonable to let
> the metaclass provide the dict to be used as locals.
[snip]
> class C(B1, B2, metaclass=Foo):
>    ...

On 12/8/06, Phillip J. Eby <pje at telecommunity.com> wrote:
> I definitely like the idea of the metaclass getting to control the locals()
> of the class suite, but then again it also seems like it would be just as
> easy to say that the class statement creates a class/type object (using the
> normal metaclass rules applied to the bases), and then the suite executes
> with a locals() that does getattr(cls, name) and setattr(cls, name, val)
> for getitem and setitem.

The suggestion in open issues of the `make statement PEP`_ was that,
given a class statement like::

    class C(metaclass=metaclass):
        <body>

something like the following would be executed::

    metadict = metaclass.__metadict__()
    exec <body> in metadict
    C = metaclass('C', (), metadict)

So if you wanted to monitor how attributes were assigned, you'd define
classes like::

    class my_type(type):
        class __metadict__(object):
            def __getitem__(self, name):
                ...
            def __setitem__(self, name, value):
                ...

I know that seems overly complicated, and it seems like it would be
better if you could follow Phillip's suggestion where the metaclass
instance is created first and then ``getattr()`` and ``setattr()`` are
called appropriately.  Then you could just write::

    class my_type(type):
        def __getattr__(self, name):
            ...
        def __setattr__(self, name, value):
            ...

The `make statement PEP`_ didn't propose this approach because it
would have broken existing metaclasses when the signatures of
``__new__`` and ``__init__`` dropped the classdict parameter, e.g.::

    def __new__(meta, name, bases):
        ...
    def __init__(cls, name, bases):
        ...

Personally, I wouldn't object to having to rewrite my metaclasses to
these new APIs, but I'm still not certain how much backwards
incompatibility Python 3000 is willing to accept.

.. _make statement: http://www.python.org/dev/peps/pep-0359/

STeVe
-- 
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