I guess I need to give an example to show what my proposal is about. Imagine a metaclass which registers all classes based on it:
class MetaRegistrar(type): def __init__(self, name, bases, dict): super().__init__(name, bases, dict) Registrar.classlist.append(self)
class Registrar(object, metaclass=MetaRegistrar): classlist = 
now every subclass of Registrar is registered into its classlist. Imagine now you want to register a class which inherits another metaclass. A real world example I stumbled over was using a QObject from PyQt4. Then you have:
class Spam(Registrar, QObject): pass
which gives you a nice error message. Sure, you can now define a new metaclass:
class MetaQRegistrar(MetaRegistrar, type(QObject)): pass
but then you always have to write something like
class Spam(Registrar, QObject, metaclass=MetaQRegistrar): pass
everyone who uses Registrar needs to know the details of how those classes can be combined. With my addition, one could simply add a method to MetaRegistrar:
def __add__(self, other): class Combination(self, other): pass return Combination
which mixes MetaRegistrar into whatever comes. Sure, this is a very simplified example, one would cache the created classes, and maybe one wants to register classes that can be mixed.
So, I hope this helps to illustrate my idea, now I'm answering specific questions raised:
Why the + operator? This doesn't seem to have anything to do with addition, or concatentation.
well, technically I'm fine with any method name, one of the binary operators just has the advantage that all the details with when __add__ as opposed to __radd__ is called are all sorted out already. But maybe the | operator is a better choice, as mixing classes is more like a union of two sets.
Your default implementation of __add__ shows that this has nothing to do with anything remotely like the standard use of plus:
That's actually not true. My methods combine classes, and if one is already a subclass of the other, they are already mixed, so yes, it is like a standard union of sets (I start to like the idea of |)
Just overriding __add__ (or whatever method used) doesn't solve the problem. You still have to actually make the metaclasses compatible, so that it is meaningful to mix the metaclasses.
Well, it does solve the problem. Before it was not at all possible to programmatically make metaclasses compatible, you had to write it down explicitly, each time of use.
They can be easily overwritten to get a different metaclass mixing behavior.
I question how easy that would be. If I have understood your proposal for metaclass __add__, mc1 + mc2 would have to return a new metaclass, mc3, which somehow combines behaviour from the two arguments. Even with cooperative metaclasses designed to work together, that sounds to me like it would be painful.
well, to give an example:
class MetaClassMixin(type): def __add__(self, other): class ret(self, other): pass return ret
just mixes your class into the other class.