[ python-Bugs-672115 ] Assignment to __bases__ of direct object subclasses

SourceForge.net noreply at sourceforge.net
Tue Mar 29 00:54:45 CEST 2005


Bugs item #672115, was opened at 2003-01-21 13:45
Message generated for change (Comment added) made by glchapman
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: Greg Chapman (glchapman)
Date: 2005-03-28 13: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 04: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 05: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-04 17: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 09: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 08: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 02: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


More information about the Python-bugs-list mailing list