Negative array indicies and slice()
Andrew Robinson
andrew3 at r3dsolutions.com
Mon Oct 29 14:00:08 EDT 2012
On 10/29/2012 06:53 AM, Chris Angelico wrote:
> Can you provide links to these notes? I'm looking at
> cpython/Include/sliceobject.h that has this comment:
>
> /*
>
> A slice object containing start, stop, and step data members (the
> names are from range). After much talk with Guido, it was decided to
> let these be any arbitrary python type. Py_None stands for omitted values.
> */
>
> Also, the code for slice objects in CPython works with Py_ssize_t (a
> signed quantity of the same length as size_t), which will allow at
> least 2**31 for an index. I would guess that your crashes were nothing
> to do with 20 million elements and slices.
>
> ChrisA
Let's look at the source code rather than the web notes -- the source
must be the true answer anyhow.
I downloaded the source code for python 3.3.0, as the tbz;
In the directory "Python-3.3.0/Python", look at Python-ast.c, line 2089
& ff.
Clearly a slice is malloced for a slice_ty type.
It has four elements: kind, lower, upper, and step.
So, tracing it back to the struct definition...
"Include/Python-ast.h" has "typedef struct _slice *slice_ty;"
And, here's the answer!:
enum _slice_kind {Slice_kind=1, ExtSlice_kind=2, Index_kind=3};
struct _slice {
enum _slice_kind kind;
union {
struct {
expr_ty lower;
expr_ty upper;
expr_ty step;
} Slice;
struct {
asdl_seq *dims;
} ExtSlice;
struct {
expr_ty value;
} Index;
} v;
};
So, slice() does indeed have arbitrary python types included in it;
contrary to what I read elsewhere.
expr_ty is a pointer to an arbitrary expression, so the actual structure
is 4 pointers, at 32 bits each = 16 bytes.
The size of the structure itself, given in an earlier post, is 20 bytes
-- which means one more pointer is involved, perhaps the one pointing to
the slice structure itself.
Hmm...!
An empty tuple gives sys.getsizeof( () ) = 24.
But, I would expect a tuple to be merely a list of object pointers;
hence I would expect 4 bytes for len(), and then a head pointer 4 bytes,
and then a pointer for each object.
3 objects gives 12 bytes, + 8 = 16 bytes.
Then we need one more pointer so Python knows where the struct is...
So a Tuple of 3 objects ought to fit nicely into 20 bytes; the same size
as slice() --
but it's 24, even when empty...
And 36 when initialized...
What are the extra 16 bytes for?
All I see is:
typedef struct { object** whatever } PyTupleObject;
More information about the Python-list
mailing list