No, any called calls will do. In your case, the type.__new__() method has a restriction that you violate; this has nothing to do with what you assign __metaclass__ .
The function is called:
def metaclass_function(name, bases, body): return type(name, bases, body)
This simply returns the result of type() (not type.__new__() ), but it is just callable. The class uses the return value. You really could return something:
>>> class Foo(object): ... __metaclass__ = lambda *args: [] ... >>> Foo []
Here, the caller creates an instance of the list, so Foo bound to the list. Not very useful, but __metaclass__ just called to create something and something is used directly.
In your example, the first argument to type.__new__() not a type, but a call that fails. mcs bound to a list , not a (subclass) of type . type.__new__() you can set such restrictions.
Now, since the metaclass is still attached to the class object ( type(ClassObj) returns it), and it is used to allow searching for attributes of the class object (where the attribute is not available in the MRO class), it is usually a good idea to subclass it type , therefore that it gives you the correct implementation of things like __getattribute__ . It is for this reason that type.__new__() makes a restriction on what can be passed as the first argument; this is the first argument that type() attached to the returned class object.
source share