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