[Python-ideas] A (meta)class algebra

Martin Teichmann lkb.teichmann at gmail.com
Thu Feb 12 11:09:24 CET 2015


Hi list,

metaclasses are a really cool thing in python. Unfortunately, it can
easily get out of hand if you use them too much, once one wants to
inherit from two classes with different metaclasses one has to go
some lengths to get things going again. On one hand this is
unavoidable, as python has no way to guess how two metaclasses
are to be mixed.

Often, however, two metaclasses are designed to work together.
But currently, there is no way to tell the metaclass machinery how
to mix them.

I propose to use the + operator to mix metaclasses. This means
one can simply overwrite __add__ to get a new metaclass mixing
behavior.

Let's look at how metaclass determination works right now. It is done
in typeobject.c. I'm giving here the python equivalent of the function
doing it:

def CalculateMetaclass(metatype, type):
    winner = metatype
    for b in type.__bases__:
        if issubclass(winner, b):
            continue
        elif issubclass(b, winner):
            winner = b
            continue
        else:
            raise TypeError("metaclass conflict")
    return winner

I would replace that with the following function, which uses addition
istead of issubclass:

def CalculateMetaclass(metatype, type):
    winner = metatype
    for b in type.__bases__:
         try:
             winner = winner + b
         except TypeError:
             raise TypeError("metaclass conflict")

Now the default implementation of __add__ in type would be
something like:

def __add__(self, other):
    if issubclass(self, other):
        return self
    return NotImplemented

def __radd__(self, other):
    if issubclass(self, other):
         return self
    return NotImplemented

This gives the default behavior for all metaclasses inheriting type.
They can be easily overwritten to get a different metaclass mixing
behavior.

Greetings

Martin


More information about the Python-ideas mailing list