mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
b60f2d0977
commit
50d756e262
|
@ -3347,30 +3347,61 @@ _PyEval_SliceIndex(PyObject *v, int *pi)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef ISINT
|
||||||
|
#define ISINT(x) ((x) == NULL || PyInt_Check(x) || PyLong_Check(x))
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */
|
apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */
|
||||||
{
|
{
|
||||||
int ilow = 0, ihigh = INT_MAX;
|
PyTypeObject *tp = u->ob_type;
|
||||||
if (!_PyEval_SliceIndex(v, &ilow))
|
PySequenceMethods *sq = tp->tp_as_sequence;
|
||||||
return NULL;
|
|
||||||
if (!_PyEval_SliceIndex(w, &ihigh))
|
if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
|
||||||
return NULL;
|
int ilow = 0, ihigh = INT_MAX;
|
||||||
return PySequence_GetSlice(u, ilow, ihigh);
|
if (!_PyEval_SliceIndex(v, &ilow))
|
||||||
|
return NULL;
|
||||||
|
if (!_PyEval_SliceIndex(w, &ihigh))
|
||||||
|
return NULL;
|
||||||
|
return PySequence_GetSlice(u, ilow, ihigh);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyObject *slice = PySlice_New(v, w, NULL);
|
||||||
|
if (slice != NULL)
|
||||||
|
return PyObject_GetItem(u, slice);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
|
assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
|
||||||
/* u[v:w] = x */
|
/* u[v:w] = x */
|
||||||
{
|
{
|
||||||
int ilow = 0, ihigh = INT_MAX;
|
PyTypeObject *tp = u->ob_type;
|
||||||
if (!_PyEval_SliceIndex(v, &ilow))
|
PySequenceMethods *sq = tp->tp_as_sequence;
|
||||||
return -1;
|
|
||||||
if (!_PyEval_SliceIndex(w, &ihigh))
|
if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
|
||||||
return -1;
|
int ilow = 0, ihigh = INT_MAX;
|
||||||
if (x == NULL)
|
if (!_PyEval_SliceIndex(v, &ilow))
|
||||||
return PySequence_DelSlice(u, ilow, ihigh);
|
return -1;
|
||||||
else
|
if (!_PyEval_SliceIndex(w, &ihigh))
|
||||||
return PySequence_SetSlice(u, ilow, ihigh, x);
|
return -1;
|
||||||
|
if (x == NULL)
|
||||||
|
return PySequence_DelSlice(u, ilow, ihigh);
|
||||||
|
else
|
||||||
|
return PySequence_SetSlice(u, ilow, ihigh, x);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyObject *slice = PySlice_New(v, w, NULL);
|
||||||
|
if (slice != NULL) {
|
||||||
|
if (x != NULL)
|
||||||
|
return PyObject_SetItem(u, slice, x);
|
||||||
|
else
|
||||||
|
return PyObject_DelItem(u, slice);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
Loading…
Reference in New Issue