Bugs item #672115, was opened at 2003-01-21 22:45
Message generated for change (Comment added) made by mwh
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=672115&group_id=5470

Category: Python Interpreter Core
Group: Python 2.3
Status: Open
Resolution: None
Priority: 5
Submitted By: Greg Chapman (glchapman)
Assigned to: Michael Hudson (mwh)
Summary: Assignment to __bases__ of direct object subclasses

Initial Comment:
I'm not entirely sure this is a bug, but I think it is 
surprising:

Python 2.3a1 (#38, Dec 31 2002, 17:53:59) [MSC 
v.1200 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or 
"license" for more 
information.
>>> class A(object):
...     pass
...
>>> class B(object):
...     pass
...
>>> B.__bases__ = (A,)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: __bases__ assignment: 'A' deallocator differs 
from 'object'

It seems like you should be able to change the 
__bases__ of a new-style class (implemented in 
Python) which inherits directly from object to another 
new-style class.  (Will the deallocator issue ever come 
into play if the only types involved are HEAPTYPES and 
object as the ultimate base?)


----------------------------------------------------------------------

>Comment By: Michael Hudson (mwh)
Date: 2005-03-29 13:21

Message:
Logged In: YES 
user_id=6656

Well, my motivation is to better understand what's going on
in typeobject.c.  There are a number of unclear sections (to
put it mildly) and undocumented assumptions and this makes
it hard to work out whether things (like this) are bugs or not.

I'm now fairly confident that the line
"compatible_for_assigment(new_base, self->tp_base)" is
asking the right question (and, thus, your patch is not
really correct, though I doubt it's actually unsafe).  The
spelling is a bit funny though.

This issue in and of itself isn't that high a priority, but
understanding (and documenting that understanding) of
typeobject.c does seem worth working on...

----------------------------------------------------------------------

Comment By: Greg Chapman (glchapman)
Date: 2005-03-28 23:54

Message:
Logged In: YES 
user_id=86307

Still here -- sorry not to reply sooner.  I couldn't
actually remember what my patch was supposed to do, or more
specifically I couldn't remember what it did to check that
this sort of change in __bases__ was safe.  So, anyway, I
finally got around to looking at the patch again, and at
typeobject.c, and I can say that I'm less sure of the
subtleties involved now than I was then.  Anyway, with that
caveat, what you suggest sounds reasonable enough, though I
suppose you'd have to reinsert a dict descriptor if
__bases__ was later changed back to (object,).  (It looks
like the patch would have supported changing __bases__ back
to (object,), though perhaps it shouldn't.)

It seems to me nobody is particularly troubled by this
limitation on assignment to __bases__ (perhaps you know
differently?).  Maybe it's best just to close this as "not a
bug."


----------------------------------------------------------------------

Comment By: Michael Hudson (mwh)
Date: 2005-03-16 13:22

Message:
Logged In: YES 
user_id=6656

Two years on, I think about this again.  Still here? :)

The motivating thought is that:

class A(object): pass
class B(object): pass
B.__bases__ = (A,)

and 

class A(object): pass
class B(A): pass

should be equivalent.

An issue that hadn't occurred to me before is that in the first example both 
A and B have a __dict__ (and __weakref__) descriptor, and in the second 
B doesn't.  Should B's __dict__ descriptor be removed on the 
__bases__ assignment?

----------------------------------------------------------------------

Comment By: Michael Hudson (mwh)
Date: 2003-02-05 14:22

Message:
Logged In: YES 
user_id=6656

Mhmm.  That looks OK to me (after realizing that solid_base
worries about __slots__).

But I don't know how one can be sure :-(

----------------------------------------------------------------------

Comment By: Greg Chapman (glchapman)
Date: 2003-02-05 02:39

Message:
Logged In: YES 
user_id=86307

Well, I wrote a small patch which I'm attaching.  However, I 
can't say that I'm partcularly confident in it.  It works for the 
simple cases I've  been able to think of (and for 
test_descr.py), but looking at typeobject.c, I get the nagging 
feeling that a lot more tests are required to be sure it's OK.  
The problem is, I'm just not sure what they (the tests) are.


----------------------------------------------------------------------

Comment By: Michael Hudson (mwh)
Date: 2003-01-31 18:09

Message:
Logged In: YES 
user_id=6656

Are you interested in working up a patch for this?  Hacking
this kind of stuff requires motivation I'm not sure I can
drum up in time for 2.3...

----------------------------------------------------------------------

Comment By: Greg Chapman (glchapman)
Date: 2003-01-23 17:03

Message:
Logged In: YES 
user_id=86307

Sorry about the parenthetical comment; I think what I was trying 
to say is basically what you have in your last paragraph.

As for use cases, I don't have any myself (I ran into this with 
some test code for a metaclass which "overrides" __bases__).  
However, grepping through the standard library, I note that one 
place where assignment to __bases__ is used is in 
xmlrpclib.SlowParser.  It appears to me that if SlowParser and 
xmllib.XMLParser (neither of which has a base class) were 
converted to new-style classes, the assignment to __bases__ 
would generate this exception.  Of course, that shouldn't be too 
hard to work around if that turns out to be necessary.



----------------------------------------------------------------------

Comment By: Michael Hudson (mwh)
Date: 2003-01-22 11:50

Message:
Logged In: YES 
user_id=6656

I agree this is a bit surprising.  When I was writing this
code I went for the conservative-as-possible approach as I
didn't want to introduce instabilities to Python.

It certainly may be that I've overdone it.  In this case I
probably have; if the tp_dealloc of the class being adjusted
is subtype_dealloc and the tp_dealloc that ultimately gets
invoked is the same we're probably OK.  But I'm not sure and
it's been a while since I thought about this.

It also happens that my motivating use-case for this isn't
troubled by this restriction.

I don't understand your last, parenthetical, comment. 
HEAPTYPES as such doesn't come into it, does it?  

You might be right that we don't need to worry about
tp_dealloc if the ultimate solid_base doesn't change and all
the tp_deallocs on the way there are subtype_dealloc...

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=672115&group_id=5470
_______________________________________________
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to