diff options
Diffstat (limited to 'Modules/arraymodule.c')
-rw-r--r-- | Modules/arraymodule.c | 95 |
1 files changed, 35 insertions, 60 deletions
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index b9f87aeea3..4d9a23fb99 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -31,7 +31,7 @@ struct arraydescr { int itemsize; PyObject * (*getitem)(struct arrayobject *, Py_ssize_t); int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *); - char *formats; + const char *formats; int is_integer_type; int is_signed; }; @@ -40,7 +40,7 @@ typedef struct arrayobject { PyObject_VAR_HEAD char *ob_item; Py_ssize_t allocated; - struct arraydescr *ob_descr; + const struct arraydescr *ob_descr; PyObject *weakreflist; /* List of weak references */ int ob_exports; /* Number of exported buffers */ } arrayobject; @@ -511,7 +511,7 @@ d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) * Don't forget to update typecode_to_mformat_code() if you add a new * typecode. */ -static struct arraydescr descriptors[] = { +static const struct arraydescr descriptors[] = { {'b', 1, b_getitem, b_setitem, "b", 1, 1}, {'B', 1, BB_getitem, BB_setitem, "B", 1, 0}, {'u', sizeof(Py_UNICODE), u_getitem, u_setitem, "u", 0, 0}, @@ -539,7 +539,7 @@ class array.array "arrayobject *" "&Arraytype" /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ad43d37e942a8854]*/ static PyObject * -newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr) +newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr) { arrayobject *op; size_t nbytes; @@ -846,37 +846,10 @@ array_repeat(arrayobject *a, Py_ssize_t n) } static int -array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) +array_del_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh) { char *item; - Py_ssize_t n; /* Size of replacement array */ Py_ssize_t d; /* Change in size */ -#define b ((arrayobject *)v) - if (v == NULL) - n = 0; - else if (array_Check(v)) { - n = Py_SIZE(b); - if (a == b) { - /* Special case "a[i:j] = a" -- copy b first */ - int ret; - v = array_slice(b, 0, n); - if (!v) - return -1; - ret = array_ass_slice(a, ilow, ihigh, v); - Py_DECREF(v); - return ret; - } - if (b->ob_descr != a->ob_descr) { - PyErr_BadArgument(); - return -1; - } - } - else { - PyErr_Format(PyExc_TypeError, - "can only assign array (not \"%.200s\") to array slice", - Py_TYPE(v)->tp_name); - return -1; - } if (ilow < 0) ilow = 0; else if (ilow > Py_SIZE(a)) @@ -888,7 +861,7 @@ array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) else if (ihigh > Py_SIZE(a)) ihigh = Py_SIZE(a); item = a->ob_item; - d = n - (ihigh-ilow); + d = ihigh-ilow; /* Issue #4509: If the array has exported buffers and the slice assignment would change the size of the array, fail early to make sure we don't modify it. */ @@ -897,25 +870,14 @@ array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) "cannot resize an array that is exporting buffers"); return -1; } - if (d < 0) { /* Delete -d items */ - memmove(item + (ihigh+d)*a->ob_descr->itemsize, + if (d > 0) { /* Delete d items */ + memmove(item + (ihigh-d)*a->ob_descr->itemsize, item + ihigh*a->ob_descr->itemsize, (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize); - if (array_resize(a, Py_SIZE(a) + d) == -1) + if (array_resize(a, Py_SIZE(a) - d) == -1) return -1; } - else if (d > 0) { /* Insert d items */ - if (array_resize(a, Py_SIZE(a) + d)) - return -1; - memmove(item + (ihigh+d)*a->ob_descr->itemsize, - item + ihigh*a->ob_descr->itemsize, - (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize); - } - if (n > 0) - memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item, - n*b->ob_descr->itemsize); return 0; -#undef b } static int @@ -927,7 +889,7 @@ array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v) return -1; } if (v == NULL) - return array_ass_slice(a, i, i+1, v); + return array_del_slice(a, i, i+1); return (*a->ob_descr->setitem)(a, i, v); } @@ -1155,8 +1117,7 @@ array_array_remove(arrayobject *self, PyObject *v) cmp = PyObject_RichCompareBool(selfi, v, Py_EQ); Py_DECREF(selfi); if (cmp > 0) { - if (array_ass_slice(self, i, i+1, - (PyObject *)NULL) != 0) + if (array_del_slice(self, i, i+1) != 0) return NULL; Py_INCREF(Py_None); return Py_None; @@ -1199,7 +1160,7 @@ array_array_pop_impl(arrayobject *self, Py_ssize_t i) v = getarrayitem((PyObject *)self, i); if (v == NULL) return NULL; - if (array_ass_slice(self, i, i+1, (PyObject *)NULL) != 0) { + if (array_del_slice(self, i, i+1) != 0) { Py_DECREF(v); return NULL; } @@ -1946,7 +1907,7 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, { PyObject *converted_items; PyObject *result; - struct arraydescr *descr; + const struct arraydescr *descr; if (!PyType_Check(arraytype)) { PyErr_Format(PyExc_TypeError, @@ -2084,7 +2045,7 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, Py_ssize_t itemcount = Py_SIZE(items) / mf_descr.size; const unsigned char *memstr = (unsigned char *)PyBytes_AS_STRING(items); - struct arraydescr *descr; + const struct arraydescr *descr; /* If possible, try to pack array's items using a data type * that fits better. This may result in an array with narrower @@ -2554,7 +2515,7 @@ array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags) view->format = NULL; view->internal = NULL; if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) { - view->format = self->ob_descr->formats; + view->format = (char *)self->ob_descr->formats; #ifdef Py_UNICODE_WIDE if (self->ob_descr->typecode == 'u') { view->format = "w"; @@ -2595,7 +2556,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { int c; PyObject *initial = NULL, *it = NULL; - struct arraydescr *descr; + const struct arraydescr *descr; if (type == &Arraytype && !_PyArg_NoKeywords("array.array()", kwds)) return NULL; @@ -2875,9 +2836,20 @@ array_iter(arrayobject *ao) static PyObject * arrayiter_next(arrayiterobject *it) { + arrayobject *ao; + + assert(it != NULL); assert(PyArrayIter_Check(it)); - if (it->index < Py_SIZE(it->ao)) - return (*it->getitem)(it->ao, it->index++); + ao = it->ao; + if (ao == NULL) { + return NULL; + } + assert(array_Check(ao)); + if (it->index < Py_SIZE(ao)) { + return (*it->getitem)(ao, it->index++); + } + it->ao = NULL; + Py_DECREF(ao); return NULL; } @@ -2906,8 +2878,11 @@ static PyObject * array_arrayiterator___reduce___impl(arrayiterobject *self) /*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/ { - return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - self->ao, self->index); + PyObject *func = _PyObject_GetBuiltin("iter"); + if (self->ao == NULL) { + return Py_BuildValue("N(())", func); + } + return Py_BuildValue("N(O)n", func, self->ao, self->index); } /*[clinic input] @@ -2987,7 +2962,7 @@ array_modexec(PyObject *m) char buffer[Py_ARRAY_LENGTH(descriptors)], *p; PyObject *typecodes; Py_ssize_t size = 0; - struct arraydescr *descr; + const struct arraydescr *descr; if (PyType_Ready(&Arraytype) < 0) return -1; |