Possible bug in "metaclass resolution order" ?

Pedro Werneck pedro.werneck at terra.com.br
Fri Sep 16 20:31:09 EDT 2005


Hi

I have a class A, with metaclass M_A, and class B, subclass of A, with
metaclass M_B, subclass of M_A.

A class C, subclass of B must have M_B or a subclass of it as metaclass,
but what if I need to 'disable' the code in M_B on C ? The correct way
to do that seems to be with a M_C metaclass, subclass of M_B,
implementing but not calling parent class methods, or calling 'type'
methods. 

But if I try to do that using other metaclass, not related to M_B, I get a
"TypeError: metaclass conflict exception" as expected.

Python 2.4.1 (#1, Sep 16 2005, 17:47:47) 
[GCC 3.3.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class M_A(type): pass
... 
>>> class A: __metaclass__ = M_A
... 
>>> class M_B(M_A): pass
... 
>>> class B(A): __metaclass__ = M_B
... 
>>> class M_C(type): pass
... 
>>> class C(B): __metaclass__ = M_C
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
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
>>>


The problem is, if I try to do the same thing with 'type' the
interpreter use M_B and I don't get an exception, warning or anything
else. In fact, the __metaclass__ attribute of the C class points to
'type' but the __class__ to M_B!

>>> class C(B): __metaclass__ = type
... 
>>> C.__metaclass__
<type 'type'>
>>> C.__class__
<class '__main__.M_B'>
>>> type(C)
<class '__main__.M_B'>


Since the explicit __metaclass__ attribute has priority over parent
classes, a case like this is an error and should raise an exception like
the metaclass conflict, right ?

Regards,

-- 
Pedro Werneck



More information about the Python-list mailing list