Take the 2-minute tour ×

Here is a python session.

>>> class Z(type):
    def __new__(cls, name, bases, attrs):
        print cls
        print name
        return type(name, bases, attrs)
>>> class Y(object):
    __metaclass__ = Z
<class '__main__.Z'>
>>> class X(Y):
...     pass
>>> class W(Y):
...     __metaclass__ = Z
<class '__main__.Z'>

After I define class X I expect Z._new__ to be called for it, and to print the two line, which is not happening, (as metaclass are inherited?)

share|improve this question

1 Answer 1

up vote 11 down vote accepted

The problem is that the cls argument (which is the metaclass object) is not passed on when you call type, therefore the class object Y that is created and returned does not have any reference to the metaclass Z.

If you replace the last line in __new__ with

return super(Z, cls).__new__(cls, name, bases, attrs)

then it works. Note that even though cls is used in super we still have to provide cls as an argument as well, since super here returns an unbound method (see here for more).

As an alternative to using super one could use:

 return type.__new__(cls, name, bases, attrs)

The important thing is that we give cls (our metaclass object Z) to the classmethod __new__. The shorter form type(name, bases, attrs) fills in type itself for the cls argument, which is of course wrong. This error is similar to calling an instance method with the wrong self argument.

I prefer using super, since this is better style.

share|improve this answer
Ah, ok, that work. But shouldnt return super(Z, cls).__new__ be equivalent to type.__class__.new whis is equivalent to type.__new__ which should be same as creating a new class via type? –  agiliq Nov 21 '09 at 6:17
It is actually not the same, I now address this in my answer. Super does call the type.__new__ method, but we can then use the correct cls argument, which is not possible if we just call type directly. –  nikow Nov 21 '09 at 9:24

Your Answer


