Simple metaclass code failing

LittleGrasshopper seattlehanks at yahoo.com
Mon Jun 1 19:05:30 EDT 2009


On Jun 1, 2:38 am, Piet van Oostrum <p... at cs.uu.nl> wrote:
> >>>>> LittleGrasshopper <seattleha... at yahoo.com> (L) wrote:
> >L> On May 31, 3:59 pm, Carl Banks <pavlovevide... at gmail.com> wrote:
> >>> On May 31, 3:52 pm, LittleGrasshopper <seattleha... at yahoo.com> wrote:
>
> >>> > This is some simple code which I got from Guido's paper on the
> >>> > unification of classes and types, which Arnaud suggested to improve my
> >>> > knowledge of metaclasses:
>
> >>> > class M1(type):
> >>> >     pass
> >>> > class M2(M1):
> >>> >     pass
> >>> > class M3(M2):
> >>> >     pass
> >>> > class C1:
> >>> >     __metaclass__ = M1
> >>> > class C2(C1):
> >>> >     __metaclass__ = M2
> >>> > class C3(C1, C2):
> >>> >     __metaclass__ = M3
>
> >>> > It is failing when processing C3:
> >>> > Traceback (most recent call last):
> >>> >   File "metaerror.py", line 18, in <module>
> >>> >     class C3(C1, C2):
> >>> > TypeError: Error when calling the metaclass bases
> >>> >     Cannot create a consistent method resolution
> >>> > order (MRO) for bases C2, C1
>
> [snip]
>
> >L> I guess the resulting MROs do not satisfy monotonicity, I
> >L> just have to find out how to derive the MRO. I had the notion that it
> >L> was constructed by listing the current class, followed by the MROs of
> >L> each base in order, and then retaining the rightmost instance of each
> >L> class in the MRO list, but I think that might be an
> >L> oversimplification, since in this case that would be:
> >L> (C1, object)
> >L> (C2, C1, object)
> >L> (C3, C2, C1, object)
> >L> And I don't see any issues. But I'll read the paper to figure out what
> >L> the problem is, thanks.
>
> Here is exactly the problem. Merging the two MRO's as you state would
> give C3, C2, C1, object, i.e. C2 before C1.
>
> But your class definition:
>
> class C3(C1, C2):
> says that C1 should be before C2. Conflict!!
> Change it to class C3(C2, C1):
>
> You see it has nothing to do with the metaclasses. The following code
> gives the same error:
>
> class C1(object):
>     pass
> class C2(C1):
>     pass
> class C3(C1, C2):
>     pass
>
> --
> Piet van Oostrum <p... at cs.uu.nl>
> URL:http://pietvanoostrum.com[PGP 8DAE142BE17999C4]
> Private email: p... at vanoostrum.org

Thank you, Piet. You are correct. I actually went through the whole C3
MRO paper from Michele and I realized the issue (local precedence is
not maintained.) And, like you said, the way to fix it is to change
the order of the bases in C3.



More information about the Python-list mailing list