Why does the class definition's metaclass keyword argument accept a callable?
<h2>Background</h2>

<p>The Python 3 <a href="https://docs.python.org/3.6/reference/datamodel.html#determining-the-appropriate-metaclass">documentation</a> clearly describes how the metaclass of a class is determined:</p>

<blockquote>
  <ul>
  <li>if no bases and no explicit metaclass are given, then type() is used</li>
  <li>if an explicit metaclass is given and it is not an instance of type(), then it is used directly as the metaclass</li>
  <li>if an instance of type() is given as the explicit metaclass, or bases are defined, then the most derived metaclass is used</li>
  </ul>
</blockquote>

<p>Therefore, according to the second rule, it is possible to specify a metaclass using a callable.  E.g.,</p>

<pre><code>class MyMetaclass(type):
    pass

def metaclass_callable(name, bases, namespace):
    print("Called with", name)
    return MyMetaclass(name, bases, namespace)

class MyClass(metaclass=metaclass_callable):
    pass

class MyDerived(MyClass):
    pass

print(type(MyClass), type(MyDerived))
</code></pre>

<h2>Question 1</h2>

<p>Is the metaclass of <code>MyClass</code>: <code>metaclass_callable</code> or <code>MyMetaclass</code>?  The second rule in the documentation says that the provided callable "is used directly as the metaclass".  However, it seems to make more sense to say that the metaclass is <code>MyMetaclass</code> since</p>

<ul>
<li><code>MyClass</code> and <code>MyDerived</code> have type <code>MyMetaclass</code>,</li>
<li><code>metaclass_callable</code> is called once and then appears to be unrecoverable,</li>
<li>derived classes do not use (as far as I can tell) <code>metaclass_callable</code> in any way (they use <code>MyMetaclass</code>).</li>
</ul>

<h2>Question 2</h2>

<p>Is there anything you can do with a callable that you can't do with an instance of <code>type</code>?  What is the purpose of accepting an arbitrary callable?</p>

<p>Concerning question 1, I think the "metaclass" of a class <code>cls</code> should be understood as <code>type(cls)</code>. That way of understanding is compatible with Python's error message in the following example:</p>

<pre><code>&gt;&gt;&gt; class Meta1(type): pass
... 
&gt;&gt;&gt; class Meta2(type): pass
... 
&gt;&gt;&gt; def metafunc(name, bases, methods):
...     if methods.get('version') == 1:
...         return Meta1(name, bases, methods)
...     return Meta2(name, bases, methods)
... 
&gt;&gt;&gt; class C1:
...     __metaclass__ = metafunc
...     version = 1
... 
&gt;&gt;&gt; class C2:
...     __metaclass__ = metafunc
...     version = 2
... 
&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
... 
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
TypeError: Error when calling the metaclass bases
    metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
</code></pre>

<p>I.e., according to the error message, the metaclass of a class is a class, even though the callable used to construct the class can be just anything.</p>

<p>Concerning the second question, indeed with a subclass of type used as a metaclass, you can do the same as with any other callable. In particular, it is possible that it yields something that is not its instance:</p>

<pre><code>&gt;&gt;&gt; class Mockup(type):
...     def __new__(cls, name, bases, methods):
...         return Meta1(name, bases, methods)
... 
&gt;&gt;&gt; class Foo:
...     __metaclass__ = Mockup
... 
&gt;&gt;&gt; type(Foo)
&lt;class '__main__.Meta1'&gt;
&gt;&gt;&gt; isinstance(Foo, Mockup)
False
&gt;&gt;&gt; Foo.__metaclass__
&lt;class '__main__.Mockup'&gt;
</code></pre>

<p>As to why Python gives the freedom of using any callable: The previous example shows that it is actually irrelevant whether the callable is a type or not.</p>

<p>BTW, here is a fun example: It is possible to code metaclasses that, themselves, have a metaclass different from <code>type</code>---let's call it a metametaclass. The metametaclass implements what happens when a metaclass is called. In that way, it is possible to create a class with two bases whose metaclasses are <em>not</em> subclass of each other (compare with Python's error message in the example above!). Indeed, only the metaclass of the resulting class is subclass of the metaclass of the bases, and this metaclass is created on the fly:</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>What is less fun: The preceding example won't work in Python 3. If I understand correctly, Python 2 creates the class and checks whether its metaclass is a subclass of all its bases, whereas Python 3 <em>first</em> checks whether there is one base whose metaclass is superclass of the metaclasses of all other bases, and only <em>then</em> creates the new class. That's a regression, from my point of view. But that shall be the topic of a new question that I am about to post...</p>

<p><strong>Edit</strong>: The new question is <a href="http://stackoverflow.com/questions/40031906/is-it-possible-to-dynamically-create-a-metaclass-for-a-class-with-several-bases">here</a></p>

python class python-3.x metaclass