mmap as a sequence behavior

L

Lawrence Oluyede

While wrapping mmap indexing/sequence emulation I noticed something
"strange".

The source code of this oddity is:

static PyObject *
mmap_item(mmap_object *self, Py_ssize_t i)
{
CHECK_VALID(NULL);
if (i < 0 || (size_t)i >= self->size) {
PyErr_SetString(PyExc_IndexError, "mmap index out of range");
return NULL;
}
return PyString_FromStringAndSize(self->data + i, 1);
}

located in mmapmodule.c

What's got my attention was the fact that passing -1 from Python does
not trigger the exception but is changed to the last positive and valid
index. Let's make an example:

import mmap
f = open("foo", "w+")
f.write("foobar")
f.flush()
m = mmap.mmap(f.fileno(), 6)
print m[-1] # == 'f'

I expect this raise IndexError as reading the C source code but it
behaves exactly like sequence types in Python. That's fair to me but I
don't get *where* my index is translated.

If I print the 'i' variable in the C source code before the if statement
I get len(ourmap) - 1 instead of "-1"

What am I missing from the C API?
 
S

Scott David Daniels

Lawrence said:
While wrapping mmap indexing/sequence emulation I noticed something
"strange". What's got my attention was the fact that passing -1 from
> Python does not trigger the exception but is changed to the last
> positive and valid index....
> I expect this raise IndexError as reading the C source code but it
> behaves exactly like sequence types in Python. That's fair to me but I
> don't get *where* my index is translated.


That is sequence behavior. The convention of -1 for last, -2 for
second-to-last, ... is done before it gets to your C code. I suspect
if you don't define a __len__ method, you'd suppress this.

--Scott David Daniels
(e-mail address removed)
 
L

Lawrence Oluyede

Scott David Daniels said:
That is sequence behavior. The convention of -1 for last, -2 for
second-to-last, ... is done before it gets to your C code. I suspect
if you don't define a __len__ method, you'd suppress this.

I defined a __len__ method but I get the index "plain" without any kind
of conversion before entering the method
 
L

Lawrence Oluyede

Lawrence Oluyede said:
What am I missing from the C API?

Found. I edit abstract.c placing some printf here and there and
discovered PyObject_GetItem is always called and in turn it call
PySequence_GetItem so is there my index is translated.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top