[Python-Dev] Assignment to __class__

Guido van Rossum guido@python.org
Fri, 10 Jan 2003 08:00:36 -0500


> Sorry, I was not as clear as I should have been.  Here is what used to work,
> and I hope can be made to work again:
> 
>   class AlgebraicDict(dict):
>     def doReallyComplexThings(self, foo): ...
>     def __add__(self, other): ...
>     def __mul__(self, other): ...
> 
>   unsuspecting_dict = {1:[1,2],2:3}
> 
>   unsuspecting_dict.__class__ = AlgebraicDict
>   > TypeError: __class__ assignment: only for heap types

But in this case, the instance layout of dict and AlgebraicDict is
different anyway (AlgebraicDict has room for the __dict__ to contain
instance variables) so you can't do that.

The layouts could be the same if you add __slots__ = [] to
AlgebraicDict.

But the problem is that even then, AlgebraicDict may be allocated
using a different free list than dict, and changing its __class__ to
dict would free it using the wrong free list.

To work around, create a neutral dict subclass that has the same
layout at AlgebraicDict.

--Guido van Rossum (home page: http://www.python.org/~guido/)