[Python-Dev] assigning to new-style-class.__name__

Michael Hudson mwh@python.net
27 Nov 2002 13:11:28 +0000


"Samuele Pedroni" <pedronis@bluewin.ch> writes:

> From: "Michael Hudson" <mwh@python.net>
> 
> 
> 
> > ...  ...   ...
> >  \   /     /
> >   \ /     /
> >    C     D
> >     \   /
> >      \ /
> >       E
> >
> > is it possible to rearrange the __bases__ of C in a way that doesn't
> > create a conflict for C but does for E?  I haven't thought about MRO
> > calculations at all, I'm afraid.
> >
> 
> Yes, if A B (in this order in the mro) are bases of C, and also bases of D and
> you swap them in C (but not D) then E's mro will become subject to an order
> disagreement.

Yes, that's quite obvious, isn't it?

Fortunately:

>>> class A(object):
...  pass
... 
>>> class B(object):
...  pass
... 
>>> class C(A,B):
...  pass
... 
>>> class D(A,B):
...  pass
... 
>>> class E(C, D):
...  pass
... 
>>> C.__bases__   
(<class '__main__.A'>, <class '__main__.B'>)
>>> C.__bases__ = (B, A)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: MRO conflict among bases A, B

The error message isn't the greatest, but things seem to be behaving.

> I haven't looked at the code, but if it checks directly for the consistency of
> E's mro when you change C's bases, then there is no way to move from a
> hierarchy where A precedes B in the mros to one where the two are swapped,
> although the second would be legal if constructed anew piecewise from
> superclasses down to subclasses.

Hmm, I hadn't thought about that.

> So maybe the mros of the subclasses should be computed lazily when needed (e.g.
> onthe  first - after the changes - dispatch), although this may produce
> inconsistences and errors at odd times. 

This makes me feel queasy... currently (at least in my tree -- I need
to write some tests before checkin) the code tries really quite hard
to ensure that the system is always in a consistent state.

Do you (or anyone else) know what CL or Dylan or other dynamic MI
languages do about this?

> Maybe the code is already doing that?

No, and I'm unconvinced it should.  We're allowing something that's
not currently allowed so I feel I have the right to be restrictive.  I
would mention this restriction in the docs, if the were any...

All *I* want assignment to __bases__ for is to swap out one class for
another -- making instances of the old class instances of the new
class, which was possible and making subclasses of the old subclasses
of the new, which wasn't.  In the fairly simple cases I'm envisioning
I'm not going to run into mro conflicts.

Cheers,
M.

-- 
39. Re graphics:  A picture is worth 10K words - but only those
    to describe the picture.  Hardly any sets of 10K words can be
    adequately described with pictures.
  -- Alan Perlis, http://www.cs.yale.edu/homes/perlis-alan/quotes.html