summaryrefslogtreecommitdiff
path: root/Modules/arraymodule.c
diff options
context:
space:
mode:
authorEzio Melotti <ezio.melotti@gmail.com>2015-09-06 21:44:45 +0300
committerEzio Melotti <ezio.melotti@gmail.com>2015-09-06 21:44:45 +0300
commitf352202977fc53197bd38198b1ac26ed4008a9ba (patch)
tree34246df426e6f7d82794886be98c613903a5655e /Modules/arraymodule.c
parentd68070857ae58758849446f5ae162ff3bffb7d6e (diff)
parent2936930f6c8fc1d8992b680181c30f417d74b7c2 (diff)
downloadcpython-f352202977fc53197bd38198b1ac26ed4008a9ba.tar.gz
#23144: merge with 3.4.
Diffstat (limited to 'Modules/arraymodule.c')
-rw-r--r--Modules/arraymodule.c768
1 files changed, 431 insertions, 337 deletions
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index 5ab1ab6836..a3ccf9344f 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -15,6 +15,11 @@
#endif /* HAVE_SYS_TYPES_H */
#endif /* !STDC_HEADERS */
+/*[clinic input]
+module array
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7d1b8d7f5958fd83]*/
+
struct arrayobject; /* Forward */
/* All possible arraydescr values are defined in the vector "descriptors"
@@ -42,6 +47,63 @@ typedef struct arrayobject {
static PyTypeObject Arraytype;
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t index;
+ arrayobject *ao;
+ PyObject* (*getitem)(struct arrayobject *, Py_ssize_t);
+} arrayiterobject;
+
+static PyTypeObject PyArrayIter_Type;
+
+#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
+
+enum machine_format_code {
+ UNKNOWN_FORMAT = -1,
+ /* UNKNOWN_FORMAT is used to indicate that the machine format for an
+ * array type code cannot be interpreted. When this occurs, a list of
+ * Python objects is used to represent the content of the array
+ * instead of using the memory content of the array directly. In that
+ * case, the array_reconstructor mechanism is bypassed completely, and
+ * the standard array constructor is used instead.
+ *
+ * This is will most likely occur when the machine doesn't use IEEE
+ * floating-point numbers.
+ */
+
+ UNSIGNED_INT8 = 0,
+ SIGNED_INT8 = 1,
+ UNSIGNED_INT16_LE = 2,
+ UNSIGNED_INT16_BE = 3,
+ SIGNED_INT16_LE = 4,
+ SIGNED_INT16_BE = 5,
+ UNSIGNED_INT32_LE = 6,
+ UNSIGNED_INT32_BE = 7,
+ SIGNED_INT32_LE = 8,
+ SIGNED_INT32_BE = 9,
+ UNSIGNED_INT64_LE = 10,
+ UNSIGNED_INT64_BE = 11,
+ SIGNED_INT64_LE = 12,
+ SIGNED_INT64_BE = 13,
+ IEEE_754_FLOAT_LE = 14,
+ IEEE_754_FLOAT_BE = 15,
+ IEEE_754_DOUBLE_LE = 16,
+ IEEE_754_DOUBLE_BE = 17,
+ UTF16_LE = 18,
+ UTF16_BE = 19,
+ UTF32_LE = 20,
+ UTF32_BE = 21
+};
+#define MACHINE_FORMAT_CODE_MIN 0
+#define MACHINE_FORMAT_CODE_MAX 21
+
+
+/*
+ * Must come after arrayobject, arrayiterobject,
+ * and enum machine_code_type definitions.
+ */
+#include "clinic/arraymodule.c.h"
+
#define array_Check(op) PyObject_TypeCheck(op, &Arraytype)
#define array_CheckExact(op) (Py_TYPE(op) == &Arraytype)
@@ -471,6 +533,10 @@ static struct arraydescr descriptors[] = {
/****************************************************************************
Implementations of array object methods.
****************************************************************************/
+/*[clinic input]
+class array.array "arrayobject *" "&Arraytype"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ad43d37e942a8854]*/
static PyObject *
newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr)
@@ -684,16 +750,35 @@ array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
return (PyObject *)np;
}
+
+/*[clinic input]
+array.array.__copy__
+
+Return a copy of the array.
+[clinic start generated code]*/
+
static PyObject *
-array_copy(arrayobject *a, PyObject *unused)
+array_array___copy___impl(arrayobject *self)
+/*[clinic end generated code: output=dec7c3f925d9619e input=ad1ee5b086965f09]*/
{
- return array_slice(a, 0, Py_SIZE(a));
+ return array_slice(self, 0, Py_SIZE(self));
}
-PyDoc_STRVAR(copy_doc,
-"copy(array)\n\
-\n\
- Return a copy of the array.");
+/*[clinic input]
+array.array.__deepcopy__
+
+ unused: object
+ /
+
+Return a copy of the array.
+[clinic start generated code]*/
+
+static PyObject *
+array_array___deepcopy__(arrayobject *self, PyObject *unused)
+/*[clinic end generated code: output=1ec748d8e14a9faa input=2405ecb4933748c4]*/
+{
+ return array_array___copy___impl(self);
+}
static PyObject *
array_concat(arrayobject *a, PyObject *bb)
@@ -961,8 +1046,18 @@ ins(arrayobject *self, Py_ssize_t where, PyObject *v)
return Py_None;
}
+/*[clinic input]
+array.array.count
+
+ v: object
+ /
+
+Return number of occurrences of v in the array.
+[clinic start generated code]*/
+
static PyObject *
-array_count(arrayobject *self, PyObject *v)
+array_array_count(arrayobject *self, PyObject *v)
+/*[clinic end generated code: output=3dd3624bf7135a3a input=d9bce9d65e39d1f5]*/
{
Py_ssize_t count = 0;
Py_ssize_t i;
@@ -984,13 +1079,19 @@ array_count(arrayobject *self, PyObject *v)
return PyLong_FromSsize_t(count);
}
-PyDoc_STRVAR(count_doc,
-"count(x)\n\
-\n\
-Return number of occurrences of x in the array.");
+
+/*[clinic input]
+array.array.index
+
+ v: object
+ /
+
+Return index of first occurrence of v in the array.
+[clinic start generated code]*/
static PyObject *
-array_index(arrayobject *self, PyObject *v)
+array_array_index(arrayobject *self, PyObject *v)
+/*[clinic end generated code: output=d48498d325602167 input=cf619898c6649d08]*/
{
Py_ssize_t i;
@@ -1013,11 +1114,6 @@ array_index(arrayobject *self, PyObject *v)
return NULL;
}
-PyDoc_STRVAR(index_doc,
-"index(x)\n\
-\n\
-Return index of first occurrence of x in the array.");
-
static int
array_contains(arrayobject *self, PyObject *v)
{
@@ -1034,8 +1130,18 @@ array_contains(arrayobject *self, PyObject *v)
return cmp;
}
+/*[clinic input]
+array.array.remove
+
+ v: object
+ /
+
+Remove the first occurrence of v in the array.
+[clinic start generated code]*/
+
static PyObject *
-array_remove(arrayobject *self, PyObject *v)
+array_array_remove(arrayobject *self, PyObject *v)
+/*[clinic end generated code: output=bef06be9fdf9dceb input=0b1e5aed25590027]*/
{
int i;
@@ -1062,18 +1168,23 @@ array_remove(arrayobject *self, PyObject *v)
return NULL;
}
-PyDoc_STRVAR(remove_doc,
-"remove(x)\n\
-\n\
-Remove the first occurrence of x in the array.");
+/*[clinic input]
+array.array.pop
+
+ i: Py_ssize_t = -1
+ /
+
+Return the i-th element and delete it from the array.
+
+i defaults to -1.
+[clinic start generated code]*/
static PyObject *
-array_pop(arrayobject *self, PyObject *args)
+array_array_pop_impl(arrayobject *self, Py_ssize_t i)
+/*[clinic end generated code: output=bc1f0c54fe5308e4 input=8e5feb4c1a11cd44]*/
{
- Py_ssize_t i = -1;
PyObject *v;
- if (!PyArg_ParseTuple(args, "|n:pop", &i))
- return NULL;
+
if (Py_SIZE(self) == 0) {
/* Special-case most common failure cause */
PyErr_SetString(PyExc_IndexError, "pop from empty array");
@@ -1095,13 +1206,18 @@ array_pop(arrayobject *self, PyObject *args)
return v;
}
-PyDoc_STRVAR(pop_doc,
-"pop([i])\n\
-\n\
-Return the i-th element and delete it from the array. i defaults to -1.");
+/*[clinic input]
+array.array.extend
+
+ bb: object
+ /
+
+Append items to the end of the array.
+[clinic start generated code]*/
static PyObject *
-array_extend(arrayobject *self, PyObject *bb)
+array_array_extend(arrayobject *self, PyObject *bb)
+/*[clinic end generated code: output=bbddbc8e8bef871d input=43be86aba5c31e44]*/
{
if (array_do_extend(self, bb) == -1)
return NULL;
@@ -1109,29 +1225,35 @@ array_extend(arrayobject *self, PyObject *bb)
return Py_None;
}
-PyDoc_STRVAR(extend_doc,
-"extend(array or iterable)\n\
-\n\
- Append items to the end of the array.");
+/*[clinic input]
+array.array.insert
+
+ i: Py_ssize_t
+ v: object
+ /
+
+Insert a new item v into the array before position i.
+[clinic start generated code]*/
static PyObject *
-array_insert(arrayobject *self, PyObject *args)
+array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v)
+/*[clinic end generated code: output=5a3648e278348564 input=5577d1b4383e9313]*/
{
- Py_ssize_t i;
- PyObject *v;
- if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))
- return NULL;
return ins(self, i, v);
}
-PyDoc_STRVAR(insert_doc,
-"insert(i,x)\n\
-\n\
-Insert a new item x into the array before position i.");
+/*[clinic input]
+array.array.buffer_info
+Return a tuple (address, length) giving the current memory address and the length in items of the buffer used to hold array's contents.
+
+The length should be multiplied by the itemsize attribute to calculate
+the buffer length in bytes.
+[clinic start generated code]*/
static PyObject *
-array_buffer_info(arrayobject *self, PyObject *unused)
+array_array_buffer_info_impl(arrayobject *self)
+/*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=a58bae5c6e1ac6a6]*/
{
PyObject *retval = NULL, *v;
@@ -1156,29 +1278,34 @@ array_buffer_info(arrayobject *self, PyObject *unused)
return retval;
}
-PyDoc_STRVAR(buffer_info_doc,
-"buffer_info() -> (address, length)\n\
-\n\
-Return a tuple (address, length) giving the current memory address and\n\
-the length in items of the buffer used to hold array's contents\n\
-The length should be multiplied by the itemsize attribute to calculate\n\
-the buffer length in bytes.");
+/*[clinic input]
+array.array.append
+
+ v: object
+ /
+Append new value v to the end of the array.
+[clinic start generated code]*/
static PyObject *
-array_append(arrayobject *self, PyObject *v)
+array_array_append(arrayobject *self, PyObject *v)
+/*[clinic end generated code: output=745a0669bf8db0e2 input=0b98d9d78e78f0fa]*/
{
return ins(self, Py_SIZE(self), v);
}
-PyDoc_STRVAR(append_doc,
-"append(x)\n\
-\n\
-Append new value x to the end of the array.");
+/*[clinic input]
+array.array.byteswap
+
+Byteswap all items of the array.
+If the items in the array are not 1, 2, 4, or 8 bytes in size, RuntimeError is
+raised.
+[clinic start generated code]*/
static PyObject *
-array_byteswap(arrayobject *self, PyObject *unused)
+array_array_byteswap_impl(arrayobject *self)
+/*[clinic end generated code: output=5f8236cbdf0d90b5 input=6a85591b950a0186]*/
{
char *p;
Py_ssize_t i;
@@ -1228,14 +1355,15 @@ array_byteswap(arrayobject *self, PyObject *unused)
return Py_None;
}
-PyDoc_STRVAR(byteswap_doc,
-"byteswap()\n\
-\n\
-Byteswap all items of the array. If the items in the array are not 1, 2,\n\
-4, or 8 bytes in size, RuntimeError is raised.");
+/*[clinic input]
+array.array.reverse
+
+Reverse the order of the items in the array.
+[clinic start generated code]*/
static PyObject *
-array_reverse(arrayobject *self, PyObject *unused)
+array_array_reverse_impl(arrayobject *self)
+/*[clinic end generated code: output=c04868b36f6f4089 input=cd904f01b27d966a]*/
{
Py_ssize_t itemsize = self->ob_descr->itemsize;
char *p, *q;
@@ -1261,27 +1389,26 @@ array_reverse(arrayobject *self, PyObject *unused)
return Py_None;
}
-PyDoc_STRVAR(reverse_doc,
-"reverse()\n\
-\n\
-Reverse the order of the items in the array.");
+/*[clinic input]
+array.array.fromfile
+ f: object
+ n: Py_ssize_t
+ /
-/* Forward */
-static PyObject *array_frombytes(arrayobject *self, PyObject *args);
+Read n objects from the file object f and append them to the end of the array.
+[clinic start generated code]*/
static PyObject *
-array_fromfile(arrayobject *self, PyObject *args)
+array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n)
+/*[clinic end generated code: output=ec9f600e10f53510 input=e188afe8e58adf40]*/
{
- PyObject *f, *b, *res;
+ PyObject *b, *res;
Py_ssize_t itemsize = self->ob_descr->itemsize;
- Py_ssize_t n, nbytes;
+ Py_ssize_t nbytes;
_Py_IDENTIFIER(read);
int not_enough_bytes;
- if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n))
- return NULL;
-
if (n < 0) {
PyErr_SetString(PyExc_ValueError, "negative count");
return NULL;
@@ -1305,13 +1432,8 @@ array_fromfile(arrayobject *self, PyObject *args)
not_enough_bytes = (PyBytes_GET_SIZE(b) != nbytes);
- args = Py_BuildValue("(O)", b);
+ res = array_array_frombytes(self, b);
Py_DECREF(b);
- if (args == NULL)
- return NULL;
-
- res = array_frombytes(self, args);
- Py_DECREF(args);
if (res == NULL)
return NULL;
@@ -1325,15 +1447,18 @@ array_fromfile(arrayobject *self, PyObject *args)
return res;
}
-PyDoc_STRVAR(fromfile_doc,
-"fromfile(f, n)\n\
-\n\
-Read n objects from the file object f and append them to the end of the\n\
-array.");
+/*[clinic input]
+array.array.tofile
+ f: object
+ /
+
+Write all items (as machine values) to the file object f.
+[clinic start generated code]*/
static PyObject *
-array_tofile(arrayobject *self, PyObject *f)
+array_array_tofile(arrayobject *self, PyObject *f)
+/*[clinic end generated code: output=3a2cfa8128df0777 input=b0669a484aab0831]*/
{
Py_ssize_t nbytes = Py_SIZE(self) * self->ob_descr->itemsize;
/* Write 64K blocks at a time */
@@ -1368,14 +1493,18 @@ array_tofile(arrayobject *self, PyObject *f)
return Py_None;
}
-PyDoc_STRVAR(tofile_doc,
-"tofile(f)\n\
-\n\
-Write all items (as machine values) to the file object f.");
+/*[clinic input]
+array.array.fromlist
+ list: object
+ /
+
+Append items to array from list.
+[clinic start generated code]*/
static PyObject *
-array_fromlist(arrayobject *self, PyObject *list)
+array_array_fromlist(arrayobject *self, PyObject *list)
+/*[clinic end generated code: output=26411c2d228a3e3f input=be2605a96c49680f]*/
{
Py_ssize_t n;
@@ -1402,13 +1531,15 @@ array_fromlist(arrayobject *self, PyObject *list)
return Py_None;
}
-PyDoc_STRVAR(fromlist_doc,
-"fromlist(list)\n\
-\n\
-Append items to array from list.");
+/*[clinic input]
+array.array.tolist
+
+Convert array to an ordinary list with the same items.
+[clinic start generated code]*/
static PyObject *
-array_tolist(arrayobject *self, PyObject *unused)
+array_array_tolist_impl(arrayobject *self)
+/*[clinic end generated code: output=00b60cc9eab8ef89 input=a8d7784a94f86b53]*/
{
PyObject *list = PyList_New(Py_SIZE(self));
Py_ssize_t i;
@@ -1429,11 +1560,6 @@ error:
return NULL;
}
-PyDoc_STRVAR(tolist_doc,
-"tolist() -> list\n\
-\n\
-Convert array to an ordinary list with the same items.");
-
static PyObject *
frombytes(arrayobject *self, Py_buffer *buffer)
{
@@ -1471,47 +1597,52 @@ frombytes(arrayobject *self, Py_buffer *buffer)
return Py_None;
}
+/*[clinic input]
+array.array.fromstring
+
+ buffer: Py_buffer(accept={str, buffer})
+ /
+
+Appends items from the string, interpreting it as an array of machine values, as if it had been read from a file using the fromfile() method).
+
+This method is deprecated. Use frombytes instead.
+[clinic start generated code]*/
+
static PyObject *
-array_fromstring(arrayobject *self, PyObject *args)
+array_array_fromstring_impl(arrayobject *self, Py_buffer *buffer)
+/*[clinic end generated code: output=31c4baa779df84ce input=a3341a512e11d773]*/
{
- Py_buffer buffer;
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"fromstring() is deprecated. Use frombytes() instead.", 2) != 0)
return NULL;
- if (!PyArg_ParseTuple(args, "s*:fromstring", &buffer))
- return NULL;
- else
- return frombytes(self, &buffer);
+ return frombytes(self, buffer);
}
-PyDoc_STRVAR(fromstring_doc,
-"fromstring(string)\n\
-\n\
-Appends items from the string, interpreting it as an array of machine\n\
-values, as if it had been read from a file using the fromfile() method).\n\
-\n\
-This method is deprecated. Use frombytes instead.");
+/*[clinic input]
+array.array.frombytes
+ buffer: Py_buffer
+ /
+
+Appends items from the string, interpreting it as an array of machine values, as if it had been read from a file using the fromfile() method).
+[clinic start generated code]*/
static PyObject *
-array_frombytes(arrayobject *self, PyObject *args)
+array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer)
+/*[clinic end generated code: output=d9842c8f7510a516 input=2bbf2b53ebfcc988]*/
{
- Py_buffer buffer;
- if (!PyArg_ParseTuple(args, "y*:frombytes", &buffer))
- return NULL;
- else
- return frombytes(self, &buffer);
+ return frombytes(self, buffer);
}
-PyDoc_STRVAR(frombytes_doc,
-"frombytes(bytestring)\n\
-\n\
-Appends items from the string, interpreting it as an array of machine\n\
-values, as if it had been read from a file using the fromfile() method).");
+/*[clinic input]
+array.array.tobytes
+Convert the array to an array of machine values and return the bytes representation.
+[clinic start generated code]*/
static PyObject *
-array_tobytes(arrayobject *self, PyObject *unused)
+array_array_tobytes_impl(arrayobject *self)
+/*[clinic end generated code: output=87318e4edcdc2bb6 input=90ee495f96de34f5]*/
{
if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
return PyBytes_FromStringAndSize(self->ob_item,
@@ -1521,40 +1652,44 @@ array_tobytes(arrayobject *self, PyObject *unused)
}
}
-PyDoc_STRVAR(tobytes_doc,
-"tobytes() -> bytes\n\
-\n\
-Convert the array to an array of machine values and return the bytes\n\
-representation.");
+/*[clinic input]
+array.array.tostring
+Convert the array to an array of machine values and return the bytes representation.
+
+This method is deprecated. Use tobytes instead.
+[clinic start generated code]*/
static PyObject *
-array_tostring(arrayobject *self, PyObject *unused)
+array_array_tostring_impl(arrayobject *self)
+/*[clinic end generated code: output=7d6bd92745a2c8f3 input=b6c0ddee7b30457e]*/
{
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"tostring() is deprecated. Use tobytes() instead.", 2) != 0)
return NULL;
- return array_tobytes(self, unused);
+ return array_array_tobytes_impl(self);
}
-PyDoc_STRVAR(tostring_doc,
-"tostring() -> bytes\n\
-\n\
-Convert the array to an array of machine values and return the bytes\n\
-representation.\n\
-\n\
-This method is deprecated. Use tobytes instead.");
+/*[clinic input]
+array.array.fromunicode
+
+ ustr: Py_UNICODE(zeroes=True)
+ /
+Extends this array with data from the unicode string ustr.
+
+The array must be a unicode type array; otherwise a ValueError is raised.
+Use array.frombytes(ustr.encode(...)) to append Unicode data to an array of
+some other type.
+[clinic start generated code]*/
static PyObject *
-array_fromunicode(arrayobject *self, PyObject *args)
+array_array_fromunicode_impl(arrayobject *self, Py_UNICODE *ustr,
+ Py_ssize_clean_t ustr_length)
+/*[clinic end generated code: output=ebb72fc16975e06d input=150f00566ffbca6e]*/
{
- Py_UNICODE *ustr;
- Py_ssize_t n;
char typecode;
- if (!PyArg_ParseTuple(args, "u#:fromunicode", &ustr, &n))
- return NULL;
typecode = self->ob_descr->typecode;
if (typecode != 'u') {
PyErr_SetString(PyExc_ValueError,
@@ -1562,29 +1697,30 @@ array_fromunicode(arrayobject *self, PyObject *args)
"unicode type arrays");
return NULL;
}
- if (n > 0) {
+ if (ustr_length > 0) {
Py_ssize_t old_size = Py_SIZE(self);
- if (array_resize(self, old_size + n) == -1)
+ if (array_resize(self, old_size + ustr_length) == -1)
return NULL;
memcpy(self->ob_item + old_size * sizeof(Py_UNICODE),
- ustr, n * sizeof(Py_UNICODE));
+ ustr, ustr_length * sizeof(Py_UNICODE));
}
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
-PyDoc_STRVAR(fromunicode_doc,
-"fromunicode(ustr)\n\
-\n\
-Extends this array with data from the unicode string ustr.\n\
-The array must be a unicode type array; otherwise a ValueError\n\
-is raised. Use array.frombytes(ustr.encode(...)) to\n\
-append Unicode data to an array of some other type.");
+/*[clinic input]
+array.array.tounicode
+
+Extends this array with data from the unicode string ustr.
+Convert the array to a unicode string. The array must be a unicode type array;
+otherwise a ValueError is raised. Use array.tobytes().decode() to obtain a
+unicode string from an array of some other type.
+[clinic start generated code]*/
static PyObject *
-array_tounicode(arrayobject *self, PyObject *unused)
+array_array_tounicode_impl(arrayobject *self)
+/*[clinic end generated code: output=08e442378336e1ef input=127242eebe70b66d]*/
{
char typecode;
typecode = self->ob_descr->typecode;
@@ -1596,70 +1732,24 @@ array_tounicode(arrayobject *self, PyObject *unused)
return PyUnicode_FromUnicode((Py_UNICODE *) self->ob_item, Py_SIZE(self));
}
-PyDoc_STRVAR(tounicode_doc,
-"tounicode() -> unicode\n\
-\n\
-Convert the array to a unicode string. The array must be\n\
-a unicode type array; otherwise a ValueError is raised. Use\n\
-array.tobytes().decode() to obtain a unicode string from\n\
-an array of some other type.");
+/*[clinic input]
+array.array.__sizeof__
+Size of the array in memory, in bytes.
+[clinic start generated code]*/
static PyObject *
-array_sizeof(arrayobject *self, PyObject *unused)
+array_array___sizeof___impl(arrayobject *self)
+/*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/
{
Py_ssize_t res;
res = sizeof(arrayobject) + self->allocated * self->ob_descr->itemsize;
return PyLong_FromSsize_t(res);
}
-PyDoc_STRVAR(sizeof_doc,
-"__sizeof__() -> int\n\
-\n\
-Size of the array in memory, in bytes.");
-
/*********************** Pickling support ************************/
-enum machine_format_code {
- UNKNOWN_FORMAT = -1,
- /* UNKNOWN_FORMAT is used to indicate that the machine format for an
- * array type code cannot be interpreted. When this occurs, a list of
- * Python objects is used to represent the content of the array
- * instead of using the memory content of the array directly. In that
- * case, the array_reconstructor mechanism is bypassed completely, and
- * the standard array constructor is used instead.
- *
- * This is will most likely occur when the machine doesn't use IEEE
- * floating-point numbers.
- */
-
- UNSIGNED_INT8 = 0,
- SIGNED_INT8 = 1,
- UNSIGNED_INT16_LE = 2,
- UNSIGNED_INT16_BE = 3,
- SIGNED_INT16_LE = 4,
- SIGNED_INT16_BE = 5,
- UNSIGNED_INT32_LE = 6,
- UNSIGNED_INT32_BE = 7,
- SIGNED_INT32_LE = 8,
- SIGNED_INT32_BE = 9,
- UNSIGNED_INT64_LE = 10,
- UNSIGNED_INT64_BE = 11,
- SIGNED_INT64_LE = 12,
- SIGNED_INT64_BE = 13,
- IEEE_754_FLOAT_LE = 14,
- IEEE_754_FLOAT_BE = 15,
- IEEE_754_DOUBLE_LE = 16,
- IEEE_754_DOUBLE_BE = 17,
- UTF16_LE = 18,
- UTF16_BE = 19,
- UTF32_LE = 20,
- UTF32_BE = 21
-};
-#define MACHINE_FORMAT_CODE_MIN 0
-#define MACHINE_FORMAT_CODE_MAX 21
-
static const struct mformatdescr {
size_t size;
int is_signed;
@@ -1835,21 +1925,29 @@ make_array(PyTypeObject *arraytype, char typecode, PyObject *items)
* This functions is a special constructor used when unpickling an array. It
* provides a portable way to rebuild an array from its memory representation.
*/
+/*[clinic input]
+array._array_reconstructor
+
+ arraytype: object(type="PyTypeObject *")
+ typecode: int(accept={str})
+ mformat_code: int(type="enum machine_format_code")
+ items: object
+ /
+
+Internal. Used for pickling support.
+[clinic start generated code]*/
+
static PyObject *
-array_reconstructor(PyObject *self, PyObject *args)
+array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype,
+ int typecode,
+ enum machine_format_code mformat_code,
+ PyObject *items)
+/*[clinic end generated code: output=6ecbf0e8e4d92ab9 input=2464dc8f4c7736b5]*/
{
- PyTypeObject *arraytype;
- PyObject *items;
PyObject *converted_items;
PyObject *result;
- int typecode;
- enum machine_format_code mformat_code;
struct arraydescr *descr;
- if (!PyArg_ParseTuple(args, "OCiO:array._array_reconstructor",
- &arraytype, &typecode, &mformat_code, &items))
- return NULL;
-
if (!PyType_Check(arraytype)) {
PyErr_Format(PyExc_TypeError,
"first argument must a type object, not %.200s",
@@ -2000,7 +2098,7 @@ array_reconstructor(PyObject *self, PyObject *args)
*/
for (descr = descriptors; descr->typecode != '\0'; descr++) {
if (descr->is_integer_type &&
- descr->itemsize == mf_descr.size &&
+ (size_t)descr->itemsize == mf_descr.size &&
descr->is_signed == mf_descr.is_signed)
typecode = descr->typecode;
}
@@ -2038,13 +2136,23 @@ array_reconstructor(PyObject *self, PyObject *args)
return result;
}
+/*[clinic input]
+array.array.__reduce_ex__
+
+ value: object
+ /
+
+Return state information for pickling.
+[clinic start generated code]*/
+
static PyObject *
-array_reduce_ex(arrayobject *array, PyObject *value)
+array_array___reduce_ex__(arrayobject *self, PyObject *value)
+/*[clinic end generated code: output=051e0a6175d0eddb input=c36c3f85de7df6cd]*/
{
PyObject *dict;
PyObject *result;
PyObject *array_str;
- int typecode = array->ob_descr->typecode;
+ int typecode = self->ob_descr->typecode;
int mformat_code;
static PyObject *array_reconstructor = NULL;
long protocol;
@@ -2072,7 +2180,7 @@ array_reduce_ex(arrayobject *array, PyObject *value)
if (protocol == -1 && PyErr_Occurred())
return NULL;
- dict = _PyObject_GetAttrId((PyObject *)array, &PyId___dict__);
+ dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
if (dict == NULL) {
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
return NULL;
@@ -2095,32 +2203,30 @@ array_reduce_ex(arrayobject *array, PyObject *value)
* coercing unicode objects to bytes in array_reconstructor.
*/
PyObject *list;
- list = array_tolist(array, NULL);
+ list = array_array_tolist_impl(self);
if (list == NULL) {
Py_DECREF(dict);
return NULL;
}
result = Py_BuildValue(
- "O(CO)O", Py_TYPE(array), typecode, list, dict);
+ "O(CO)O", Py_TYPE(self), typecode, list, dict);
Py_DECREF(list);
Py_DECREF(dict);
return result;
}
- array_str = array_tobytes(array, NULL);
+ array_str = array_array_tobytes_impl(self);
if (array_str == NULL) {
Py_DECREF(dict);
return NULL;
}
result = Py_BuildValue(
- "O(OCiN)O", array_reconstructor, Py_TYPE(array), typecode,
+ "O(OCiN)O", array_reconstructor, Py_TYPE(self), typecode,
mformat_code, array_str, dict);
Py_DECREF(dict);
return result;
}
-PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
-
static PyObject *
array_get_typecode(arrayobject *a, void *closure)
{
@@ -2143,55 +2249,31 @@ static PyGetSetDef array_getsets [] = {
};
static PyMethodDef array_methods[] = {
- {"append", (PyCFunction)array_append, METH_O,
- append_doc},
- {"buffer_info", (PyCFunction)array_buffer_info, METH_NOARGS,
- buffer_info_doc},
- {"byteswap", (PyCFunction)array_byteswap, METH_NOARGS,
- byteswap_doc},
- {"__copy__", (PyCFunction)array_copy, METH_NOARGS,
- copy_doc},
- {"count", (PyCFunction)array_count, METH_O,
- count_doc},
- {"__deepcopy__", (PyCFunction)array_copy, METH_O,
- copy_doc},
- {"extend", (PyCFunction)array_extend, METH_O,
- extend_doc},
- {"fromfile", (PyCFunction)array_fromfile, METH_VARARGS,
- fromfile_doc},
- {"fromlist", (PyCFunction)array_fromlist, METH_O,
- fromlist_doc},
- {"fromstring", (PyCFunction)array_fromstring, METH_VARARGS,
- fromstring_doc},
- {"frombytes", (PyCFunction)array_frombytes, METH_VARARGS,
- frombytes_doc},
- {"fromunicode", (PyCFunction)array_fromunicode, METH_VARARGS,
- fromunicode_doc},
- {"index", (PyCFunction)array_index, METH_O,
- index_doc},
- {"insert", (PyCFunction)array_insert, METH_VARARGS,
- insert_doc},
- {"pop", (PyCFunction)array_pop, METH_VARARGS,
- pop_doc},
- {"__reduce_ex__", (PyCFunction)array_reduce_ex, METH_O,
- reduce_doc},
- {"remove", (PyCFunction)array_remove, METH_O,
- remove_doc},
- {"reverse", (PyCFunction)array_reverse, METH_NOARGS,
- reverse_doc},
- {"tofile", (PyCFunction)array_tofile, METH_O,
- tofile_doc},
- {"tolist", (PyCFunction)array_tolist, METH_NOARGS,
- tolist_doc},
- {"tostring", (PyCFunction)array_tostring, METH_NOARGS,
- tostring_doc},
- {"tobytes", (PyCFunction)array_tobytes, METH_NOARGS,
- tobytes_doc},
- {"tounicode", (PyCFunction)array_tounicode, METH_NOARGS,
- tounicode_doc},
- {"__sizeof__", (PyCFunction)array_sizeof, METH_NOARGS,
- sizeof_doc},
- {NULL, NULL} /* sentinel */
+ ARRAY_ARRAY_APPEND_METHODDEF
+ ARRAY_ARRAY_BUFFER_INFO_METHODDEF
+ ARRAY_ARRAY_BYTESWAP_METHODDEF
+ ARRAY_ARRAY___COPY___METHODDEF
+ ARRAY_ARRAY_COUNT_METHODDEF
+ ARRAY_ARRAY___DEEPCOPY___METHODDEF
+ ARRAY_ARRAY_EXTEND_METHODDEF
+ ARRAY_ARRAY_FROMFILE_METHODDEF
+ ARRAY_ARRAY_FROMLIST_METHODDEF
+ ARRAY_ARRAY_FROMSTRING_METHODDEF
+ ARRAY_ARRAY_FROMBYTES_METHODDEF
+ ARRAY_ARRAY_FROMUNICODE_METHODDEF
+ ARRAY_ARRAY_INDEX_METHODDEF
+ ARRAY_ARRAY_INSERT_METHODDEF
+ ARRAY_ARRAY_POP_METHODDEF
+ ARRAY_ARRAY___REDUCE_EX___METHODDEF
+ ARRAY_ARRAY_REMOVE_METHODDEF
+ ARRAY_ARRAY_REVERSE_METHODDEF
+ ARRAY_ARRAY_TOFILE_METHODDEF
+ ARRAY_ARRAY_TOLIST_METHODDEF
+ ARRAY_ARRAY_TOSTRING_METHODDEF
+ ARRAY_ARRAY_TOBYTES_METHODDEF
+ ARRAY_ARRAY_TOUNICODE_METHODDEF
+ ARRAY_ARRAY___SIZEOF___METHODDEF
+ {NULL, NULL} /* sentinel */
};
static PyObject *
@@ -2207,9 +2289,9 @@ array_repr(arrayobject *a)
return PyUnicode_FromFormat("array('%c')", (int)typecode);
}
if (typecode == 'u') {
- v = array_tounicode(a, NULL);
+ v = array_array_tounicode_impl(a);
} else {
- v = array_tolist(a, NULL);
+ v = array_array_tolist_impl(a);
}
if (v == NULL)
return NULL;
@@ -2446,7 +2528,11 @@ static const void *emptybuf = "";
static int
array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags)
{
- if (view==NULL) goto finish;
+ if (view == NULL) {
+ PyErr_SetString(PyExc_BufferError,
+ "array_buffer_getbuf: view==NULL argument is obsolete");
+ return -1;
+ }
view->buf = (void *)self->ob_item;
view->obj = (PyObject*)self;
@@ -2476,7 +2562,6 @@ array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags)
#endif
}
- finish:
self->ob_exports++;
return 0;
}
@@ -2586,15 +2671,9 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
else if (initial != NULL && (PyByteArray_Check(initial) ||
PyBytes_Check(initial))) {
- PyObject *t_initial, *v;
- t_initial = PyTuple_Pack(1, initial);
- if (t_initial == NULL) {
- Py_DECREF(a);
- return NULL;
- }
- v = array_frombytes((arrayobject *)a,
- t_initial);
- Py_DECREF(t_initial);
+ PyObject *v;
+ v = array_array_frombytes((arrayobject *)a,
+ initial);
if (v == NULL) {
Py_DECREF(a);
return NULL;
@@ -2766,16 +2845,10 @@ static PyTypeObject Arraytype = {
/*********************** Array Iterator **************************/
-typedef struct {
- PyObject_HEAD
- Py_ssize_t index;
- arrayobject *ao;
- PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
-} arrayiterobject;
-
-static PyTypeObject PyArrayIter_Type;
-
-#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
+/*[clinic input]
+class array.arrayiterator "arrayiterobject *" "&PyArrayIter_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5aefd2d74d8c8e30]*/
static PyObject *
array_iter(arrayobject *ao)
@@ -2823,33 +2896,47 @@ arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
return 0;
}
+/*[clinic input]
+array.arrayiterator.__reduce__
+
+Return state information for pickling.
+[clinic start generated code]*/
+
static PyObject *
-arrayiter_reduce(arrayiterobject *it)
+array_arrayiterator___reduce___impl(arrayiterobject *self)
+/*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/
{
return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
- it->ao, it->index);
+ self->ao, self->index);
}
+/*[clinic input]
+array.arrayiterator.__setstate__
+
+ state: object
+ /
+
+Set state information for unpickling.
+[clinic start generated code]*/
+
static PyObject *
-arrayiter_setstate(arrayiterobject *it, PyObject *state)
+array_arrayiterator___setstate__(arrayiterobject *self, PyObject *state)
+/*[clinic end generated code: output=397da9904e443cbe input=f47d5ceda19e787b]*/
{
Py_ssize_t index = PyLong_AsSsize_t(state);
if (index == -1 && PyErr_Occurred())
return NULL;
if (index < 0)
index = 0;
- else if (index > Py_SIZE(it->ao))
- index = Py_SIZE(it->ao); /* iterator exhausted */
- it->index = index;
+ else if (index > Py_SIZE(self->ao))
+ index = Py_SIZE(self->ao); /* iterator exhausted */
+ self->index = index;
Py_RETURN_NONE;
}
-PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
static PyMethodDef arrayiter_methods[] = {
- {"__reduce__", (PyCFunction)arrayiter_reduce, METH_NOARGS,
- reduce_doc},
- {"__setstate__", (PyCFunction)arrayiter_setstate, METH_O,
- setstate_doc},
+ ARRAY_ARRAYITERATOR___REDUCE___METHODDEF
+ ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF
{NULL, NULL} /* sentinel */
};
@@ -2890,39 +2977,21 @@ static PyTypeObject PyArrayIter_Type = {
/* No functions in array module. */
static PyMethodDef a_methods[] = {
- {"_array_reconstructor", array_reconstructor, METH_VARARGS,
- PyDoc_STR("Internal. Used for pickling support.")},
+ ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF
{NULL, NULL, 0, NULL} /* Sentinel */
};
-static struct PyModuleDef arraymodule = {
- PyModuleDef_HEAD_INIT,
- "array",
- module_doc,
- -1,
- a_methods,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-
-PyMODINIT_FUNC
-PyInit_array(void)
+static int
+array_modexec(PyObject *m)
{
- PyObject *m;
char buffer[Py_ARRAY_LENGTH(descriptors)], *p;
PyObject *typecodes;
Py_ssize_t size = 0;
struct arraydescr *descr;
if (PyType_Ready(&Arraytype) < 0)
- return NULL;
+ return -1;
Py_TYPE(&PyArrayIter_Type) = &PyType_Type;
- m = PyModule_Create(&arraymodule);
- if (m == NULL)
- return NULL;
Py_INCREF((PyObject *)&Arraytype);
PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype);
@@ -2945,5 +3014,30 @@ PyInit_array(void)
Py_DECREF(m);
m = NULL;
}
- return m;
+ return 0;
+}
+
+static PyModuleDef_Slot arrayslots[] = {
+ {Py_mod_exec, array_modexec},
+ {0, NULL}
+};
+
+
+static struct PyModuleDef arraymodule = {
+ PyModuleDef_HEAD_INIT,
+ "array",
+ module_doc,
+ 0,
+ a_methods,
+ arrayslots,
+ NULL,
+ NULL,
+ NULL
+};
+
+
+PyMODINIT_FUNC
+PyInit_array(void)
+{
+ return PyModuleDef_Init(&arraymodule);
}