[Python-Dev] Metatype conflict among bases?
Phillip J. Eby
pje@telecommunity.com
Tue, 22 Apr 2003 18:31:24 -0400
David Abrahams <dave@boost-consulting.com> wrote:
>
>Consider:
>
> class A(object):
> class __metaclass__(type):
> pass
>
> class B(A): # TypeError: metatype conflict among bases
> class __metaclass__(type):
> pass
>
>Now that's a weird error message at least! There's only one base (A),
>and I'm telling Python explicitly to use the nested __metaclass__
>instead of A's __metaclass__!
>
>Should I not be surprised that Python won't let me set the metatype
>explicitly?
The problem here is that B.__metaclass__ *must* be the same as, or a
subclass of, A.__metaclass__, or vice versa. It doesn't matter whether the
metaclass is specified implicitly or explicitly, this constraint must be
met. Your code doesn't meet this constraint. Here's a revised example
that does:
class A(object):
class __metaclass__(type):
pass
class B(A):
class __metaclass__(A.__class__):
pass
B.__metaclass__ will now meet the "metaclass inheritance" constraint. See
the "descrintro" document for some more info about this, and the "Putting
Metaclasses To Work" book for even more info about it than you would ever
want to know. :)
Here's a short statement of the constraint, though:
A class X's metaclass (X.__class__) must be identical to, or a subclass of,
the metaclass of *every* class in X.__bases__. That is:
for b in X.__bases__:
assert X.__class__ is b.__class__ or issubclass(X.__class, b.__class__),\
"metatype conflict among bases"