Negative array indicies and slice()

Andrew Robinson andrew3 at r3dsolutions.com
Mon Oct 29 18:39:42 EDT 2012


On 10/29/2012 06:49 PM, Chris Kaynor wrote:
> Every Python object requires two pieces of data, both of which are 
> pointer-sized (one is a pointer, one is an int the size of a pointer). 
> These are: a pointer to the object's type, and the object's reference 
> count. A tuple actually does not need a head pointer: the head pointer 
> is merely an offset from the tuple's pointer. It merely has a ref 
> count, type, an item count, and pointers to its contents. A slice has 
> the same type pointer and reference count, then three pointers to the 
> start, stop, and step objects. This means a slice object should be the 
> same size as a two-item tuple: the tuple needs a count, while that is 
> fixed at 3 for a slice (though some items may be unset). NOTE: The 
> above is taken from reading the source code for Python 2.6. For some 
> odd reason, I am getting that an empty tuple consists of 6 
> pointer-sized objects (48 bytes on x64), rather than the expected 3 
> pointer-sized (24 bytes on x64). Slices are showing up as the expected 
> 5 pointer-sized (40 bytes on x64), and tuples grow at the expected 1 
> pointer (8 bytes on x64) per item. I imagine I am missing something, 
> but cannot figure out what that would be.
>> All I see is:
>> typedef struct { object** whatever } PyTupleObject;
>>
It's fairly straight forward in 3.2.0.  I debugged the code with GDB and 
watched.
Perhaps it is the same in 2.6 ?

In addition to those items you mention, of which the reference count is 
not even *inside* the struct -- there is additional debugging 
information not mentioned.  Built in objects contain a "line number", a 
"column number", and a "context" pointer.  These each require a full 
word of storage.

Also, built in types appear to have a "kind" field which indicates the 
object "type" but is not a pointer.  That suggests two "object" type 
indicators, a generic pointer (probably pointing to "builtin"? somewhere 
outside the struct) and a specific one (an enum) inside the "C" struct.

Inside the tuple struct, I count 4 undocumented words of information.
Over all, there is a length, the list of pointers, a "kind", "line", 
"col" and "context"; making 6 pieces in total.

Although your comment says the head pointer is not required; I found in 
3.3.0 that it is a true head pointer; The Tuple() function on line 2069 
of Python-ast.c, (3.3 version) -- is passed in a pointer called *elts.  
That pointer is copied into the Tuple struct.

How ironic,  slices don't have debugging info, that's the main reason 
they are smaller.
When I do slice(3,0,2), suprisingly "Slice()" is NOT called.
But when I do a[1:2:3] it *IS* called.







More information about the Python-list mailing list