[Patches] [ python-Patches-1173475 ] __slots__ for subclasses of variable length types

SourceForge.net noreply at sourceforge.net
Sun Apr 3 17:27:26 CEST 2005


Patches item #1173475, was opened at 2005-03-30 17:09
Message generated for change (Comment added) made by arigo
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1173475&group_id=5470

Category: Core (C code)
Group: Python 2.5
Status: Open
Resolution: None
Priority: 5
Submitted By: Michael Hudson (mwh)
Assigned to: Armin Rigo (arigo)
Summary: __slots__ for subclasses of variable length types

Initial Comment:
This is a first, rough cut at allowing subclasses of variable length 
types to have __slots__ of all flavours, not just __dict__.

The motivation is trying to understand and document what's going on 
in typeobject.c, and the less special cases knocking around the 
better.

This patch also allows instances of such classes to be weakly 
referenced.

What is missing: tests, lots of tests, documentation.  Also, the code 
is a bit hackish at various points; a degree of clean up can certainly 
be acheived.

Also, I think my code probably fails to cope with code like:

class A(str):
 pass # implicitly adds __dict__, __weakref__
class B(A):
 __slots__ = ["a", "b"]

b = B()
b.c = 1

Hmm, yes.  Oh well, no time to fix today (I don't think it's that big a 
deal).

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

>Comment By: Armin Rigo (arigo)
Date: 2005-04-03 15:27

Message:
Logged In: YES 
user_id=4771

I think it's still possible to give slot.offset the same meaning as tp_dictoffset, even given the additional constrain that it can't change upon subclassing.  In your example classes S and T, we can put 'b' before 'a' in memory, so that a.offset==-4 (for both S and T) and b.offset==-8.

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

Comment By: Michael Hudson (mwh)
Date: 2005-04-03 14:32

Message:
Logged In: YES 
user_id=6656

> I'm confused: the rule for negative slot offsets appear to be
> different to the one for tp_dictoffset

Yes.  I think this is actually necessary.

Consider:

class S(str):
    __slots__ = ['a']

you'd except S.__dict__['a'].__offset__ (well, if the attribute existed) to be 
-4.

Then

class T(S):
    __slots__ = ['b']

then using the 'from the end of the object' rule for  T().a would actually find 
T.b.  (IOW, T.__dict__['b'].__offset__ == T.__dict__['a'].__offset__ == -4).  
The alternative would be to somehow override all the slots in S when T is 
defined -- and this doesn't seem wise.

__dict__ indeed works differently, because 
instance.__class__.__dictoffset__ is updated on subclassing.  You could 
make __dict__ work like the slots mentioned above, but then you'd have to 
find the '__dict__' descriptor every time you wanted to access an 
instance's dictionary, and that would be slow (and might even not really 
work, but I don't want to risk brain-explosion by thinking about it too hard)

> which only increases the amount of obscurity around here.

Yeah, sorry about that.

I think something I've realised over the past few days is that __dict__ 
really is special.  I'm not sure __weakref__ is (though I guess it's special in 
that you want to be able to access it from C without any risk of executing 
Python level code, i.e. replacing Py_GETWEAKREFLIST(ob) with 
PyOjbect_GetAttrString(ob, "__weakref__") would be unfortunate).

> This should be resolved one way or the other 

See above -- don't think you can.

> -- and I think that
> a clear picture of the various parts of the object and how they
> are measured would be a good start.

No kidding here!

> That's also related to your proposed change to extra_ivars(),
> which would become slightly more permissive; I strongly suspect
> that it would allow more strange segfaulting cases to sneak in
> undetected...

Almost certainly!

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

Comment By: Armin Rigo (arigo)
Date: 2005-04-03 14:11

Message:
Logged In: YES 
user_id=4771

I'm confused: the rule for negative slot offsets appear to be different to the one for tp_dictoffset, which only increases the amount of obscurity around here.

tp_dictoffset counts relative to the end of the object, whereas in your patch negative slot offsets are a different trick to mean "relative to the start but skipping the varsized part".  The difference shows up when subclassing increases tp_basicsize.  This should be resolved one way or the other -- and I think that a clear picture of the various parts of the object and how they are measured would be a good start.

That's also related to your proposed change to extra_ivars(), which would become slightly more permissive; I strongly suspect that it would allow more strange segfaulting cases to sneak in undetected...

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

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1173475&group_id=5470


More information about the Patches mailing list