Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 50d756e

Browse files
committed
Fix SF bug #443600:
Change to get/set/del slice operations so that if the object doesn't support slicing, *or* if either of the slice arguments is not an int or long, we construct a slice object and call the get/set/del item operation instead. This makes it possible to design classes that support slice arguments of non-integral types.
1 parent b60f2d0 commit 50d756e

1 file changed

Lines changed: 46 additions & 15 deletions

File tree

Python/ceval.c

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3347,30 +3347,61 @@ _PyEval_SliceIndex(PyObject *v, int *pi)
33473347
return 1;
33483348
}
33493349

3350+
#undef ISINT
3351+
#define ISINT(x) ((x) == NULL || PyInt_Check(x) || PyLong_Check(x))
3352+
33503353
static PyObject *
33513354
apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */
33523355
{
3353-
int ilow = 0, ihigh = INT_MAX;
3354-
if (!_PyEval_SliceIndex(v, &ilow))
3355-
return NULL;
3356-
if (!_PyEval_SliceIndex(w, &ihigh))
3357-
return NULL;
3358-
return PySequence_GetSlice(u, ilow, ihigh);
3356+
PyTypeObject *tp = u->ob_type;
3357+
PySequenceMethods *sq = tp->tp_as_sequence;
3358+
3359+
if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
3360+
int ilow = 0, ihigh = INT_MAX;
3361+
if (!_PyEval_SliceIndex(v, &ilow))
3362+
return NULL;
3363+
if (!_PyEval_SliceIndex(w, &ihigh))
3364+
return NULL;
3365+
return PySequence_GetSlice(u, ilow, ihigh);
3366+
}
3367+
else {
3368+
PyObject *slice = PySlice_New(v, w, NULL);
3369+
if (slice != NULL)
3370+
return PyObject_GetItem(u, slice);
3371+
else
3372+
return NULL;
3373+
}
33593374
}
33603375

33613376
static int
33623377
assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
33633378
/* u[v:w] = x */
33643379
{
3365-
int ilow = 0, ihigh = INT_MAX;
3366-
if (!_PyEval_SliceIndex(v, &ilow))
3367-
return -1;
3368-
if (!_PyEval_SliceIndex(w, &ihigh))
3369-
return -1;
3370-
if (x == NULL)
3371-
return PySequence_DelSlice(u, ilow, ihigh);
3372-
else
3373-
return PySequence_SetSlice(u, ilow, ihigh, x);
3380+
PyTypeObject *tp = u->ob_type;
3381+
PySequenceMethods *sq = tp->tp_as_sequence;
3382+
3383+
if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
3384+
int ilow = 0, ihigh = INT_MAX;
3385+
if (!_PyEval_SliceIndex(v, &ilow))
3386+
return -1;
3387+
if (!_PyEval_SliceIndex(w, &ihigh))
3388+
return -1;
3389+
if (x == NULL)
3390+
return PySequence_DelSlice(u, ilow, ihigh);
3391+
else
3392+
return PySequence_SetSlice(u, ilow, ihigh, x);
3393+
}
3394+
else {
3395+
PyObject *slice = PySlice_New(v, w, NULL);
3396+
if (slice != NULL) {
3397+
if (x != NULL)
3398+
return PyObject_SetItem(u, slice, x);
3399+
else
3400+
return PyObject_DelItem(u, slice);
3401+
}
3402+
else
3403+
return -1;
3404+
}
33743405
}
33753406

33763407
static PyObject *

0 commit comments

Comments
 (0)