Is it possible to dynamically create a metaclass for a class with several bases, in Python 3?
<p>In Python 2, with a trick it is possible to create a class with several bases, although the bases have metaclasses that are <em>not</em> subclass of each other.</p>

<p>The trick is that these metaclasses have themselves a metaclass (name it a "metametaclass"), and this metametaclass provides the metaclasses with a call method that dynamically creates a common sub-metaclass of the base metaclasses, if necessary. Eventually, a class results whose metaclass is the new sub-metaclass. Here is the code:</p>

<pre><code>&gt;&gt;&gt; class MetaMeta(type):
...     def __call__(mcls, name, bases, methods):
...         metabases = set(type(X) for X in bases)
...         metabases.add(mcls)
...         if len(metabases) &gt; 1:
...             mcls = type(''.join([X.__name__ for X in metabases]), tuple(metabases), {})
...         return mcls.__new__(mcls, name, bases, methods)
... 
&gt;&gt;&gt; class Meta1(type):
...     __metaclass__ = MetaMeta
... 
&gt;&gt;&gt; class Meta2(type):
...     __metaclass__ = MetaMeta
... 
&gt;&gt;&gt; class C1:
...     __metaclass__ = Meta1
... 
&gt;&gt;&gt; class C2:
...     __metaclass__ = Meta2
... 
&gt;&gt;&gt; type(C1)
&lt;class '__main__.Meta1'&gt;
&gt;&gt;&gt; type(C2)
&lt;class '__main__.Meta2'&gt;
&gt;&gt;&gt; class C3(C1,C2): pass
... 
&gt;&gt;&gt; type(C3)
&lt;class '__main__.Meta1Meta2'&gt;
</code></pre>

<p>This example (of course changing the syntax to <code>class C1(metaclass=Meta1)</code> etc) doesn't work in Python 3.</p>

<p><strong>Question 1:</strong> Do I understand correctly that in Python 2, first <code>C3</code> is constructed, using the metaclass of the first base, and an error would only result if <code>type(C3)</code> were not a common subclass of <code>type(C1)</code> and <code>type(C2)</code>, whereas in Python 3 the error is raised earlier?</p>

<p><strong>Question 2:</strong> (How) Is it possible to make the above example work in Python 3? I did try to use a subclass of <code>abc.ABCMeta</code> as metametaclass, but even though using a custom <code>__subclasscheck__</code> makes <code>issubclass(Meta1, Meta2)</code> return <code>True</code>, the creation of C3 would still result in an error.</p>

<p><strong>Note:</strong> Of course I could make Python 3 happy by statically defining <code>Meta1Meta2</code> and explicitly using it as a metaclass for <code>C3</code>. However, that's not what I want. I want that the common sub-metaclass is created dynamically.</p>

<p>Here's an example that shows some options that you have in python3.x.  Specifically, <code>C3</code> has a metaclass that is created dynamically, but in a lot of ways, explicitly.  <code>C4</code> has a metaclass that is created dynamically within it's metaclass <em>function</em>.  <code>C5</code> is just to demonstrate that it too has the same metaclass properies that <code>C4</code> has.  (We didn't lose anything through inheritance which <em>can</em> happen if you use a function as a metaclass instead of a <code>type</code> ...)</p>

<pre><code>class Meta1(type):
    def foo(cls):
        print(cls)


class Meta2(type):
    def bar(cls):
        print(cls)


class C1(object, metaclass=Meta1):
    """C1"""


class C2(object, metaclass=Meta2):
    """C2"""


class C3(C1, C2, metaclass=type('Meta3', (Meta1, Meta2), {})):
    """C3"""

def meta_mixer(name, bases, dct):
    cls = type('MixedMeta', tuple(type(b) for b in bases), dct)
    return cls(name, bases, dct)


class C4(C1, C2, metaclass=meta_mixer):
    """C4"""


C1.foo()
C2.bar()

C3.foo()
C3.bar()

C4.foo()
C4.bar()

class C5(C4):
    """C5"""

C5.foo()
C5.bar()
</code></pre>

<p>It should be noted that we're playing with fire here (the same way that you're playing with fire in your original example).  There is no guarantee that the metaclasses will play nicely in cooperative multiple inheritance.  If they weren't designed for it, chances are that you'll run into bugs using this at <em>some</em> point.  If they <em>were</em> designed for it, there'd be no reason to be doing this hacky runtime mixing :-).</p>

python metaclass