inheritance, multiple inheritance and the weaklist and instance dictionaries
Carl Banks
pavlovevidence at gmail.com
Wed Feb 9 16:58:12 EST 2011
On Feb 9, 1:14 pm, Rouslan Korneychuk <rousl... at msn.com> wrote:
> On 02/09/2011 02:42 PM, Carl Banks wrote:
> > This is the only case I can think of where the
> > layout conflict would be caused by a type setting tp_dictoffset.
>
> No, actually I have code that is roughly equivalent to the following
> pseudocode:
>
> class _internal_class(object):
> __slots__ = ()
>
> class BaseA(_internal_class):
> __slots__ = (some_data,...,__weaklist__,__dict__)
>
> class BaseB(BaseA):
> __slots__ = (some_data,...,__weaklist__,__dict__)
>
> class BaseC(_internal_class):
> __slots__ = (some_other_data,...,__weaklist__,__dict__)
>
> class Derived(BaseB,BaseC):
> __slots__ = (combined_data,...,__weaklist__,__dict__)
Ah, ok. So BaseA sticks weaklist and dict into a certain layout
location. BaseB gets the same location because it has the same
layout.
BaseC sticks weaklist and dict into a different location. Derived
then can't reconcile it because dict and weakref are in different
locations.
Again, for the reasons I mentioned the layouts conflict even if you
set tp_weakreflist and tp_dictoffset.
> Before adding the weaklist and instance dicts, this all worked fine.
> _internal_class was necessary to prevent the "lay-out conflict" error.
That actually seems like an error to me. It should signal a conflict
if bases have different layout sizes from their own base, and one
isn't a base of the other, which wouldn't be the case here.
"some_data" a proper subset of "some_other_data", right? (If it isn't
you have worse problems than dict and weakreflist.) A more natural
way to handle this situation would be to place common slots in the
internal_class.
But we'll just accept it for now.
> But when I added them to every class except _internal_class, I got the
> error. I tried adding the dicts to _internal_class and it worked again.
> (The classes are set up like this because the code is from my unit-test
> code.)
Don't set tp_dictoffset and tp_weakrefoffset in any of the bases. Set
them only in Derived. If you need to instantiate a Base, make a
trivial dervied class for it.
Carl Banks
More information about the Python-list
mailing list