Possible bug in "metaclass resolution order" ?

Pedro Werneck pedro.werneck at terra.com.br
Sun Sep 18 15:13:26 EDT 2005


On 18 Sep 2005 10:33:11 -0700
"Simon Percivall" <percivall at gmail.com> wrote:

> Isn't that exactly what you are doing?

Yes, and that example has the same inconsistency. 

>>> class X(type): pass
... 
>>> class D2(C3, C2): __metaclass__ = X
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: Error when calling the metaclass bases

For class D2, the explicit metaclass X is not a subclass of the base
metaclasses, just like M1 with D in the example, but with X you get a
metaclass conflict error, and with M1 doesn't. Choosing M3 satisfies the
constraint, but why it is choosen when you use M1 but not with X ?

That's exactly my point. If I wanted M3 or M2, I would be using an
explicit dict['__metaclass__'] = M3 or M2. Since I am trying to do it
with M1, which does not satisfy the constraint, it is an error, and
according to Python design concepts it was supposed to raise the same
exception. 

I don't know if it was a deliberate decision to go silently for the base
class metaclass if the explicit metaclass does not satisfy the
constraint but is a base class of any of the base classes metaclass, but
if it was, the same should happen when the explicit metaclass has no
relation to the base classes metaclass, which seems a very strange
design decision, and not only from Python "explicity and simplicity"
standpoint.

If this is really not an error, just a documentation issue like Mr.
Simionato argues, the first rule for determining M a few lines above
your quote is much more complex and should be changed from:

* if dict['__metaclass__'] exists, it is used.

to something more like:

* if dict['__metaclass__'] exists and is equal to, or a subclass of,
each of the metaclasses of the bases, it is used; if it exists and is a
base class of any of the metaclasses of the bases, the first base class
metaclass is used. If it exists and doesn't satisfies any of these
constraints, TypeError is raised.

If I am right and this is a bug, althought I am not very familiar with
Python internals my speculations on what may be wrong are on the bug
report I filled yesterday. If it's not a bug and this was the intended
behaviour, I think it's not consistent with Python design concepts,
especially "errors should never pass silently" and "explicit is better
than implicit". If it's just a documentation issue, the first rule in
search order is much more complex than documented. If I am completely
wrong in all of this, maybe it's better stop wasting our time. :)


Thank you

-- 
Pedro Werneck

http://sourceforge.net/tracker/index.php?func=detail&aid=1294232&group_id=5470&atid=105470



More information about the Python-list mailing list