mirror of
https://github.com/python/cpython
synced 2026-09-29 09:55:31 +03:00
Remove the simple slicing API. All slicing is now done with slice objects.
This commit is contained in:
parent
582b586617
commit
d2cf20eea2
32 changed files with 78 additions and 810 deletions
|
|
@ -1505,26 +1505,12 @@ PySequence_GetItem(PyObject *s, Py_ssize_t i)
|
|||
PyObject *
|
||||
PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
|
||||
{
|
||||
PySequenceMethods *m;
|
||||
PyMappingMethods *mp;
|
||||
|
||||
if (!s) return null_error();
|
||||
|
||||
m = s->ob_type->tp_as_sequence;
|
||||
if (m && m->sq_slice) {
|
||||
if (i1 < 0 || i2 < 0) {
|
||||
if (m->sq_length) {
|
||||
Py_ssize_t l = (*m->sq_length)(s);
|
||||
if (l < 0)
|
||||
return NULL;
|
||||
if (i1 < 0)
|
||||
i1 += l;
|
||||
if (i2 < 0)
|
||||
i2 += l;
|
||||
}
|
||||
}
|
||||
return m->sq_slice(s, i1, i2);
|
||||
} else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_subscript) {
|
||||
mp = s->ob_type->tp_as_mapping;
|
||||
if (mp->mp_subscript) {
|
||||
PyObject *res;
|
||||
PyObject *slice = _PySlice_FromIndices(i1, i2);
|
||||
if (!slice)
|
||||
|
|
@ -1594,7 +1580,6 @@ PySequence_DelItem(PyObject *s, Py_ssize_t i)
|
|||
int
|
||||
PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o)
|
||||
{
|
||||
PySequenceMethods *m;
|
||||
PyMappingMethods *mp;
|
||||
|
||||
if (s == NULL) {
|
||||
|
|
@ -1602,21 +1587,8 @@ PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o)
|
|||
return -1;
|
||||
}
|
||||
|
||||
m = s->ob_type->tp_as_sequence;
|
||||
if (m && m->sq_ass_slice) {
|
||||
if (i1 < 0 || i2 < 0) {
|
||||
if (m->sq_length) {
|
||||
Py_ssize_t l = (*m->sq_length)(s);
|
||||
if (l < 0)
|
||||
return -1;
|
||||
if (i1 < 0)
|
||||
i1 += l;
|
||||
if (i2 < 0)
|
||||
i2 += l;
|
||||
}
|
||||
}
|
||||
return m->sq_ass_slice(s, i1, i2, o);
|
||||
} else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_ass_subscript) {
|
||||
mp = s->ob_type->tp_as_mapping;
|
||||
if (mp->mp_ass_subscript) {
|
||||
int res;
|
||||
PyObject *slice = _PySlice_FromIndices(i1, i2);
|
||||
if (!slice)
|
||||
|
|
@ -1633,27 +1605,22 @@ PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o)
|
|||
int
|
||||
PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
|
||||
{
|
||||
PySequenceMethods *m;
|
||||
PyMappingMethods *mp;
|
||||
|
||||
if (s == NULL) {
|
||||
null_error();
|
||||
return -1;
|
||||
}
|
||||
|
||||
m = s->ob_type->tp_as_sequence;
|
||||
if (m && m->sq_ass_slice) {
|
||||
if (i1 < 0 || i2 < 0) {
|
||||
if (m->sq_length) {
|
||||
Py_ssize_t l = (*m->sq_length)(s);
|
||||
if (l < 0)
|
||||
return -1;
|
||||
if (i1 < 0)
|
||||
i1 += l;
|
||||
if (i2 < 0)
|
||||
i2 += l;
|
||||
}
|
||||
}
|
||||
return m->sq_ass_slice(s, i1, i2, (PyObject *)NULL);
|
||||
mp = s->ob_type->tp_as_mapping;
|
||||
if (mp->mp_ass_subscript) {
|
||||
int res;
|
||||
PyObject *slice = _PySlice_FromIndices(i1, i2);
|
||||
if (!slice)
|
||||
return -1;
|
||||
res = mp->mp_ass_subscript(s, slice, NULL);
|
||||
Py_DECREF(slice);
|
||||
return res;
|
||||
}
|
||||
type_error("'%.200s' object doesn't support slice deletion", s);
|
||||
return -1;
|
||||
|
|
@ -1925,9 +1892,7 @@ int
|
|||
PyMapping_Check(PyObject *o)
|
||||
{
|
||||
return o && o->ob_type->tp_as_mapping &&
|
||||
o->ob_type->tp_as_mapping->mp_subscript &&
|
||||
!(o->ob_type->tp_as_sequence &&
|
||||
o->ob_type->tp_as_sequence->sq_slice);
|
||||
o->ob_type->tp_as_mapping->mp_subscript;
|
||||
}
|
||||
|
||||
Py_ssize_t
|
||||
|
|
|
|||
|
|
@ -464,28 +464,6 @@ buffer_item(PyBufferObject *self, Py_ssize_t idx)
|
|||
return ob;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
|
||||
{
|
||||
PyObject *ob;
|
||||
PyBuffer view;
|
||||
if (!get_buf(self, &view, PyBUF_SIMPLE))
|
||||
return NULL;
|
||||
if (left < 0)
|
||||
left = 0;
|
||||
if (right < 0)
|
||||
right = 0;
|
||||
if (right > view.len)
|
||||
right = view.len;
|
||||
if (right < left)
|
||||
right = left;
|
||||
/* XXX(nnorwitz): is it possible to access unitialized memory? */
|
||||
ob = PyBytes_FromStringAndSize((char *)view.buf + left,
|
||||
right - left);
|
||||
PyObject_ReleaseBuffer((PyObject *)self, &view);
|
||||
return ob;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
buffer_subscript(PyBufferObject *self, PyObject *item)
|
||||
{
|
||||
|
|
@ -604,62 +582,6 @@ buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right,
|
||||
PyObject *other)
|
||||
{
|
||||
PyBufferProcs *pb;
|
||||
PyBuffer v1, v2;
|
||||
Py_ssize_t slice_len;
|
||||
|
||||
pb = other ? other->ob_type->tp_as_buffer : NULL;
|
||||
if (pb == NULL ||
|
||||
pb->bf_getbuffer == NULL) {
|
||||
PyErr_BadArgument();
|
||||
return -1;
|
||||
}
|
||||
if (!get_buf(self, &v1, PyBUF_SIMPLE))
|
||||
return -1;
|
||||
|
||||
if (self->b_readonly || v1.readonly) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"buffer is read-only");
|
||||
PyObject_ReleaseBuffer((PyObject *)self, &v1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((*pb->bf_getbuffer)(other, &v2, PyBUF_SIMPLE) < 0) {
|
||||
PyObject_ReleaseBuffer((PyObject *)self, &v1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (left < 0)
|
||||
left = 0;
|
||||
else if (left > v1.len)
|
||||
left = v1.len;
|
||||
if (right < left)
|
||||
right = left;
|
||||
else if (right > v1.len)
|
||||
right = v1.len;
|
||||
slice_len = right - left;
|
||||
|
||||
if (v2.len != slice_len) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
"right operand length must match slice length");
|
||||
PyObject_ReleaseBuffer((PyObject *)self, &v1);
|
||||
PyObject_ReleaseBuffer(other, &v2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (slice_len)
|
||||
memcpy((char *)v1.buf + left, v2.buf, slice_len);
|
||||
|
||||
PyObject_ReleaseBuffer((PyObject *)self, &v1);
|
||||
PyObject_ReleaseBuffer(other, &v2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
|
||||
{
|
||||
|
|
@ -743,9 +665,9 @@ static PySequenceMethods buffer_as_sequence = {
|
|||
(binaryfunc)buffer_concat, /*sq_concat*/
|
||||
(ssizeargfunc)buffer_repeat, /*sq_repeat*/
|
||||
(ssizeargfunc)buffer_item, /*sq_item*/
|
||||
(ssizessizeargfunc)buffer_slice, /*sq_slice*/
|
||||
0, /*sq_slice*/
|
||||
(ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
|
||||
(ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
|
||||
0, /*sq_ass_slice*/
|
||||
};
|
||||
|
||||
static PyMappingMethods buffer_as_mapping = {
|
||||
|
|
|
|||
|
|
@ -2423,9 +2423,9 @@ static PySequenceMethods list_as_sequence = {
|
|||
(binaryfunc)list_concat, /* sq_concat */
|
||||
(ssizeargfunc)list_repeat, /* sq_repeat */
|
||||
(ssizeargfunc)list_item, /* sq_item */
|
||||
(ssizessizeargfunc)list_slice, /* sq_slice */
|
||||
0, /* sq_slice */
|
||||
(ssizeobjargproc)list_ass_item, /* sq_ass_item */
|
||||
(ssizessizeobjargproc)list_ass_slice, /* sq_ass_slice */
|
||||
0, /* sq_ass_slice */
|
||||
(objobjproc)list_contains, /* sq_contains */
|
||||
(binaryfunc)list_inplace_concat, /* sq_inplace_concat */
|
||||
(ssizeargfunc)list_inplace_repeat, /* sq_inplace_repeat */
|
||||
|
|
|
|||
|
|
@ -965,29 +965,6 @@ string_repeat(register PyStringObject *a, register Py_ssize_t n)
|
|||
return (PyObject *) op;
|
||||
}
|
||||
|
||||
/* String slice a[i:j] consists of characters a[i] ... a[j-1] */
|
||||
|
||||
static PyObject *
|
||||
string_slice(register PyStringObject *a, register Py_ssize_t i,
|
||||
register Py_ssize_t j)
|
||||
/* j -- may be negative! */
|
||||
{
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
if (j < 0)
|
||||
j = 0; /* Avoid signed/unsigned bug in next line */
|
||||
if (j > Py_Size(a))
|
||||
j = Py_Size(a);
|
||||
if (i == 0 && j == Py_Size(a) && PyString_CheckExact(a)) {
|
||||
/* It's the same as a */
|
||||
Py_INCREF(a);
|
||||
return (PyObject *)a;
|
||||
}
|
||||
if (j < i)
|
||||
j = i;
|
||||
return PyString_FromStringAndSize(a->ob_sval + i, j-i);
|
||||
}
|
||||
|
||||
static int
|
||||
string_contains(PyObject *str_obj, PyObject *sub_obj)
|
||||
{
|
||||
|
|
@ -1193,7 +1170,7 @@ static PySequenceMethods string_as_sequence = {
|
|||
(binaryfunc)string_concat, /*sq_concat*/
|
||||
(ssizeargfunc)string_repeat, /*sq_repeat*/
|
||||
(ssizeargfunc)string_item, /*sq_item*/
|
||||
(ssizessizeargfunc)string_slice, /*sq_slice*/
|
||||
0, /*sq_slice*/
|
||||
0, /*sq_ass_item*/
|
||||
0, /*sq_ass_slice*/
|
||||
(objobjproc)string_contains /*sq_contains*/
|
||||
|
|
|
|||
|
|
@ -340,7 +340,7 @@ static PySequenceMethods structseq_as_sequence = {
|
|||
(binaryfunc)structseq_concat, /* sq_concat */
|
||||
(ssizeargfunc)structseq_repeat, /* sq_repeat */
|
||||
(ssizeargfunc)structseq_item, /* sq_item */
|
||||
(ssizessizeargfunc)structseq_slice, /* sq_slice */
|
||||
0, /* sq_slice */
|
||||
0, /* sq_ass_item */
|
||||
0, /* sq_ass_slice */
|
||||
(objobjproc)structseq_contains, /* sq_contains */
|
||||
|
|
|
|||
|
|
@ -554,7 +554,7 @@ static PySequenceMethods tuple_as_sequence = {
|
|||
(binaryfunc)tupleconcat, /* sq_concat */
|
||||
(ssizeargfunc)tuplerepeat, /* sq_repeat */
|
||||
(ssizeargfunc)tupleitem, /* sq_item */
|
||||
(ssizessizeargfunc)tupleslice, /* sq_slice */
|
||||
0, /* sq_slice */
|
||||
0, /* sq_ass_item */
|
||||
0, /* sq_ass_slice */
|
||||
(objobjproc)tuplecontains, /* sq_contains */
|
||||
|
|
|
|||
|
|
@ -3260,9 +3260,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
|
|||
COPYSEQ(sq_concat);
|
||||
COPYSEQ(sq_repeat);
|
||||
COPYSEQ(sq_item);
|
||||
COPYSEQ(sq_slice);
|
||||
COPYSEQ(sq_ass_item);
|
||||
COPYSEQ(sq_ass_slice);
|
||||
COPYSEQ(sq_contains);
|
||||
COPYSEQ(sq_inplace_concat);
|
||||
COPYSEQ(sq_inplace_repeat);
|
||||
|
|
@ -3765,17 +3763,6 @@ wrap_sq_item(PyObject *self, PyObject *args, void *wrapped)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
wrap_ssizessizeargfunc(PyObject *self, PyObject *args, void *wrapped)
|
||||
{
|
||||
ssizessizeargfunc func = (ssizessizeargfunc)wrapped;
|
||||
Py_ssize_t i, j;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "nn", &i, &j))
|
||||
return NULL;
|
||||
return (*func)(self, i, j);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
wrap_sq_setitem(PyObject *self, PyObject *args, void *wrapped)
|
||||
{
|
||||
|
|
@ -3817,39 +3804,6 @@ wrap_sq_delitem(PyObject *self, PyObject *args, void *wrapped)
|
|||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
wrap_ssizessizeobjargproc(PyObject *self, PyObject *args, void *wrapped)
|
||||
{
|
||||
ssizessizeobjargproc func = (ssizessizeobjargproc)wrapped;
|
||||
Py_ssize_t i, j;
|
||||
int res;
|
||||
PyObject *value;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "nnO", &i, &j, &value))
|
||||
return NULL;
|
||||
res = (*func)(self, i, j, value);
|
||||
if (res == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
wrap_delslice(PyObject *self, PyObject *args, void *wrapped)
|
||||
{
|
||||
ssizessizeobjargproc func = (ssizessizeobjargproc)wrapped;
|
||||
Py_ssize_t i, j;
|
||||
int res;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "nn", &i, &j))
|
||||
return NULL;
|
||||
res = (*func)(self, i, j, NULL);
|
||||
if (res == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
/* XXX objobjproc is a misnomer; should be objargpred */
|
||||
static PyObject *
|
||||
wrap_objobjproc(PyObject *self, PyObject *args, void *wrapped)
|
||||
|
|
@ -4363,8 +4317,6 @@ slot_sq_item(PyObject *self, Py_ssize_t i)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SLOT2(slot_sq_slice, "__getslice__", Py_ssize_t, Py_ssize_t, "nn")
|
||||
|
||||
static int
|
||||
slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value)
|
||||
{
|
||||
|
|
@ -4383,24 +4335,6 @@ slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
slot_sq_ass_slice(PyObject *self, Py_ssize_t i, Py_ssize_t j, PyObject *value)
|
||||
{
|
||||
PyObject *res;
|
||||
static PyObject *delslice_str, *setslice_str;
|
||||
|
||||
if (value == NULL)
|
||||
res = call_method(self, "__delslice__", &delslice_str,
|
||||
"(nn)", i, j);
|
||||
else
|
||||
res = call_method(self, "__setslice__", &setslice_str,
|
||||
"(nnO)", i, j, value);
|
||||
if (res == NULL)
|
||||
return -1;
|
||||
Py_DECREF(res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
slot_sq_contains(PyObject *self, PyObject *value)
|
||||
{
|
||||
|
|
@ -5123,23 +5057,10 @@ static slotdef slotdefs[] = {
|
|||
"x.__rmul__(n) <==> n*x"),
|
||||
SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item,
|
||||
"x.__getitem__(y) <==> x[y]"),
|
||||
SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_ssizessizeargfunc,
|
||||
"x.__getslice__(i, j) <==> x[i:j]\n\
|
||||
\n\
|
||||
Use of negative indices is not supported."),
|
||||
SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem,
|
||||
"x.__setitem__(i, y) <==> x[i]=y"),
|
||||
SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem,
|
||||
"x.__delitem__(y) <==> del x[y]"),
|
||||
SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice,
|
||||
wrap_ssizessizeobjargproc,
|
||||
"x.__setslice__(i, j, y) <==> x[i:j]=y\n\
|
||||
\n\
|
||||
Use of negative indices is not supported."),
|
||||
SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice, wrap_delslice,
|
||||
"x.__delslice__(i, j) <==> del x[i:j]\n\
|
||||
\n\
|
||||
Use of negative indices is not supported."),
|
||||
SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc,
|
||||
"x.__contains__(y) <==> y in x"),
|
||||
SQSLOT("__iadd__", sq_inplace_concat, NULL,
|
||||
|
|
|
|||
|
|
@ -7502,28 +7502,6 @@ unicode_rjust(PyUnicodeObject *self, PyObject *args)
|
|||
return (PyObject*) pad(self, width - self->length, 0, fillchar);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
unicode_slice(PyUnicodeObject *self, Py_ssize_t start, Py_ssize_t end)
|
||||
{
|
||||
/* standard clamping */
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
if (end < 0)
|
||||
end = 0;
|
||||
if (end > self->length)
|
||||
end = self->length;
|
||||
if (start == 0 && end == self->length && PyUnicode_CheckExact(self)) {
|
||||
/* full slice, return original string */
|
||||
Py_INCREF(self);
|
||||
return (PyObject*) self;
|
||||
}
|
||||
if (start > end)
|
||||
start = end;
|
||||
/* copy slice */
|
||||
return (PyObject*) PyUnicode_FromUnicode(self->str + start,
|
||||
end - start);
|
||||
}
|
||||
|
||||
PyObject *PyUnicode_Split(PyObject *s,
|
||||
PyObject *sep,
|
||||
Py_ssize_t maxsplit)
|
||||
|
|
@ -8039,7 +8017,7 @@ static PySequenceMethods unicode_as_sequence = {
|
|||
PyUnicode_Concat, /* sq_concat */
|
||||
(ssizeargfunc) unicode_repeat, /* sq_repeat */
|
||||
(ssizeargfunc) unicode_getitem, /* sq_item */
|
||||
(ssizessizeargfunc) unicode_slice, /* sq_slice */
|
||||
0, /* sq_slice */
|
||||
0, /* sq_ass_item */
|
||||
0, /* sq_ass_slice */
|
||||
PyUnicode_Contains, /* sq_contains */
|
||||
|
|
|
|||
|
|
@ -520,22 +520,6 @@ proxy_dealloc(PyWeakReference *self)
|
|||
|
||||
/* sequence slots */
|
||||
|
||||
static PyObject *
|
||||
proxy_slice(PyWeakReference *proxy, Py_ssize_t i, Py_ssize_t j)
|
||||
{
|
||||
if (!proxy_checkref(proxy))
|
||||
return NULL;
|
||||
return PySequence_GetSlice(PyWeakref_GET_OBJECT(proxy), i, j);
|
||||
}
|
||||
|
||||
static int
|
||||
proxy_ass_slice(PyWeakReference *proxy, Py_ssize_t i, Py_ssize_t j, PyObject *value)
|
||||
{
|
||||
if (!proxy_checkref(proxy))
|
||||
return -1;
|
||||
return PySequence_SetSlice(PyWeakref_GET_OBJECT(proxy), i, j, value);
|
||||
}
|
||||
|
||||
static int
|
||||
proxy_contains(PyWeakReference *proxy, PyObject *value)
|
||||
{
|
||||
|
|
@ -628,9 +612,9 @@ static PySequenceMethods proxy_as_sequence = {
|
|||
0, /*sq_concat*/
|
||||
0, /*sq_repeat*/
|
||||
0, /*sq_item*/
|
||||
(ssizessizeargfunc)proxy_slice, /*sq_slice*/
|
||||
0, /*sq_slice*/
|
||||
0, /*sq_ass_item*/
|
||||
(ssizessizeobjargproc)proxy_ass_slice, /*sq_ass_slice*/
|
||||
0, /*sq_ass_slice*/
|
||||
(objobjproc)proxy_contains, /* sq_contains */
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue