mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-24 08:14:10 +03:00
py3k: Allow slicing for paths
This is Gohlke's fix for two issues: negative indexes on paths were not resolved to the correct index, and path slicing didn't work. His fix for slicing is related to the one found at: http://renesd.blogspot.com/2009/07/python3-c-api-simple-slicing-sqslice.html With this commit, all 79 tests (82 minus the three skipped ones) run successfully on Python 2.6.8, Python 2.7.3rc2, and Python 3.2.3.
This commit is contained in:
parent
a7e3b2e47b
commit
be560f00f5
51
path.c
51
path.c
|
@ -370,6 +370,8 @@ path_getbbox(PyPathObject* self, PyObject* args)
|
|||
static PyObject*
|
||||
path_getitem(PyPathObject* self, int i)
|
||||
{
|
||||
if (i < 0)
|
||||
i = self->count + i;
|
||||
if (i < 0 || i >= self->count) {
|
||||
PyErr_SetString(PyExc_IndexError, "path index out of range");
|
||||
return NULL;
|
||||
|
@ -559,6 +561,47 @@ static struct PyGetSetDef getsetters[] = {
|
|||
{ NULL }
|
||||
};
|
||||
|
||||
static PyObject*
|
||||
path_subscript(PyPathObject* self, PyObject* item) {
|
||||
if (PyIndex_Check(item)) {
|
||||
Py_ssize_t i;
|
||||
i = PyNumber_AsSsize_t(item, PyExc_IndexError);
|
||||
if (i == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
return path_getitem(self, i);
|
||||
}
|
||||
if (PySlice_Check(item)) {
|
||||
int len = 4;
|
||||
Py_ssize_t start, stop, step, slicelength;
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
if (PySlice_GetIndicesEx(item, len, &start, &stop, &step, &slicelength) < 0)
|
||||
return NULL;
|
||||
#else
|
||||
if (PySlice_GetIndicesEx((PySliceObject*)item, len, &start, &stop, &step, &slicelength) < 0)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
if (slicelength <= 0) {
|
||||
double *xy = alloc_array(0);
|
||||
return (PyObject*) path_new(0, xy, 0);
|
||||
}
|
||||
else if (step == 1) {
|
||||
return path_getslice(self, start, stop);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "slice steps not supported");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Path indices must be integers, not %.200s",
|
||||
Py_TYPE(&item)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static PySequenceMethods path_as_sequence = {
|
||||
(lenfunc)path_len, /*sq_length*/
|
||||
(binaryfunc)0, /*sq_concat*/
|
||||
|
@ -569,6 +612,12 @@ static PySequenceMethods path_as_sequence = {
|
|||
(ssizessizeobjargproc)0, /*sq_ass_slice*/
|
||||
};
|
||||
|
||||
static PyMappingMethods path_as_mapping = {
|
||||
(lenfunc)path_len,
|
||||
(binaryfunc)path_subscript,
|
||||
NULL
|
||||
};
|
||||
|
||||
static PyTypeObject PyPathType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"Path", /*tp_name*/
|
||||
|
@ -583,7 +632,7 @@ static PyTypeObject PyPathType = {
|
|||
0, /*tp_repr*/
|
||||
0, /*tp_as_number */
|
||||
&path_as_sequence, /*tp_as_sequence */
|
||||
0, /*tp_as_mapping */
|
||||
&path_as_mapping, /*tp_as_mapping */
|
||||
0, /*tp_hash*/
|
||||
0, /*tp_call*/
|
||||
0, /*tp_str*/
|
||||
|
|
Loading…
Reference in New Issue
Block a user