blob: 12bd51705579bdcae22552040fcae3f2f8455123 [file] [log] [blame]
Guido van Rossum778983b1993-02-19 15:55:02 +00001/* Array object implementation */
2
3/* An array is a uniform list -- all items have the same type.
4 The item type is restricted to simple C types like int or float */
5
Martin v. Löwis18e16552006-02-15 17:27:45 +00006#define PY_SSIZE_T_CLEAN
Roger E. Masse2919eaa1996-12-09 20:10:36 +00007#include "Python.h"
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01008#include "structmember.h" // PyMemberDef
Victor Stinner4a21e572020-04-15 02:35:41 +02009#include <stddef.h> // offsetof()
Roger E. Masse5817f8f1996-12-09 22:24:19 +000010
Guido van Rossum0c709541994-08-19 12:01:32 +000011#ifdef STDC_HEADERS
12#include <stddef.h>
Guido van Rossum7f1de831999-08-27 20:33:52 +000013#else /* !STDC_HEADERS */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000014#ifdef HAVE_SYS_TYPES_H
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000015#include <sys/types.h> /* For size_t */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000016#endif /* HAVE_SYS_TYPES_H */
Guido van Rossum7f1de831999-08-27 20:33:52 +000017#endif /* !STDC_HEADERS */
Guido van Rossum778983b1993-02-19 15:55:02 +000018
Brett Cannon1eb32c22014-10-10 16:26:45 -040019/*[clinic input]
Brett Cannon1eb32c22014-10-10 16:26:45 -040020module array
21[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030022/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7d1b8d7f5958fd83]*/
Brett Cannon1eb32c22014-10-10 16:26:45 -040023
Guido van Rossum778983b1993-02-19 15:55:02 +000024struct arrayobject; /* Forward */
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +010025static struct PyModuleDef arraymodule;
Guido van Rossum778983b1993-02-19 15:55:02 +000026
Tim Petersbb307342000-09-10 05:22:54 +000027/* All possible arraydescr values are defined in the vector "descriptors"
28 * below. That's defined later because the appropriate get and set
29 * functions aren't visible yet.
30 */
Guido van Rossum778983b1993-02-19 15:55:02 +000031struct arraydescr {
Victor Stinnerf8bb7d02011-09-30 00:03:59 +020032 char typecode;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000033 int itemsize;
34 PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
35 int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
Adrian Wielgosik7c17e232017-08-17 12:46:06 +000036 int (*compareitems)(const void *, const void *, Py_ssize_t);
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020037 const char *formats;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000038 int is_integer_type;
39 int is_signed;
Guido van Rossum778983b1993-02-19 15:55:02 +000040};
41
42typedef struct arrayobject {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043 PyObject_VAR_HEAD
44 char *ob_item;
45 Py_ssize_t allocated;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020046 const struct arraydescr *ob_descr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000047 PyObject *weakreflist; /* List of weak references */
Hai Shi06cd5b62019-10-21 14:31:46 +080048 Py_ssize_t ob_exports; /* Number of exported buffers */
Guido van Rossum778983b1993-02-19 15:55:02 +000049} arrayobject;
50
Brett Cannon1eb32c22014-10-10 16:26:45 -040051typedef struct {
52 PyObject_HEAD
53 Py_ssize_t index;
54 arrayobject *ao;
55 PyObject* (*getitem)(struct arrayobject *, Py_ssize_t);
56} arrayiterobject;
57
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +010058typedef struct {
59 PyTypeObject *ArrayType;
60 PyTypeObject *ArrayIterType;
61} array_state;
Brett Cannon1eb32c22014-10-10 16:26:45 -040062
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +010063static array_state *
64get_array_state(PyObject *module)
65{
66 return (array_state *)PyModule_GetState(module);
67}
68
69#define find_array_state_by_type(tp) \
70 (get_array_state(_PyType_GetModuleByDef(tp, &arraymodule)))
71#define get_array_state_by_class(cls) \
72 (get_array_state(PyType_GetModule(cls)))
Brett Cannon1eb32c22014-10-10 16:26:45 -040073
Larry Hastingsdfbeb162014-10-13 10:39:41 +010074enum machine_format_code {
75 UNKNOWN_FORMAT = -1,
76 /* UNKNOWN_FORMAT is used to indicate that the machine format for an
77 * array type code cannot be interpreted. When this occurs, a list of
78 * Python objects is used to represent the content of the array
79 * instead of using the memory content of the array directly. In that
80 * case, the array_reconstructor mechanism is bypassed completely, and
81 * the standard array constructor is used instead.
82 *
83 * This is will most likely occur when the machine doesn't use IEEE
84 * floating-point numbers.
85 */
86
87 UNSIGNED_INT8 = 0,
88 SIGNED_INT8 = 1,
89 UNSIGNED_INT16_LE = 2,
90 UNSIGNED_INT16_BE = 3,
91 SIGNED_INT16_LE = 4,
92 SIGNED_INT16_BE = 5,
93 UNSIGNED_INT32_LE = 6,
94 UNSIGNED_INT32_BE = 7,
95 SIGNED_INT32_LE = 8,
96 SIGNED_INT32_BE = 9,
97 UNSIGNED_INT64_LE = 10,
98 UNSIGNED_INT64_BE = 11,
99 SIGNED_INT64_LE = 12,
100 SIGNED_INT64_BE = 13,
101 IEEE_754_FLOAT_LE = 14,
102 IEEE_754_FLOAT_BE = 15,
103 IEEE_754_DOUBLE_LE = 16,
104 IEEE_754_DOUBLE_BE = 17,
105 UTF16_LE = 18,
106 UTF16_BE = 19,
107 UTF32_LE = 20,
108 UTF32_BE = 21
109};
110#define MACHINE_FORMAT_CODE_MIN 0
111#define MACHINE_FORMAT_CODE_MAX 21
112
113
114/*
115 * Must come after arrayobject, arrayiterobject,
116 * and enum machine_code_type definitions.
117 */
Brett Cannon1eb32c22014-10-10 16:26:45 -0400118#include "clinic/arraymodule.c.h"
119
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100120#define array_Check(op, state) PyObject_TypeCheck(op, state->ArrayType)
Guido van Rossum778983b1993-02-19 15:55:02 +0000121
Raymond Hettinger6e2ee862004-03-14 04:37:50 +0000122static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000123array_resize(arrayobject *self, Py_ssize_t newsize)
Raymond Hettinger6e2ee862004-03-14 04:37:50 +0000124{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 char *items;
126 size_t _new_size;
Raymond Hettinger6e2ee862004-03-14 04:37:50 +0000127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000128 if (self->ob_exports > 0 && newsize != Py_SIZE(self)) {
129 PyErr_SetString(PyExc_BufferError,
130 "cannot resize an array that is exporting buffers");
131 return -1;
132 }
Antoine Pitrou3ad3a0d2008-12-18 17:08:32 +0000133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 /* Bypass realloc() when a previous overallocation is large enough
135 to accommodate the newsize. If the newsize is 16 smaller than the
136 current size, then proceed with the realloc() to shrink the array.
137 */
Raymond Hettinger6e2ee862004-03-14 04:37:50 +0000138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 if (self->allocated >= newsize &&
140 Py_SIZE(self) < newsize + 16 &&
141 self->ob_item != NULL) {
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100142 Py_SET_SIZE(self, newsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000143 return 0;
144 }
Raymond Hettinger6e2ee862004-03-14 04:37:50 +0000145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146 if (newsize == 0) {
Victor Stinner00d7abd2020-12-01 09:56:42 +0100147 PyMem_Free(self->ob_item);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 self->ob_item = NULL;
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100149 Py_SET_SIZE(self, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 self->allocated = 0;
151 return 0;
152 }
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 /* This over-allocates proportional to the array size, making room
155 * for additional growth. The over-allocation is mild, but is
156 * enough to give linear-time amortized behavior over a long
157 * sequence of appends() in the presence of a poorly-performing
158 * system realloc().
159 * The growth pattern is: 0, 4, 8, 16, 25, 34, 46, 56, 67, 79, ...
160 * Note, the pattern starts out the same as for lists but then
161 * grows at a smaller rate so that larger arrays only overallocate
162 * by about 1/16th -- this is done because arrays are presumed to be more
163 * memory critical.
164 */
Raymond Hettinger6e2ee862004-03-14 04:37:50 +0000165
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 _new_size = (newsize >> 4) + (Py_SIZE(self) < 8 ? 3 : 7) + newsize;
167 items = self->ob_item;
168 /* XXX The following multiplication and division does not optimize away
169 like it does for lists since the size is not known at compile time */
170 if (_new_size <= ((~(size_t)0) / self->ob_descr->itemsize))
171 PyMem_RESIZE(items, char, (_new_size * self->ob_descr->itemsize));
172 else
173 items = NULL;
174 if (items == NULL) {
175 PyErr_NoMemory();
176 return -1;
177 }
178 self->ob_item = items;
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100179 Py_SET_SIZE(self, newsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 self->allocated = _new_size;
181 return 0;
Raymond Hettinger6e2ee862004-03-14 04:37:50 +0000182}
183
Tim Petersbb307342000-09-10 05:22:54 +0000184/****************************************************************************
185Get and Set functions for each type.
186A Get function takes an arrayobject* and an integer index, returning the
187array value at that index wrapped in an appropriate PyObject*.
188A Set function takes an arrayobject, integer index, and PyObject*; sets
189the array value at that index to the raw C data extracted from the PyObject*,
190and returns 0 if successful, else nonzero on failure (PyObject* not of an
191appropriate type or value).
192Note that the basic Get and Set functions do NOT check that the index is
193in bounds; that's the responsibility of the caller.
194****************************************************************************/
Guido van Rossum778983b1993-02-19 15:55:02 +0000195
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000196static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000197b_getitem(arrayobject *ap, Py_ssize_t i)
Guido van Rossum778983b1993-02-19 15:55:02 +0000198{
Disconnect3d13ab5702019-07-11 23:57:42 +0200199 long x = ((signed char *)ap->ob_item)[i];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 return PyLong_FromLong(x);
Guido van Rossum778983b1993-02-19 15:55:02 +0000201}
202
203static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000204b_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 short x;
207 /* PyArg_Parse's 'b' formatter is for an unsigned char, therefore
208 must use the next size up that is signed ('h') and manually do
209 the overflow checking */
210 if (!PyArg_Parse(v, "h;array item must be integer", &x))
211 return -1;
212 else if (x < -128) {
213 PyErr_SetString(PyExc_OverflowError,
214 "signed char is less than minimum");
215 return -1;
216 }
217 else if (x > 127) {
218 PyErr_SetString(PyExc_OverflowError,
219 "signed char is greater than maximum");
220 return -1;
221 }
222 if (i >= 0)
223 ((char *)ap->ob_item)[i] = (char)x;
224 return 0;
Guido van Rossum778983b1993-02-19 15:55:02 +0000225}
226
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000227static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000228BB_getitem(arrayobject *ap, Py_ssize_t i)
Guido van Rossum549ab711997-01-03 19:09:47 +0000229{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 long x = ((unsigned char *)ap->ob_item)[i];
231 return PyLong_FromLong(x);
Guido van Rossum549ab711997-01-03 19:09:47 +0000232}
233
Fred Drake541dc3b2000-06-28 17:49:30 +0000234static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000235BB_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
Fred Drake541dc3b2000-06-28 17:49:30 +0000236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 unsigned char x;
238 /* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */
239 if (!PyArg_Parse(v, "b;array item must be integer", &x))
240 return -1;
241 if (i >= 0)
242 ((char *)ap->ob_item)[i] = x;
243 return 0;
Fred Drake541dc3b2000-06-28 17:49:30 +0000244}
Guido van Rossum549ab711997-01-03 19:09:47 +0000245
Martin v. Löwis99866332002-03-01 10:27:01 +0000246static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000247u_getitem(arrayobject *ap, Py_ssize_t i)
Martin v. Löwis99866332002-03-01 10:27:01 +0000248{
Inada Naokid5d9a712020-05-11 15:37:25 +0900249 return PyUnicode_FromOrdinal(((wchar_t *) ap->ob_item)[i]);
Martin v. Löwis99866332002-03-01 10:27:01 +0000250}
251
252static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000253u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
Martin v. Löwis99866332002-03-01 10:27:01 +0000254{
Inada Naokid5d9a712020-05-11 15:37:25 +0900255 PyObject *u;
256 if (!PyArg_Parse(v, "U;array item must be unicode character", &u)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 return -1;
Inada Naokid5d9a712020-05-11 15:37:25 +0900258 }
259
260 Py_ssize_t len = PyUnicode_AsWideChar(u, NULL, 0);
261 if (len != 2) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 PyErr_SetString(PyExc_TypeError,
263 "array item must be unicode character");
264 return -1;
265 }
Inada Naokid5d9a712020-05-11 15:37:25 +0900266
267 wchar_t w;
268 len = PyUnicode_AsWideChar(u, &w, 1);
269 assert(len == 1);
270
271 if (i >= 0) {
272 ((wchar_t *)ap->ob_item)[i] = w;
273 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 return 0;
Martin v. Löwis99866332002-03-01 10:27:01 +0000275}
Martin v. Löwis99866332002-03-01 10:27:01 +0000276
Travis E. Oliphantd5c0add2007-10-12 22:05:15 +0000277
Guido van Rossum549ab711997-01-03 19:09:47 +0000278static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000279h_getitem(arrayobject *ap, Py_ssize_t i)
Guido van Rossum778983b1993-02-19 15:55:02 +0000280{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 return PyLong_FromLong((long) ((short *)ap->ob_item)[i]);
Guido van Rossum778983b1993-02-19 15:55:02 +0000282}
283
Travis E. Oliphantd5c0add2007-10-12 22:05:15 +0000284
Guido van Rossum778983b1993-02-19 15:55:02 +0000285static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000286h_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 short x;
289 /* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */
290 if (!PyArg_Parse(v, "h;array item must be integer", &x))
291 return -1;
292 if (i >= 0)
293 ((short *)ap->ob_item)[i] = x;
294 return 0;
Guido van Rossum778983b1993-02-19 15:55:02 +0000295}
296
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000297static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000298HH_getitem(arrayobject *ap, Py_ssize_t i)
Guido van Rossum549ab711997-01-03 19:09:47 +0000299{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 return PyLong_FromLong((long) ((unsigned short *)ap->ob_item)[i]);
Guido van Rossum549ab711997-01-03 19:09:47 +0000301}
302
Fred Drake541dc3b2000-06-28 17:49:30 +0000303static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000304HH_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
Fred Drake541dc3b2000-06-28 17:49:30 +0000305{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 int x;
307 /* PyArg_Parse's 'h' formatter is for a signed short, therefore
308 must use the next size up and manually do the overflow checking */
309 if (!PyArg_Parse(v, "i;array item must be integer", &x))
310 return -1;
311 else if (x < 0) {
312 PyErr_SetString(PyExc_OverflowError,
313 "unsigned short is less than minimum");
314 return -1;
315 }
316 else if (x > USHRT_MAX) {
317 PyErr_SetString(PyExc_OverflowError,
318 "unsigned short is greater than maximum");
319 return -1;
320 }
321 if (i >= 0)
322 ((short *)ap->ob_item)[i] = (short)x;
323 return 0;
Fred Drake541dc3b2000-06-28 17:49:30 +0000324}
Guido van Rossum549ab711997-01-03 19:09:47 +0000325
326static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000327i_getitem(arrayobject *ap, Py_ssize_t i)
Guido van Rossume77a7571993-11-03 15:01:26 +0000328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 return PyLong_FromLong((long) ((int *)ap->ob_item)[i]);
Guido van Rossume77a7571993-11-03 15:01:26 +0000330}
331
332static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000333i_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
Guido van Rossume77a7571993-11-03 15:01:26 +0000334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 int x;
336 /* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */
337 if (!PyArg_Parse(v, "i;array item must be integer", &x))
338 return -1;
339 if (i >= 0)
340 ((int *)ap->ob_item)[i] = x;
341 return 0;
Guido van Rossume77a7571993-11-03 15:01:26 +0000342}
343
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000344static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000345II_getitem(arrayobject *ap, Py_ssize_t i)
Guido van Rossum549ab711997-01-03 19:09:47 +0000346{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 return PyLong_FromUnsignedLong(
348 (unsigned long) ((unsigned int *)ap->ob_item)[i]);
Guido van Rossum549ab711997-01-03 19:09:47 +0000349}
350
351static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000352II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
Guido van Rossum549ab711997-01-03 19:09:47 +0000353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 unsigned long x;
orenmn964281a2017-03-09 11:35:28 +0200355 int do_decref = 0; /* if nb_int was called */
356
357 if (!PyLong_Check(v)) {
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300358 v = _PyNumber_Index(v);
orenmn964281a2017-03-09 11:35:28 +0200359 if (NULL == v) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 return -1;
361 }
orenmn964281a2017-03-09 11:35:28 +0200362 do_decref = 1;
363 }
364 x = PyLong_AsUnsignedLong(v);
365 if (x == (unsigned long)-1 && PyErr_Occurred()) {
366 if (do_decref) {
367 Py_DECREF(v);
368 }
369 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 }
371 if (x > UINT_MAX) {
372 PyErr_SetString(PyExc_OverflowError,
orenmn964281a2017-03-09 11:35:28 +0200373 "unsigned int is greater than maximum");
374 if (do_decref) {
375 Py_DECREF(v);
376 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 return -1;
378 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 if (i >= 0)
380 ((unsigned int *)ap->ob_item)[i] = (unsigned int)x;
orenmn964281a2017-03-09 11:35:28 +0200381
382 if (do_decref) {
383 Py_DECREF(v);
384 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 return 0;
Guido van Rossum549ab711997-01-03 19:09:47 +0000386}
387
388static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000389l_getitem(arrayobject *ap, Py_ssize_t i)
Guido van Rossum778983b1993-02-19 15:55:02 +0000390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 return PyLong_FromLong(((long *)ap->ob_item)[i]);
Guido van Rossum778983b1993-02-19 15:55:02 +0000392}
393
394static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000395l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000396{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 long x;
398 if (!PyArg_Parse(v, "l;array item must be integer", &x))
399 return -1;
400 if (i >= 0)
401 ((long *)ap->ob_item)[i] = x;
402 return 0;
Guido van Rossum778983b1993-02-19 15:55:02 +0000403}
404
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000405static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000406LL_getitem(arrayobject *ap, Py_ssize_t i)
Guido van Rossum549ab711997-01-03 19:09:47 +0000407{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]);
Guido van Rossum549ab711997-01-03 19:09:47 +0000409}
410
411static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000412LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
Guido van Rossum549ab711997-01-03 19:09:47 +0000413{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 unsigned long x;
orenmn964281a2017-03-09 11:35:28 +0200415 int do_decref = 0; /* if nb_int was called */
416
417 if (!PyLong_Check(v)) {
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300418 v = _PyNumber_Index(v);
orenmn964281a2017-03-09 11:35:28 +0200419 if (NULL == v) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 return -1;
421 }
orenmn964281a2017-03-09 11:35:28 +0200422 do_decref = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 }
orenmn964281a2017-03-09 11:35:28 +0200424 x = PyLong_AsUnsignedLong(v);
425 if (x == (unsigned long)-1 && PyErr_Occurred()) {
426 if (do_decref) {
427 Py_DECREF(v);
428 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 return -1;
430 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 if (i >= 0)
432 ((unsigned long *)ap->ob_item)[i] = x;
orenmn964281a2017-03-09 11:35:28 +0200433
434 if (do_decref) {
435 Py_DECREF(v);
436 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 return 0;
Guido van Rossum549ab711997-01-03 19:09:47 +0000438}
439
Meador Inge1c9f0c92011-09-20 19:55:51 -0500440static PyObject *
441q_getitem(arrayobject *ap, Py_ssize_t i)
442{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700443 return PyLong_FromLongLong(((long long *)ap->ob_item)[i]);
Meador Inge1c9f0c92011-09-20 19:55:51 -0500444}
445
446static int
447q_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
448{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700449 long long x;
Meador Inge1c9f0c92011-09-20 19:55:51 -0500450 if (!PyArg_Parse(v, "L;array item must be integer", &x))
451 return -1;
452 if (i >= 0)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700453 ((long long *)ap->ob_item)[i] = x;
Meador Inge1c9f0c92011-09-20 19:55:51 -0500454 return 0;
455}
456
457static PyObject *
458QQ_getitem(arrayobject *ap, Py_ssize_t i)
459{
460 return PyLong_FromUnsignedLongLong(
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700461 ((unsigned long long *)ap->ob_item)[i]);
Meador Inge1c9f0c92011-09-20 19:55:51 -0500462}
463
464static int
465QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
466{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700467 unsigned long long x;
orenmn964281a2017-03-09 11:35:28 +0200468 int do_decref = 0; /* if nb_int was called */
469
470 if (!PyLong_Check(v)) {
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300471 v = _PyNumber_Index(v);
orenmn964281a2017-03-09 11:35:28 +0200472 if (NULL == v) {
Meador Inge1c9f0c92011-09-20 19:55:51 -0500473 return -1;
474 }
orenmn964281a2017-03-09 11:35:28 +0200475 do_decref = 1;
Meador Inge1c9f0c92011-09-20 19:55:51 -0500476 }
orenmn964281a2017-03-09 11:35:28 +0200477 x = PyLong_AsUnsignedLongLong(v);
478 if (x == (unsigned long long)-1 && PyErr_Occurred()) {
479 if (do_decref) {
480 Py_DECREF(v);
481 }
482 return -1;
483 }
Meador Inge1c9f0c92011-09-20 19:55:51 -0500484 if (i >= 0)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700485 ((unsigned long long *)ap->ob_item)[i] = x;
orenmn964281a2017-03-09 11:35:28 +0200486
487 if (do_decref) {
488 Py_DECREF(v);
489 }
Meador Inge1c9f0c92011-09-20 19:55:51 -0500490 return 0;
491}
Meador Inge1c9f0c92011-09-20 19:55:51 -0500492
Guido van Rossum549ab711997-01-03 19:09:47 +0000493static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000494f_getitem(arrayobject *ap, Py_ssize_t i)
Guido van Rossum778983b1993-02-19 15:55:02 +0000495{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]);
Guido van Rossum778983b1993-02-19 15:55:02 +0000497}
498
499static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000500f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 float x;
503 if (!PyArg_Parse(v, "f;array item must be float", &x))
504 return -1;
505 if (i >= 0)
506 ((float *)ap->ob_item)[i] = x;
507 return 0;
Guido van Rossum778983b1993-02-19 15:55:02 +0000508}
509
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000510static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000511d_getitem(arrayobject *ap, Py_ssize_t i)
Guido van Rossum778983b1993-02-19 15:55:02 +0000512{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 return PyFloat_FromDouble(((double *)ap->ob_item)[i]);
Guido van Rossum778983b1993-02-19 15:55:02 +0000514}
515
516static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000517d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000518{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 double x;
520 if (!PyArg_Parse(v, "d;array item must be float", &x))
521 return -1;
522 if (i >= 0)
523 ((double *)ap->ob_item)[i] = x;
524 return 0;
Guido van Rossum778983b1993-02-19 15:55:02 +0000525}
526
Adrian Wielgosik7c17e232017-08-17 12:46:06 +0000527#define DEFINE_COMPAREITEMS(code, type) \
528 static int \
529 code##_compareitems(const void *lhs, const void *rhs, Py_ssize_t length) \
530 { \
531 const type *a = lhs, *b = rhs; \
532 for (Py_ssize_t i = 0; i < length; ++i) \
533 if (a[i] != b[i]) \
534 return a[i] < b[i] ? -1 : 1; \
535 return 0; \
536 }
537
538DEFINE_COMPAREITEMS(b, signed char)
539DEFINE_COMPAREITEMS(BB, unsigned char)
Inada Naokid5d9a712020-05-11 15:37:25 +0900540DEFINE_COMPAREITEMS(u, wchar_t)
Adrian Wielgosik7c17e232017-08-17 12:46:06 +0000541DEFINE_COMPAREITEMS(h, short)
542DEFINE_COMPAREITEMS(HH, unsigned short)
543DEFINE_COMPAREITEMS(i, int)
544DEFINE_COMPAREITEMS(II, unsigned int)
545DEFINE_COMPAREITEMS(l, long)
546DEFINE_COMPAREITEMS(LL, unsigned long)
547DEFINE_COMPAREITEMS(q, long long)
548DEFINE_COMPAREITEMS(QQ, unsigned long long)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000549
Alexandre Vassalottiad077152009-07-15 17:49:23 +0000550/* Description of types.
551 *
552 * Don't forget to update typecode_to_mformat_code() if you add a new
553 * typecode.
554 */
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200555static const struct arraydescr descriptors[] = {
Adrian Wielgosik7c17e232017-08-17 12:46:06 +0000556 {'b', 1, b_getitem, b_setitem, b_compareitems, "b", 1, 1},
557 {'B', 1, BB_getitem, BB_setitem, BB_compareitems, "B", 1, 0},
Inada Naokid5d9a712020-05-11 15:37:25 +0900558 {'u', sizeof(wchar_t), u_getitem, u_setitem, u_compareitems, "u", 0, 0},
Adrian Wielgosik7c17e232017-08-17 12:46:06 +0000559 {'h', sizeof(short), h_getitem, h_setitem, h_compareitems, "h", 1, 1},
560 {'H', sizeof(short), HH_getitem, HH_setitem, HH_compareitems, "H", 1, 0},
561 {'i', sizeof(int), i_getitem, i_setitem, i_compareitems, "i", 1, 1},
562 {'I', sizeof(int), II_getitem, II_setitem, II_compareitems, "I", 1, 0},
563 {'l', sizeof(long), l_getitem, l_setitem, l_compareitems, "l", 1, 1},
564 {'L', sizeof(long), LL_getitem, LL_setitem, LL_compareitems, "L", 1, 0},
565 {'q', sizeof(long long), q_getitem, q_setitem, q_compareitems, "q", 1, 1},
566 {'Q', sizeof(long long), QQ_getitem, QQ_setitem, QQ_compareitems, "Q", 1, 0},
567 {'f', sizeof(float), f_getitem, f_setitem, NULL, "f", 0, 0},
568 {'d', sizeof(double), d_getitem, d_setitem, NULL, "d", 0, 0},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 {'\0', 0, 0, 0, 0, 0, 0} /* Sentinel */
Guido van Rossum778983b1993-02-19 15:55:02 +0000570};
Tim Petersbb307342000-09-10 05:22:54 +0000571
572/****************************************************************************
573Implementations of array object methods.
574****************************************************************************/
Brett Cannon1eb32c22014-10-10 16:26:45 -0400575/*[clinic input]
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100576class array.array "arrayobject *" "ArrayType"
Brett Cannon1eb32c22014-10-10 16:26:45 -0400577[clinic start generated code]*/
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100578/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a5c29edf59f176a3]*/
Guido van Rossum778983b1993-02-19 15:55:02 +0000579
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000580static PyObject *
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200581newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr)
Guido van Rossum778983b1993-02-19 15:55:02 +0000582{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 arrayobject *op;
584 size_t nbytes;
Martin v. Löwis99866332002-03-01 10:27:01 +0000585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 if (size < 0) {
587 PyErr_BadInternalCall();
588 return NULL;
589 }
Martin v. Löwis99866332002-03-01 10:27:01 +0000590
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 /* Check for overflow */
Mark Dickinsonc04ddff2012-10-06 18:04:49 +0100592 if (size > PY_SSIZE_T_MAX / descr->itemsize) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 return PyErr_NoMemory();
594 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +0100595 nbytes = size * descr->itemsize;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000596 op = (arrayobject *) type->tp_alloc(type, 0);
597 if (op == NULL) {
598 return NULL;
599 }
600 op->ob_descr = descr;
601 op->allocated = size;
602 op->weakreflist = NULL;
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100603 Py_SET_SIZE(op, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 if (size <= 0) {
605 op->ob_item = NULL;
606 }
607 else {
608 op->ob_item = PyMem_NEW(char, nbytes);
609 if (op->ob_item == NULL) {
610 Py_DECREF(op);
611 return PyErr_NoMemory();
612 }
613 }
614 op->ob_exports = 0;
615 return (PyObject *) op;
Guido van Rossum778983b1993-02-19 15:55:02 +0000616}
617
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000618static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000619getarrayitem(PyObject *op, Py_ssize_t i)
Guido van Rossum778983b1993-02-19 15:55:02 +0000620{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100621#ifndef NDEBUG
622 array_state *state = find_array_state_by_type(Py_TYPE(op));
623 assert(array_Check(op, state));
624#endif
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200625 arrayobject *ap;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 ap = (arrayobject *)op;
627 assert(i>=0 && i<Py_SIZE(ap));
628 return (*ap->ob_descr->getitem)(ap, i);
Guido van Rossum778983b1993-02-19 15:55:02 +0000629}
630
631static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000632ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000633{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 char *items;
635 Py_ssize_t n = Py_SIZE(self);
636 if (v == NULL) {
637 PyErr_BadInternalCall();
638 return -1;
639 }
640 if ((*self->ob_descr->setitem)(self, -1, v) < 0)
641 return -1;
Raymond Hettinger6e2ee862004-03-14 04:37:50 +0000642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 if (array_resize(self, n+1) == -1)
644 return -1;
645 items = self->ob_item;
646 if (where < 0) {
647 where += n;
648 if (where < 0)
649 where = 0;
650 }
651 if (where > n)
652 where = n;
653 /* appends don't need to call memmove() */
654 if (where != n)
655 memmove(items + (where+1)*self->ob_descr->itemsize,
656 items + where*self->ob_descr->itemsize,
657 (n-where)*self->ob_descr->itemsize);
658 return (*self->ob_descr->setitem)(self, where, v);
Guido van Rossum778983b1993-02-19 15:55:02 +0000659}
660
Guido van Rossum778983b1993-02-19 15:55:02 +0000661/* Methods */
662
663static void
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000664array_dealloc(arrayobject *op)
Guido van Rossum778983b1993-02-19 15:55:02 +0000665{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100666 PyTypeObject *tp = Py_TYPE(op);
667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668 if (op->weakreflist != NULL)
669 PyObject_ClearWeakRefs((PyObject *) op);
670 if (op->ob_item != NULL)
Victor Stinner00d7abd2020-12-01 09:56:42 +0100671 PyMem_Free(op->ob_item);
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100672 tp->tp_free(op);
673 Py_DECREF(tp);
Guido van Rossum778983b1993-02-19 15:55:02 +0000674}
675
Guido van Rossum9d19cb82001-01-18 01:02:55 +0000676static PyObject *
677array_richcompare(PyObject *v, PyObject *w, int op)
Guido van Rossum778983b1993-02-19 15:55:02 +0000678{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100679 array_state *state = find_array_state_by_type(Py_TYPE(v));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 arrayobject *va, *wa;
681 PyObject *vi = NULL;
682 PyObject *wi = NULL;
683 Py_ssize_t i, k;
684 PyObject *res;
Guido van Rossum9d19cb82001-01-18 01:02:55 +0000685
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100686 if (!array_Check(v, state) || !array_Check(w, state))
Brian Curtindfc80e32011-08-10 20:28:54 -0500687 Py_RETURN_NOTIMPLEMENTED;
Guido van Rossum9d19cb82001-01-18 01:02:55 +0000688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000689 va = (arrayobject *)v;
690 wa = (arrayobject *)w;
Guido van Rossum9d19cb82001-01-18 01:02:55 +0000691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 if (Py_SIZE(va) != Py_SIZE(wa) && (op == Py_EQ || op == Py_NE)) {
693 /* Shortcut: if the lengths differ, the arrays differ */
694 if (op == Py_EQ)
695 res = Py_False;
696 else
697 res = Py_True;
698 Py_INCREF(res);
699 return res;
700 }
Guido van Rossum9d19cb82001-01-18 01:02:55 +0000701
Adrian Wielgosik7c17e232017-08-17 12:46:06 +0000702 if (va->ob_descr == wa->ob_descr && va->ob_descr->compareitems != NULL) {
703 /* Fast path:
704 arrays with same types can have their buffers compared directly */
705 Py_ssize_t common_length = Py_MIN(Py_SIZE(va), Py_SIZE(wa));
706 int result = va->ob_descr->compareitems(va->ob_item, wa->ob_item,
707 common_length);
708 if (result == 0)
709 goto compare_sizes;
710
711 int cmp;
712 switch (op) {
713 case Py_LT: cmp = result < 0; break;
714 case Py_LE: cmp = result <= 0; break;
715 case Py_EQ: cmp = result == 0; break;
716 case Py_NE: cmp = result != 0; break;
717 case Py_GT: cmp = result > 0; break;
718 case Py_GE: cmp = result >= 0; break;
719 default: return NULL; /* cannot happen */
720 }
721 PyObject *res = cmp ? Py_True : Py_False;
722 Py_INCREF(res);
723 return res;
724 }
725
726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 /* Search for the first index where items are different */
728 k = 1;
729 for (i = 0; i < Py_SIZE(va) && i < Py_SIZE(wa); i++) {
730 vi = getarrayitem(v, i);
731 wi = getarrayitem(w, i);
732 if (vi == NULL || wi == NULL) {
733 Py_XDECREF(vi);
734 Py_XDECREF(wi);
735 return NULL;
736 }
737 k = PyObject_RichCompareBool(vi, wi, Py_EQ);
738 if (k == 0)
739 break; /* Keeping vi and wi alive! */
740 Py_DECREF(vi);
741 Py_DECREF(wi);
742 if (k < 0)
743 return NULL;
744 }
Guido van Rossum9d19cb82001-01-18 01:02:55 +0000745
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 if (k) {
747 /* No more items to compare -- compare sizes */
Adrian Wielgosik7c17e232017-08-17 12:46:06 +0000748 compare_sizes: ;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 Py_ssize_t vs = Py_SIZE(va);
750 Py_ssize_t ws = Py_SIZE(wa);
751 int cmp;
752 switch (op) {
753 case Py_LT: cmp = vs < ws; break;
754 case Py_LE: cmp = vs <= ws; break;
Adrian Wielgosik7c17e232017-08-17 12:46:06 +0000755 /* If the lengths were not equal,
756 the earlier fast-path check would have caught that. */
757 case Py_EQ: assert(vs == ws); cmp = 1; break;
758 case Py_NE: assert(vs == ws); cmp = 0; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 case Py_GT: cmp = vs > ws; break;
760 case Py_GE: cmp = vs >= ws; break;
761 default: return NULL; /* cannot happen */
762 }
763 if (cmp)
764 res = Py_True;
765 else
766 res = Py_False;
767 Py_INCREF(res);
768 return res;
769 }
Guido van Rossum9d19cb82001-01-18 01:02:55 +0000770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000771 /* We have an item that differs. First, shortcuts for EQ/NE */
772 if (op == Py_EQ) {
773 Py_INCREF(Py_False);
774 res = Py_False;
775 }
776 else if (op == Py_NE) {
777 Py_INCREF(Py_True);
778 res = Py_True;
779 }
780 else {
781 /* Compare the final item again using the proper operator */
782 res = PyObject_RichCompare(vi, wi, op);
783 }
784 Py_DECREF(vi);
785 Py_DECREF(wi);
786 return res;
Guido van Rossum778983b1993-02-19 15:55:02 +0000787}
788
Martin v. Löwis18e16552006-02-15 17:27:45 +0000789static Py_ssize_t
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000790array_length(arrayobject *a)
Guido van Rossum778983b1993-02-19 15:55:02 +0000791{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 return Py_SIZE(a);
Guido van Rossum778983b1993-02-19 15:55:02 +0000793}
794
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000795static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000796array_item(arrayobject *a, Py_ssize_t i)
Guido van Rossum778983b1993-02-19 15:55:02 +0000797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 if (i < 0 || i >= Py_SIZE(a)) {
799 PyErr_SetString(PyExc_IndexError, "array index out of range");
800 return NULL;
801 }
802 return getarrayitem((PyObject *)a, i);
Guido van Rossum778983b1993-02-19 15:55:02 +0000803}
804
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000805static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000806array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
Guido van Rossum778983b1993-02-19 15:55:02 +0000807{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100808 array_state *state = find_array_state_by_type(Py_TYPE(a));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 arrayobject *np;
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100810
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 if (ilow < 0)
812 ilow = 0;
813 else if (ilow > Py_SIZE(a))
814 ilow = Py_SIZE(a);
815 if (ihigh < 0)
816 ihigh = 0;
817 if (ihigh < ilow)
818 ihigh = ilow;
819 else if (ihigh > Py_SIZE(a))
820 ihigh = Py_SIZE(a);
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100821 np = (arrayobject *) newarrayobject(state->ArrayType, ihigh - ilow, a->ob_descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000822 if (np == NULL)
823 return NULL;
Martin Panterbe8da9c2016-09-07 11:04:41 +0000824 if (ihigh > ilow) {
825 memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
826 (ihigh-ilow) * a->ob_descr->itemsize);
827 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000828 return (PyObject *)np;
Guido van Rossum778983b1993-02-19 15:55:02 +0000829}
830
Brett Cannon1eb32c22014-10-10 16:26:45 -0400831
832/*[clinic input]
833array.array.__copy__
834
835Return a copy of the array.
836[clinic start generated code]*/
837
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000838static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -0400839array_array___copy___impl(arrayobject *self)
840/*[clinic end generated code: output=dec7c3f925d9619e input=ad1ee5b086965f09]*/
Raymond Hettinger3aa82c02004-03-13 18:18:51 +0000841{
Brett Cannon1eb32c22014-10-10 16:26:45 -0400842 return array_slice(self, 0, Py_SIZE(self));
Raymond Hettinger3aa82c02004-03-13 18:18:51 +0000843}
844
Brett Cannon1eb32c22014-10-10 16:26:45 -0400845/*[clinic input]
846array.array.__deepcopy__
847
848 unused: object
849 /
850
851Return a copy of the array.
852[clinic start generated code]*/
853
854static PyObject *
855array_array___deepcopy__(arrayobject *self, PyObject *unused)
856/*[clinic end generated code: output=1ec748d8e14a9faa input=2405ecb4933748c4]*/
857{
858 return array_array___copy___impl(self);
859}
Raymond Hettinger3aa82c02004-03-13 18:18:51 +0000860
861static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000862array_concat(arrayobject *a, PyObject *bb)
Guido van Rossum778983b1993-02-19 15:55:02 +0000863{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100864 array_state *state = find_array_state_by_type(Py_TYPE(a));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 Py_ssize_t size;
866 arrayobject *np;
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100867 if (!array_Check(bb, state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 PyErr_Format(PyExc_TypeError,
869 "can only append array (not \"%.200s\") to array",
870 Py_TYPE(bb)->tp_name);
871 return NULL;
872 }
Guido van Rossum778983b1993-02-19 15:55:02 +0000873#define b ((arrayobject *)bb)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000874 if (a->ob_descr != b->ob_descr) {
875 PyErr_BadArgument();
876 return NULL;
877 }
878 if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) {
879 return PyErr_NoMemory();
880 }
881 size = Py_SIZE(a) + Py_SIZE(b);
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100882 np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000883 if (np == NULL) {
884 return NULL;
885 }
Martin Panterbe8da9c2016-09-07 11:04:41 +0000886 if (Py_SIZE(a) > 0) {
887 memcpy(np->ob_item, a->ob_item, Py_SIZE(a)*a->ob_descr->itemsize);
888 }
889 if (Py_SIZE(b) > 0) {
890 memcpy(np->ob_item + Py_SIZE(a)*a->ob_descr->itemsize,
891 b->ob_item, Py_SIZE(b)*b->ob_descr->itemsize);
892 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 return (PyObject *)np;
Guido van Rossum778983b1993-02-19 15:55:02 +0000894#undef b
895}
896
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000897static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +0000898array_repeat(arrayobject *a, Py_ssize_t n)
Guido van Rossum778983b1993-02-19 15:55:02 +0000899{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100900 array_state *state = find_array_state_by_type(Py_TYPE(a));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 Py_ssize_t size;
902 arrayobject *np;
Georg Brandlc29cc6a2010-12-04 11:02:04 +0000903 Py_ssize_t oldbytes, newbytes;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000904 if (n < 0)
905 n = 0;
906 if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) {
907 return PyErr_NoMemory();
908 }
909 size = Py_SIZE(a) * n;
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100910 np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 if (np == NULL)
912 return NULL;
Martin Panterbe8da9c2016-09-07 11:04:41 +0000913 if (size == 0)
Georg Brandlc29cc6a2010-12-04 11:02:04 +0000914 return (PyObject *)np;
915 oldbytes = Py_SIZE(a) * a->ob_descr->itemsize;
916 newbytes = oldbytes * n;
917 /* this follows the code in unicode_repeat */
918 if (oldbytes == 1) {
919 memset(np->ob_item, a->ob_item[0], newbytes);
920 } else {
921 Py_ssize_t done = oldbytes;
Christian Heimesf051e432016-09-13 20:22:02 +0200922 memcpy(np->ob_item, a->ob_item, oldbytes);
Georg Brandlc29cc6a2010-12-04 11:02:04 +0000923 while (done < newbytes) {
924 Py_ssize_t ncopy = (done <= newbytes-done) ? done : newbytes-done;
Christian Heimesf051e432016-09-13 20:22:02 +0200925 memcpy(np->ob_item+done, np->ob_item, ncopy);
Georg Brandlc29cc6a2010-12-04 11:02:04 +0000926 done += ncopy;
927 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928 }
Georg Brandlc29cc6a2010-12-04 11:02:04 +0000929 return (PyObject *)np;
Guido van Rossum778983b1993-02-19 15:55:02 +0000930}
931
932static int
Martin Panter996d72b2016-07-25 02:21:14 +0000933array_del_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
Guido van Rossum778983b1993-02-19 15:55:02 +0000934{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 char *item;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000936 Py_ssize_t d; /* Change in size */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 if (ilow < 0)
938 ilow = 0;
939 else if (ilow > Py_SIZE(a))
940 ilow = Py_SIZE(a);
941 if (ihigh < 0)
942 ihigh = 0;
943 if (ihigh < ilow)
944 ihigh = ilow;
945 else if (ihigh > Py_SIZE(a))
946 ihigh = Py_SIZE(a);
947 item = a->ob_item;
Martin Panter996d72b2016-07-25 02:21:14 +0000948 d = ihigh-ilow;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 /* Issue #4509: If the array has exported buffers and the slice
950 assignment would change the size of the array, fail early to make
951 sure we don't modify it. */
952 if (d != 0 && a->ob_exports > 0) {
953 PyErr_SetString(PyExc_BufferError,
954 "cannot resize an array that is exporting buffers");
955 return -1;
956 }
Martin Panter996d72b2016-07-25 02:21:14 +0000957 if (d > 0) { /* Delete d items */
958 memmove(item + (ihigh-d)*a->ob_descr->itemsize,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 item + ihigh*a->ob_descr->itemsize,
960 (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize);
Martin Panter996d72b2016-07-25 02:21:14 +0000961 if (array_resize(a, Py_SIZE(a) - d) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 return -1;
963 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 return 0;
Guido van Rossum778983b1993-02-19 15:55:02 +0000965}
966
967static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000968array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000969{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970 if (i < 0 || i >= Py_SIZE(a)) {
971 PyErr_SetString(PyExc_IndexError,
972 "array assignment index out of range");
973 return -1;
974 }
975 if (v == NULL)
Martin Panter996d72b2016-07-25 02:21:14 +0000976 return array_del_slice(a, i, i+1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 return (*a->ob_descr->setitem)(a, i, v);
Guido van Rossum778983b1993-02-19 15:55:02 +0000978}
979
980static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000981setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000982{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +0100983#ifndef NDEBUG
984 array_state *state = find_array_state_by_type(Py_TYPE(a));
985 assert(array_Check(a, state));
986#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 return array_ass_item((arrayobject *)a, i, v);
Guido van Rossum778983b1993-02-19 15:55:02 +0000988}
989
Martin v. Löwis99866332002-03-01 10:27:01 +0000990static int
Raymond Hettinger49f9bd12004-03-14 05:43:59 +0000991array_iter_extend(arrayobject *self, PyObject *bb)
992{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 PyObject *it, *v;
Raymond Hettinger49f9bd12004-03-14 05:43:59 +0000994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 it = PyObject_GetIter(bb);
996 if (it == NULL)
997 return -1;
Raymond Hettinger49f9bd12004-03-14 05:43:59 +0000998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 while ((v = PyIter_Next(it)) != NULL) {
Mark Dickinson346f0af2010-08-06 09:36:57 +00001000 if (ins1(self, Py_SIZE(self), v) != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 Py_DECREF(v);
1002 Py_DECREF(it);
1003 return -1;
1004 }
1005 Py_DECREF(v);
1006 }
1007 Py_DECREF(it);
1008 if (PyErr_Occurred())
1009 return -1;
1010 return 0;
Raymond Hettinger49f9bd12004-03-14 05:43:59 +00001011}
1012
1013static int
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001014array_do_extend(array_state *state, arrayobject *self, PyObject *bb)
Martin v. Löwis99866332002-03-01 10:27:01 +00001015{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 Py_ssize_t size, oldsize, bbsize;
Martin v. Löwis99866332002-03-01 10:27:01 +00001017
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001018 if (!array_Check(bb, state))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001019 return array_iter_extend(self, bb);
1020#define b ((arrayobject *)bb)
1021 if (self->ob_descr != b->ob_descr) {
1022 PyErr_SetString(PyExc_TypeError,
1023 "can only extend with array of same kind");
1024 return -1;
1025 }
1026 if ((Py_SIZE(self) > PY_SSIZE_T_MAX - Py_SIZE(b)) ||
1027 ((Py_SIZE(self) + Py_SIZE(b)) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
1028 PyErr_NoMemory();
1029 return -1;
1030 }
1031 oldsize = Py_SIZE(self);
1032 /* Get the size of bb before resizing the array since bb could be self. */
1033 bbsize = Py_SIZE(bb);
1034 size = oldsize + Py_SIZE(b);
1035 if (array_resize(self, size) == -1)
1036 return -1;
Martin Panterbe8da9c2016-09-07 11:04:41 +00001037 if (bbsize > 0) {
1038 memcpy(self->ob_item + oldsize * self->ob_descr->itemsize,
1039 b->ob_item, bbsize * b->ob_descr->itemsize);
1040 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041
1042 return 0;
Martin v. Löwis99866332002-03-01 10:27:01 +00001043#undef b
1044}
1045
1046static PyObject *
1047array_inplace_concat(arrayobject *self, PyObject *bb)
1048{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001049 array_state *state = find_array_state_by_type(Py_TYPE(self));
1050
1051 if (!array_Check(bb, state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 PyErr_Format(PyExc_TypeError,
1053 "can only extend array with array (not \"%.200s\")",
1054 Py_TYPE(bb)->tp_name);
1055 return NULL;
1056 }
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001057 if (array_do_extend(state, self, bb) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 return NULL;
1059 Py_INCREF(self);
1060 return (PyObject *)self;
Martin v. Löwis99866332002-03-01 10:27:01 +00001061}
1062
1063static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +00001064array_inplace_repeat(arrayobject *self, Py_ssize_t n)
Martin v. Löwis99866332002-03-01 10:27:01 +00001065{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 char *items, *p;
1067 Py_ssize_t size, i;
Martin v. Löwis99866332002-03-01 10:27:01 +00001068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 if (Py_SIZE(self) > 0) {
1070 if (n < 0)
1071 n = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 if ((self->ob_descr->itemsize != 0) &&
1073 (Py_SIZE(self) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
1074 return PyErr_NoMemory();
1075 }
1076 size = Py_SIZE(self) * self->ob_descr->itemsize;
1077 if (n > 0 && size > PY_SSIZE_T_MAX / n) {
1078 return PyErr_NoMemory();
1079 }
1080 if (array_resize(self, n * Py_SIZE(self)) == -1)
1081 return NULL;
1082 items = p = self->ob_item;
1083 for (i = 1; i < n; i++) {
1084 p += size;
1085 memcpy(p, items, size);
1086 }
1087 }
1088 Py_INCREF(self);
1089 return (PyObject *)self;
Martin v. Löwis99866332002-03-01 10:27:01 +00001090}
1091
1092
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001093static PyObject *
Martin v. Löwis18e16552006-02-15 17:27:45 +00001094ins(arrayobject *self, Py_ssize_t where, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +00001095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 if (ins1(self, where, v) != 0)
1097 return NULL;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001098 Py_RETURN_NONE;
Guido van Rossum778983b1993-02-19 15:55:02 +00001099}
1100
Brett Cannon1eb32c22014-10-10 16:26:45 -04001101/*[clinic input]
1102array.array.count
1103
1104 v: object
1105 /
1106
1107Return number of occurrences of v in the array.
1108[clinic start generated code]*/
1109
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001110static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001111array_array_count(arrayobject *self, PyObject *v)
1112/*[clinic end generated code: output=3dd3624bf7135a3a input=d9bce9d65e39d1f5]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001113{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 Py_ssize_t count = 0;
1115 Py_ssize_t i;
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 for (i = 0; i < Py_SIZE(self); i++) {
Victor Stinner0b142e22013-07-17 23:01:30 +02001118 PyObject *selfi;
1119 int cmp;
1120
1121 selfi = getarrayitem((PyObject *)self, i);
1122 if (selfi == NULL)
1123 return NULL;
1124 cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 Py_DECREF(selfi);
1126 if (cmp > 0)
1127 count++;
1128 else if (cmp < 0)
1129 return NULL;
1130 }
1131 return PyLong_FromSsize_t(count);
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001132}
1133
Brett Cannon1eb32c22014-10-10 16:26:45 -04001134
1135/*[clinic input]
1136array.array.index
1137
1138 v: object
1139 /
1140
1141Return index of first occurrence of v in the array.
1142[clinic start generated code]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001143
1144static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001145array_array_index(arrayobject *self, PyObject *v)
1146/*[clinic end generated code: output=d48498d325602167 input=cf619898c6649d08]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 Py_ssize_t i;
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 for (i = 0; i < Py_SIZE(self); i++) {
Victor Stinner0b142e22013-07-17 23:01:30 +02001151 PyObject *selfi;
1152 int cmp;
1153
1154 selfi = getarrayitem((PyObject *)self, i);
1155 if (selfi == NULL)
1156 return NULL;
1157 cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 Py_DECREF(selfi);
1159 if (cmp > 0) {
WildCard651d3dad52020-06-23 09:21:16 -04001160 return PyLong_FromSsize_t(i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 }
1162 else if (cmp < 0)
1163 return NULL;
1164 }
Jim Fasarakis-Hilliarda4095ef2017-05-29 20:43:39 +03001165 PyErr_SetString(PyExc_ValueError, "array.index(x): x not in array");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 return NULL;
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001167}
1168
Raymond Hettinger625812f2003-01-07 01:58:52 +00001169static int
1170array_contains(arrayobject *self, PyObject *v)
1171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 Py_ssize_t i;
1173 int cmp;
Raymond Hettinger625812f2003-01-07 01:58:52 +00001174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(self); i++) {
1176 PyObject *selfi = getarrayitem((PyObject *)self, i);
Victor Stinner0b142e22013-07-17 23:01:30 +02001177 if (selfi == NULL)
Victor Stinner4755bea2013-07-18 01:12:35 +02001178 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
1180 Py_DECREF(selfi);
1181 }
1182 return cmp;
Raymond Hettinger625812f2003-01-07 01:58:52 +00001183}
1184
Brett Cannon1eb32c22014-10-10 16:26:45 -04001185/*[clinic input]
1186array.array.remove
1187
1188 v: object
1189 /
1190
1191Remove the first occurrence of v in the array.
1192[clinic start generated code]*/
1193
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001194static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001195array_array_remove(arrayobject *self, PyObject *v)
1196/*[clinic end generated code: output=bef06be9fdf9dceb input=0b1e5aed25590027]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001197{
sthaa3ecb82019-03-20 20:49:39 +01001198 Py_ssize_t i;
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 for (i = 0; i < Py_SIZE(self); i++) {
Victor Stinner0b142e22013-07-17 23:01:30 +02001201 PyObject *selfi;
1202 int cmp;
1203
1204 selfi = getarrayitem((PyObject *)self,i);
1205 if (selfi == NULL)
1206 return NULL;
1207 cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 Py_DECREF(selfi);
1209 if (cmp > 0) {
Martin Panter996d72b2016-07-25 02:21:14 +00001210 if (array_del_slice(self, i, i+1) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 return NULL;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001212 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 }
1214 else if (cmp < 0)
1215 return NULL;
1216 }
Jim Fasarakis-Hilliarda4095ef2017-05-29 20:43:39 +03001217 PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in array");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 return NULL;
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001219}
1220
Brett Cannon1eb32c22014-10-10 16:26:45 -04001221/*[clinic input]
1222array.array.pop
1223
1224 i: Py_ssize_t = -1
1225 /
1226
1227Return the i-th element and delete it from the array.
1228
1229i defaults to -1.
1230[clinic start generated code]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001231
1232static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001233array_array_pop_impl(arrayobject *self, Py_ssize_t i)
1234/*[clinic end generated code: output=bc1f0c54fe5308e4 input=8e5feb4c1a11cd44]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001235{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 PyObject *v;
Brett Cannon1eb32c22014-10-10 16:26:45 -04001237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 if (Py_SIZE(self) == 0) {
1239 /* Special-case most common failure cause */
1240 PyErr_SetString(PyExc_IndexError, "pop from empty array");
1241 return NULL;
1242 }
1243 if (i < 0)
1244 i += Py_SIZE(self);
1245 if (i < 0 || i >= Py_SIZE(self)) {
1246 PyErr_SetString(PyExc_IndexError, "pop index out of range");
1247 return NULL;
1248 }
Victor Stinner0b142e22013-07-17 23:01:30 +02001249 v = getarrayitem((PyObject *)self, i);
1250 if (v == NULL)
1251 return NULL;
Martin Panter996d72b2016-07-25 02:21:14 +00001252 if (array_del_slice(self, i, i+1) != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 Py_DECREF(v);
1254 return NULL;
1255 }
1256 return v;
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001257}
1258
Brett Cannon1eb32c22014-10-10 16:26:45 -04001259/*[clinic input]
1260array.array.extend
1261
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001262 cls: defining_class
Brett Cannon1eb32c22014-10-10 16:26:45 -04001263 bb: object
1264 /
1265
1266Append items to the end of the array.
1267[clinic start generated code]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001268
1269static PyObject *
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001270array_array_extend_impl(arrayobject *self, PyTypeObject *cls, PyObject *bb)
1271/*[clinic end generated code: output=e65eb7588f0bc266 input=8eb6817ec4d2cb62]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001272{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001273 array_state *state = get_array_state_by_class(cls);
1274
1275 if (array_do_extend(state, self, bb) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 return NULL;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001277 Py_RETURN_NONE;
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001278}
1279
Brett Cannon1eb32c22014-10-10 16:26:45 -04001280/*[clinic input]
1281array.array.insert
1282
1283 i: Py_ssize_t
1284 v: object
1285 /
1286
1287Insert a new item v into the array before position i.
1288[clinic start generated code]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001289
1290static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001291array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v)
1292/*[clinic end generated code: output=5a3648e278348564 input=5577d1b4383e9313]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001293{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 return ins(self, i, v);
Guido van Rossum778983b1993-02-19 15:55:02 +00001295}
1296
Brett Cannon1eb32c22014-10-10 16:26:45 -04001297/*[clinic input]
1298array.array.buffer_info
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001299
Brett Cannon1eb32c22014-10-10 16:26:45 -04001300Return a tuple (address, length) giving the current memory address and the length in items of the buffer used to hold array's contents.
1301
1302The length should be multiplied by the itemsize attribute to calculate
1303the buffer length in bytes.
1304[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001305
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001306static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001307array_array_buffer_info_impl(arrayobject *self)
1308/*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=a58bae5c6e1ac6a6]*/
Guido van Rossumde4a4ca1997-08-12 14:55:56 +00001309{
Victor Stinner541067a2013-11-14 01:27:12 +01001310 PyObject *retval = NULL, *v;
1311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 retval = PyTuple_New(2);
1313 if (!retval)
1314 return NULL;
Fred Drake541dc3b2000-06-28 17:49:30 +00001315
Victor Stinner541067a2013-11-14 01:27:12 +01001316 v = PyLong_FromVoidPtr(self->ob_item);
1317 if (v == NULL) {
1318 Py_DECREF(retval);
1319 return NULL;
1320 }
1321 PyTuple_SET_ITEM(retval, 0, v);
1322
Serhiy Storchaka9e941d62016-06-23 23:55:34 +03001323 v = PyLong_FromSsize_t(Py_SIZE(self));
Victor Stinner541067a2013-11-14 01:27:12 +01001324 if (v == NULL) {
1325 Py_DECREF(retval);
1326 return NULL;
1327 }
1328 PyTuple_SET_ITEM(retval, 1, v);
Fred Drake541dc3b2000-06-28 17:49:30 +00001329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 return retval;
Guido van Rossumde4a4ca1997-08-12 14:55:56 +00001331}
1332
Brett Cannon1eb32c22014-10-10 16:26:45 -04001333/*[clinic input]
1334array.array.append
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001335
Brett Cannon1eb32c22014-10-10 16:26:45 -04001336 v: object
1337 /
1338
1339Append new value v to the end of the array.
1340[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001341
Guido van Rossumde4a4ca1997-08-12 14:55:56 +00001342static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001343array_array_append(arrayobject *self, PyObject *v)
1344/*[clinic end generated code: output=745a0669bf8db0e2 input=0b98d9d78e78f0fa]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001345{
Mark Dickinson346f0af2010-08-06 09:36:57 +00001346 return ins(self, Py_SIZE(self), v);
Guido van Rossum778983b1993-02-19 15:55:02 +00001347}
1348
Brett Cannon1eb32c22014-10-10 16:26:45 -04001349/*[clinic input]
1350array.array.byteswap
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001351
Brett Cannon1eb32c22014-10-10 16:26:45 -04001352Byteswap all items of the array.
1353
1354If the items in the array are not 1, 2, 4, or 8 bytes in size, RuntimeError is
1355raised.
1356[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001357
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001358static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001359array_array_byteswap_impl(arrayobject *self)
1360/*[clinic end generated code: output=5f8236cbdf0d90b5 input=6a85591b950a0186]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 char *p;
1363 Py_ssize_t i;
Fred Drakebf272981999-12-03 17:15:30 +00001364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 switch (self->ob_descr->itemsize) {
1366 case 1:
1367 break;
1368 case 2:
1369 for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 2) {
1370 char p0 = p[0];
1371 p[0] = p[1];
1372 p[1] = p0;
1373 }
1374 break;
1375 case 4:
1376 for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 4) {
1377 char p0 = p[0];
1378 char p1 = p[1];
1379 p[0] = p[3];
1380 p[1] = p[2];
1381 p[2] = p1;
1382 p[3] = p0;
1383 }
1384 break;
1385 case 8:
1386 for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 8) {
1387 char p0 = p[0];
1388 char p1 = p[1];
1389 char p2 = p[2];
1390 char p3 = p[3];
1391 p[0] = p[7];
1392 p[1] = p[6];
1393 p[2] = p[5];
1394 p[3] = p[4];
1395 p[4] = p3;
1396 p[5] = p2;
1397 p[6] = p1;
1398 p[7] = p0;
1399 }
1400 break;
1401 default:
1402 PyErr_SetString(PyExc_RuntimeError,
1403 "don't know how to byteswap this array type");
1404 return NULL;
1405 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001406 Py_RETURN_NONE;
Guido van Rossum778983b1993-02-19 15:55:02 +00001407}
1408
Brett Cannon1eb32c22014-10-10 16:26:45 -04001409/*[clinic input]
1410array.array.reverse
1411
1412Reverse the order of the items in the array.
1413[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001414
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001415static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001416array_array_reverse_impl(arrayobject *self)
1417/*[clinic end generated code: output=c04868b36f6f4089 input=cd904f01b27d966a]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001418{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001419 Py_ssize_t itemsize = self->ob_descr->itemsize;
1420 char *p, *q;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 /* little buffer to hold items while swapping */
1422 char tmp[256]; /* 8 is probably enough -- but why skimp */
1423 assert((size_t)itemsize <= sizeof(tmp));
Guido van Rossume77a7571993-11-03 15:01:26 +00001424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 if (Py_SIZE(self) > 1) {
1426 for (p = self->ob_item,
1427 q = self->ob_item + (Py_SIZE(self) - 1)*itemsize;
1428 p < q;
1429 p += itemsize, q -= itemsize) {
1430 /* memory areas guaranteed disjoint, so memcpy
1431 * is safe (& memmove may be slower).
1432 */
1433 memcpy(tmp, p, itemsize);
1434 memcpy(p, q, itemsize);
1435 memcpy(q, tmp, itemsize);
1436 }
1437 }
Tim Petersbb307342000-09-10 05:22:54 +00001438
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001439 Py_RETURN_NONE;
Guido van Rossum778983b1993-02-19 15:55:02 +00001440}
Guido van Rossume77a7571993-11-03 15:01:26 +00001441
Brett Cannon1eb32c22014-10-10 16:26:45 -04001442/*[clinic input]
1443array.array.fromfile
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001444
Brett Cannon1eb32c22014-10-10 16:26:45 -04001445 f: object
1446 n: Py_ssize_t
1447 /
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001448
Brett Cannon1eb32c22014-10-10 16:26:45 -04001449Read n objects from the file object f and append them to the end of the array.
1450[clinic start generated code]*/
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001451
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001452static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001453array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n)
1454/*[clinic end generated code: output=ec9f600e10f53510 input=e188afe8e58adf40]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001455{
Serhiy Storchaka04e6dba2015-04-04 17:06:55 +03001456 PyObject *b, *res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 Py_ssize_t itemsize = self->ob_descr->itemsize;
Brett Cannon1eb32c22014-10-10 16:26:45 -04001458 Py_ssize_t nbytes;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001459 _Py_IDENTIFIER(read);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 int not_enough_bytes;
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001461
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001462 if (n < 0) {
1463 PyErr_SetString(PyExc_ValueError, "negative count");
1464 return NULL;
1465 }
1466 if (n > PY_SSIZE_T_MAX / itemsize) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 PyErr_NoMemory();
1468 return NULL;
1469 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001470 nbytes = n * itemsize;
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001471
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001472 b = _PyObject_CallMethodId(f, &PyId_read, "n", nbytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 if (b == NULL)
1474 return NULL;
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 if (!PyBytes_Check(b)) {
1477 PyErr_SetString(PyExc_TypeError,
1478 "read() didn't return bytes");
1479 Py_DECREF(b);
1480 return NULL;
1481 }
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001482
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 not_enough_bytes = (PyBytes_GET_SIZE(b) != nbytes);
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001484
Serhiy Storchaka04e6dba2015-04-04 17:06:55 +03001485 res = array_array_frombytes(self, b);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 Py_DECREF(b);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 if (res == NULL)
1488 return NULL;
Hirokazu Yamamoto54d0df62009-03-06 03:04:07 +00001489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 if (not_enough_bytes) {
1491 PyErr_SetString(PyExc_EOFError,
1492 "read() didn't return enough bytes");
1493 Py_DECREF(res);
1494 return NULL;
1495 }
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 return res;
Guido van Rossum778983b1993-02-19 15:55:02 +00001498}
1499
Brett Cannon1eb32c22014-10-10 16:26:45 -04001500/*[clinic input]
1501array.array.tofile
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001502
Brett Cannon1eb32c22014-10-10 16:26:45 -04001503 f: object
1504 /
1505
1506Write all items (as machine values) to the file object f.
1507[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001508
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001509static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001510array_array_tofile(arrayobject *self, PyObject *f)
1511/*[clinic end generated code: output=3a2cfa8128df0777 input=b0669a484aab0831]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001512{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 Py_ssize_t nbytes = Py_SIZE(self) * self->ob_descr->itemsize;
1514 /* Write 64K blocks at a time */
1515 /* XXX Make the block size settable */
1516 int BLOCKSIZE = 64*1024;
1517 Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1) / BLOCKSIZE;
1518 Py_ssize_t i;
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +00001519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 if (Py_SIZE(self) == 0)
1521 goto done;
Guido van Rossumb5ddcfd2007-04-11 17:08:28 +00001522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 for (i = 0; i < nblocks; i++) {
1524 char* ptr = self->ob_item + i*BLOCKSIZE;
1525 Py_ssize_t size = BLOCKSIZE;
1526 PyObject *bytes, *res;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001527 _Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 if (i*BLOCKSIZE + size > nbytes)
1530 size = nbytes - i*BLOCKSIZE;
1531 bytes = PyBytes_FromStringAndSize(ptr, size);
1532 if (bytes == NULL)
1533 return NULL;
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001534 res = _PyObject_CallMethodIdOneArg(f, &PyId_write, bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 Py_DECREF(bytes);
1536 if (res == NULL)
1537 return NULL;
1538 Py_DECREF(res); /* drop write result */
1539 }
Guido van Rossumb5ddcfd2007-04-11 17:08:28 +00001540
1541 done:
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001542 Py_RETURN_NONE;
Guido van Rossum778983b1993-02-19 15:55:02 +00001543}
1544
Brett Cannon1eb32c22014-10-10 16:26:45 -04001545/*[clinic input]
1546array.array.fromlist
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001547
Brett Cannon1eb32c22014-10-10 16:26:45 -04001548 list: object
1549 /
1550
1551Append items to array from list.
1552[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001553
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001554static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001555array_array_fromlist(arrayobject *self, PyObject *list)
1556/*[clinic end generated code: output=26411c2d228a3e3f input=be2605a96c49680f]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001557{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 Py_ssize_t n;
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +00001559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 if (!PyList_Check(list)) {
1561 PyErr_SetString(PyExc_TypeError, "arg must be list");
1562 return NULL;
1563 }
1564 n = PyList_Size(list);
1565 if (n > 0) {
1566 Py_ssize_t i, old_size;
1567 old_size = Py_SIZE(self);
1568 if (array_resize(self, old_size + n) == -1)
1569 return NULL;
1570 for (i = 0; i < n; i++) {
Zackery Spytz99d56b52018-12-08 07:16:55 -07001571 PyObject *v = PyList_GET_ITEM(list, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 if ((*self->ob_descr->setitem)(self,
1573 Py_SIZE(self) - n + i, v) != 0) {
1574 array_resize(self, old_size);
1575 return NULL;
1576 }
Zackery Spytz99d56b52018-12-08 07:16:55 -07001577 if (n != PyList_GET_SIZE(list)) {
1578 PyErr_SetString(PyExc_RuntimeError,
1579 "list changed size during iteration");
1580 array_resize(self, old_size);
1581 return NULL;
1582 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 }
1584 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001585 Py_RETURN_NONE;
Guido van Rossum778983b1993-02-19 15:55:02 +00001586}
1587
Brett Cannon1eb32c22014-10-10 16:26:45 -04001588/*[clinic input]
1589array.array.tolist
1590
1591Convert array to an ordinary list with the same items.
1592[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001593
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001594static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001595array_array_tolist_impl(arrayobject *self)
1596/*[clinic end generated code: output=00b60cc9eab8ef89 input=a8d7784a94f86b53]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001597{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 PyObject *list = PyList_New(Py_SIZE(self));
1599 Py_ssize_t i;
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +00001600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 if (list == NULL)
1602 return NULL;
1603 for (i = 0; i < Py_SIZE(self); i++) {
1604 PyObject *v = getarrayitem((PyObject *)self, i);
Victor Stinner4755bea2013-07-18 01:12:35 +02001605 if (v == NULL)
1606 goto error;
Zackery Spytz99d56b52018-12-08 07:16:55 -07001607 PyList_SET_ITEM(list, i, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 }
1609 return list;
Victor Stinner4755bea2013-07-18 01:12:35 +02001610
1611error:
1612 Py_DECREF(list);
1613 return NULL;
Guido van Rossum778983b1993-02-19 15:55:02 +00001614}
1615
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001616static PyObject *
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001617frombytes(arrayobject *self, Py_buffer *buffer)
Guido van Rossum778983b1993-02-19 15:55:02 +00001618{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001619 int itemsize = self->ob_descr->itemsize;
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001620 Py_ssize_t n;
1621 if (buffer->itemsize != 1) {
1622 PyBuffer_Release(buffer);
Serhiy Storchakab757c832014-12-05 22:25:22 +02001623 PyErr_SetString(PyExc_TypeError, "a bytes-like object is required");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 return NULL;
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001625 }
1626 n = buffer->len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 if (n % itemsize != 0) {
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001628 PyBuffer_Release(buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 PyErr_SetString(PyExc_ValueError,
Serhiy Storchakab757c832014-12-05 22:25:22 +02001630 "bytes length not a multiple of item size");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 return NULL;
1632 }
1633 n = n / itemsize;
1634 if (n > 0) {
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001635 Py_ssize_t old_size = Py_SIZE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001636 if ((n > PY_SSIZE_T_MAX - old_size) ||
1637 ((old_size + n) > PY_SSIZE_T_MAX / itemsize)) {
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001638 PyBuffer_Release(buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 return PyErr_NoMemory();
1640 }
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001641 if (array_resize(self, old_size + n) == -1) {
1642 PyBuffer_Release(buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 return NULL;
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001644 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 memcpy(self->ob_item + old_size * itemsize,
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001646 buffer->buf, n * itemsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 }
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001648 PyBuffer_Release(buffer);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001649 Py_RETURN_NONE;
Guido van Rossum778983b1993-02-19 15:55:02 +00001650}
1651
Brett Cannon1eb32c22014-10-10 16:26:45 -04001652/*[clinic input]
Brett Cannon1eb32c22014-10-10 16:26:45 -04001653array.array.frombytes
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001654
Brett Cannon1eb32c22014-10-10 16:26:45 -04001655 buffer: Py_buffer
1656 /
1657
1658Appends 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).
1659[clinic start generated code]*/
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001660
1661static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001662array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer)
1663/*[clinic end generated code: output=d9842c8f7510a516 input=2bbf2b53ebfcc988]*/
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001664{
Brett Cannon1eb32c22014-10-10 16:26:45 -04001665 return frombytes(self, buffer);
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001666}
1667
Brett Cannon1eb32c22014-10-10 16:26:45 -04001668/*[clinic input]
1669array.array.tobytes
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001670
Brett Cannon1eb32c22014-10-10 16:26:45 -04001671Convert the array to an array of machine values and return the bytes representation.
1672[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001673
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001674static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001675array_array_tobytes_impl(arrayobject *self)
1676/*[clinic end generated code: output=87318e4edcdc2bb6 input=90ee495f96de34f5]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001677{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001678 if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
1679 return PyBytes_FromStringAndSize(self->ob_item,
1680 Py_SIZE(self) * self->ob_descr->itemsize);
1681 } else {
1682 return PyErr_NoMemory();
1683 }
Guido van Rossum778983b1993-02-19 15:55:02 +00001684}
1685
Brett Cannon1eb32c22014-10-10 16:26:45 -04001686/*[clinic input]
Brett Cannon1eb32c22014-10-10 16:26:45 -04001687array.array.fromunicode
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001688
Inada Naokid5d9a712020-05-11 15:37:25 +09001689 ustr: unicode
Brett Cannon1eb32c22014-10-10 16:26:45 -04001690 /
1691
1692Extends this array with data from the unicode string ustr.
1693
1694The array must be a unicode type array; otherwise a ValueError is raised.
1695Use array.frombytes(ustr.encode(...)) to append Unicode data to an array of
1696some other type.
1697[clinic start generated code]*/
Martin v. Löwis99866332002-03-01 10:27:01 +00001698
Martin v. Löwis99866332002-03-01 10:27:01 +00001699static PyObject *
Inada Naokid5d9a712020-05-11 15:37:25 +09001700array_array_fromunicode_impl(arrayobject *self, PyObject *ustr)
1701/*[clinic end generated code: output=24359f5e001a7f2b input=025db1fdade7a4ce]*/
Martin v. Löwis99866332002-03-01 10:27:01 +00001702{
Inada Naokid5d9a712020-05-11 15:37:25 +09001703 if (self->ob_descr->typecode != 'u') {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001704 PyErr_SetString(PyExc_ValueError,
1705 "fromunicode() may only be called on "
1706 "unicode type arrays");
1707 return NULL;
1708 }
Inada Naokid5d9a712020-05-11 15:37:25 +09001709
1710 Py_ssize_t ustr_length = PyUnicode_AsWideChar(ustr, NULL, 0);
1711 assert(ustr_length > 0);
1712 if (ustr_length > 1) {
1713 ustr_length--; /* trim trailing NUL character */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 Py_ssize_t old_size = Py_SIZE(self);
Inada Naokid5d9a712020-05-11 15:37:25 +09001715 if (array_resize(self, old_size + ustr_length) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001716 return NULL;
Inada Naokid5d9a712020-05-11 15:37:25 +09001717 }
1718
1719 // must not fail
1720 PyUnicode_AsWideChar(
1721 ustr, ((wchar_t *)self->ob_item) + old_size, ustr_length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001722 }
Martin v. Löwis99866332002-03-01 10:27:01 +00001723
Brett Cannon1eb32c22014-10-10 16:26:45 -04001724 Py_RETURN_NONE;
Martin v. Löwis99866332002-03-01 10:27:01 +00001725}
1726
Brett Cannon1eb32c22014-10-10 16:26:45 -04001727/*[clinic input]
1728array.array.tounicode
Martin v. Löwis99866332002-03-01 10:27:01 +00001729
Brett Cannon1eb32c22014-10-10 16:26:45 -04001730Extends this array with data from the unicode string ustr.
1731
1732Convert the array to a unicode string. The array must be a unicode type array;
1733otherwise a ValueError is raised. Use array.tobytes().decode() to obtain a
1734unicode string from an array of some other type.
1735[clinic start generated code]*/
Martin v. Löwis99866332002-03-01 10:27:01 +00001736
1737static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001738array_array_tounicode_impl(arrayobject *self)
1739/*[clinic end generated code: output=08e442378336e1ef input=127242eebe70b66d]*/
Martin v. Löwis99866332002-03-01 10:27:01 +00001740{
Inada Naokid5d9a712020-05-11 15:37:25 +09001741 if (self->ob_descr->typecode != 'u') {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001742 PyErr_SetString(PyExc_ValueError,
1743 "tounicode() may only be called on unicode type arrays");
1744 return NULL;
1745 }
Inada Naokid5d9a712020-05-11 15:37:25 +09001746 return PyUnicode_FromWideChar((wchar_t *) self->ob_item, Py_SIZE(self));
Martin v. Löwis99866332002-03-01 10:27:01 +00001747}
1748
Brett Cannon1eb32c22014-10-10 16:26:45 -04001749/*[clinic input]
1750array.array.__sizeof__
Martin v. Löwis99866332002-03-01 10:27:01 +00001751
Brett Cannon1eb32c22014-10-10 16:26:45 -04001752Size of the array in memory, in bytes.
1753[clinic start generated code]*/
Martin v. Löwis99866332002-03-01 10:27:01 +00001754
Meador Inge03b4d502012-08-10 22:35:45 -05001755static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001756array_array___sizeof___impl(arrayobject *self)
1757/*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/
Meador Inge03b4d502012-08-10 22:35:45 -05001758{
1759 Py_ssize_t res;
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001760 res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * self->ob_descr->itemsize;
Meador Inge03b4d502012-08-10 22:35:45 -05001761 return PyLong_FromSsize_t(res);
1762}
1763
Martin v. Löwis99866332002-03-01 10:27:01 +00001764
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001765/*********************** Pickling support ************************/
1766
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001767static const struct mformatdescr {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 size_t size;
1769 int is_signed;
1770 int is_big_endian;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001771} mformat_descriptors[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 {1, 0, 0}, /* 0: UNSIGNED_INT8 */
1773 {1, 1, 0}, /* 1: SIGNED_INT8 */
1774 {2, 0, 0}, /* 2: UNSIGNED_INT16_LE */
1775 {2, 0, 1}, /* 3: UNSIGNED_INT16_BE */
1776 {2, 1, 0}, /* 4: SIGNED_INT16_LE */
1777 {2, 1, 1}, /* 5: SIGNED_INT16_BE */
1778 {4, 0, 0}, /* 6: UNSIGNED_INT32_LE */
1779 {4, 0, 1}, /* 7: UNSIGNED_INT32_BE */
1780 {4, 1, 0}, /* 8: SIGNED_INT32_LE */
1781 {4, 1, 1}, /* 9: SIGNED_INT32_BE */
1782 {8, 0, 0}, /* 10: UNSIGNED_INT64_LE */
1783 {8, 0, 1}, /* 11: UNSIGNED_INT64_BE */
1784 {8, 1, 0}, /* 12: SIGNED_INT64_LE */
1785 {8, 1, 1}, /* 13: SIGNED_INT64_BE */
1786 {4, 0, 0}, /* 14: IEEE_754_FLOAT_LE */
1787 {4, 0, 1}, /* 15: IEEE_754_FLOAT_BE */
1788 {8, 0, 0}, /* 16: IEEE_754_DOUBLE_LE */
1789 {8, 0, 1}, /* 17: IEEE_754_DOUBLE_BE */
1790 {4, 0, 0}, /* 18: UTF16_LE */
1791 {4, 0, 1}, /* 19: UTF16_BE */
1792 {8, 0, 0}, /* 20: UTF32_LE */
1793 {8, 0, 1} /* 21: UTF32_BE */
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001794};
1795
1796
1797/*
1798 * Internal: This function is used to find the machine format of a given
1799 * array type code. This returns UNKNOWN_FORMAT when the machine format cannot
1800 * be found.
1801 */
1802static enum machine_format_code
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02001803typecode_to_mformat_code(char typecode)
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001804{
Christian Heimes743e0cd2012-10-17 23:52:17 +02001805 const int is_big_endian = PY_BIG_ENDIAN;
1806
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001807 size_t intsize;
1808 int is_signed;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001809
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 switch (typecode) {
1811 case 'b':
1812 return SIGNED_INT8;
1813 case 'B':
1814 return UNSIGNED_INT8;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 case 'u':
Victor Stinner62bb3942012-08-06 00:46:05 +02001817 if (sizeof(Py_UNICODE) == 2) {
1818 return UTF16_LE + is_big_endian;
1819 }
1820 if (sizeof(Py_UNICODE) == 4) {
1821 return UTF32_LE + is_big_endian;
1822 }
1823 return UNKNOWN_FORMAT;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001824
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001825 case 'f':
1826 if (sizeof(float) == 4) {
1827 const float y = 16711938.0;
1828 if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
1829 return IEEE_754_FLOAT_BE;
1830 if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
1831 return IEEE_754_FLOAT_LE;
1832 }
1833 return UNKNOWN_FORMAT;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 case 'd':
1836 if (sizeof(double) == 8) {
1837 const double x = 9006104071832581.0;
1838 if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
1839 return IEEE_754_DOUBLE_BE;
1840 if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
1841 return IEEE_754_DOUBLE_LE;
1842 }
1843 return UNKNOWN_FORMAT;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001844
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 /* Integers */
1846 case 'h':
1847 intsize = sizeof(short);
1848 is_signed = 1;
1849 break;
1850 case 'H':
1851 intsize = sizeof(short);
1852 is_signed = 0;
1853 break;
1854 case 'i':
1855 intsize = sizeof(int);
1856 is_signed = 1;
1857 break;
1858 case 'I':
1859 intsize = sizeof(int);
1860 is_signed = 0;
1861 break;
1862 case 'l':
1863 intsize = sizeof(long);
1864 is_signed = 1;
1865 break;
1866 case 'L':
1867 intsize = sizeof(long);
1868 is_signed = 0;
1869 break;
Meador Inge1c9f0c92011-09-20 19:55:51 -05001870 case 'q':
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001871 intsize = sizeof(long long);
Meador Inge1c9f0c92011-09-20 19:55:51 -05001872 is_signed = 1;
1873 break;
1874 case 'Q':
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001875 intsize = sizeof(long long);
Meador Inge1c9f0c92011-09-20 19:55:51 -05001876 is_signed = 0;
1877 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 default:
1879 return UNKNOWN_FORMAT;
1880 }
1881 switch (intsize) {
1882 case 2:
1883 return UNSIGNED_INT16_LE + is_big_endian + (2 * is_signed);
1884 case 4:
1885 return UNSIGNED_INT32_LE + is_big_endian + (2 * is_signed);
1886 case 8:
1887 return UNSIGNED_INT64_LE + is_big_endian + (2 * is_signed);
1888 default:
1889 return UNKNOWN_FORMAT;
1890 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001891}
1892
1893/* Forward declaration. */
1894static PyObject *array_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
1895
1896/*
1897 * Internal: This function wraps the array constructor--i.e., array_new()--to
1898 * allow the creation of array objects from C code without having to deal
1899 * directly the tuple argument of array_new(). The typecode argument is a
1900 * Unicode character value, like 'i' or 'f' for example, representing an array
1901 * type code. The items argument is a bytes or a list object from which
1902 * contains the initial value of the array.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 *
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001904 * On success, this functions returns the array object created. Otherwise,
1905 * NULL is returned to indicate a failure.
1906 */
1907static PyObject *
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02001908make_array(PyTypeObject *arraytype, char typecode, PyObject *items)
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001909{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 PyObject *new_args;
1911 PyObject *array_obj;
1912 PyObject *typecode_obj;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 assert(arraytype != NULL);
1915 assert(items != NULL);
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001916
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02001917 typecode_obj = PyUnicode_FromOrdinal(typecode);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 if (typecode_obj == NULL)
1919 return NULL;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921 new_args = PyTuple_New(2);
Mat M56935a52017-11-14 01:00:54 -05001922 if (new_args == NULL) {
1923 Py_DECREF(typecode_obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 return NULL;
Mat M56935a52017-11-14 01:00:54 -05001925 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 Py_INCREF(items);
1927 PyTuple_SET_ITEM(new_args, 0, typecode_obj);
1928 PyTuple_SET_ITEM(new_args, 1, items);
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 array_obj = array_new(arraytype, new_args, NULL);
1931 Py_DECREF(new_args);
1932 if (array_obj == NULL)
1933 return NULL;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 return array_obj;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001936}
1937
1938/*
1939 * This functions is a special constructor used when unpickling an array. It
1940 * provides a portable way to rebuild an array from its memory representation.
1941 */
Brett Cannon1eb32c22014-10-10 16:26:45 -04001942/*[clinic input]
1943array._array_reconstructor
1944
1945 arraytype: object(type="PyTypeObject *")
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001946 typecode: int(accept={str})
Brett Cannon1eb32c22014-10-10 16:26:45 -04001947 mformat_code: int(type="enum machine_format_code")
1948 items: object
1949 /
1950
1951Internal. Used for pickling support.
1952[clinic start generated code]*/
1953
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001954static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001955array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype,
Larry Hastings89964c42015-04-14 18:07:59 -04001956 int typecode,
1957 enum machine_format_code mformat_code,
1958 PyObject *items)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001959/*[clinic end generated code: output=e05263141ba28365 input=2464dc8f4c7736b5]*/
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001960{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001961 array_state *state = get_array_state(module);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001962 PyObject *converted_items;
1963 PyObject *result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001964 const struct arraydescr *descr;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 if (!PyType_Check(arraytype)) {
1967 PyErr_Format(PyExc_TypeError,
Sylvaina90e64b2017-03-29 20:09:22 +02001968 "first argument must be a type object, not %.200s",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 Py_TYPE(arraytype)->tp_name);
1970 return NULL;
1971 }
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001972 if (!PyType_IsSubtype(arraytype, state->ArrayType)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 PyErr_Format(PyExc_TypeError,
1974 "%.200s is not a subtype of %.200s",
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001975 arraytype->tp_name, state->ArrayType->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 return NULL;
1977 }
1978 for (descr = descriptors; descr->typecode != '\0'; descr++) {
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02001979 if ((int)descr->typecode == typecode)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 break;
1981 }
1982 if (descr->typecode == '\0') {
1983 PyErr_SetString(PyExc_ValueError,
1984 "second argument must be a valid type code");
1985 return NULL;
1986 }
Larry Hastingsdfbeb162014-10-13 10:39:41 +01001987 if (mformat_code < MACHINE_FORMAT_CODE_MIN ||
1988 mformat_code > MACHINE_FORMAT_CODE_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001989 PyErr_SetString(PyExc_ValueError,
1990 "third argument must be a valid machine format code.");
1991 return NULL;
1992 }
1993 if (!PyBytes_Check(items)) {
1994 PyErr_Format(PyExc_TypeError,
1995 "fourth argument should be bytes, not %.200s",
1996 Py_TYPE(items)->tp_name);
1997 return NULL;
1998 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002000 /* Fast path: No decoding has to be done. */
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002001 if (mformat_code == typecode_to_mformat_code((char)typecode) ||
2002 mformat_code == UNKNOWN_FORMAT) {
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02002003 return make_array(arraytype, (char)typecode, items);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 /* Slow path: Decode the byte string according to the given machine
2007 * format code. This occurs when the computer unpickling the array
2008 * object is architecturally different from the one that pickled the
2009 * array.
2010 */
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002011 if (Py_SIZE(items) % mformat_descriptors[mformat_code].size != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002012 PyErr_SetString(PyExc_ValueError,
2013 "string length not a multiple of item size");
2014 return NULL;
2015 }
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002016 switch (mformat_code) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002017 case IEEE_754_FLOAT_LE:
2018 case IEEE_754_FLOAT_BE: {
sthaa3ecb82019-03-20 20:49:39 +01002019 Py_ssize_t i;
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002020 int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002021 Py_ssize_t itemcount = Py_SIZE(items) / 4;
2022 const unsigned char *memstr =
2023 (unsigned char *)PyBytes_AS_STRING(items);
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 converted_items = PyList_New(itemcount);
2026 if (converted_items == NULL)
2027 return NULL;
2028 for (i = 0; i < itemcount; i++) {
2029 PyObject *pyfloat = PyFloat_FromDouble(
2030 _PyFloat_Unpack4(&memstr[i * 4], le));
2031 if (pyfloat == NULL) {
2032 Py_DECREF(converted_items);
2033 return NULL;
2034 }
2035 PyList_SET_ITEM(converted_items, i, pyfloat);
2036 }
2037 break;
2038 }
2039 case IEEE_754_DOUBLE_LE:
2040 case IEEE_754_DOUBLE_BE: {
sthaa3ecb82019-03-20 20:49:39 +01002041 Py_ssize_t i;
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002042 int le = (mformat_code == IEEE_754_DOUBLE_LE) ? 1 : 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002043 Py_ssize_t itemcount = Py_SIZE(items) / 8;
2044 const unsigned char *memstr =
2045 (unsigned char *)PyBytes_AS_STRING(items);
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002047 converted_items = PyList_New(itemcount);
2048 if (converted_items == NULL)
2049 return NULL;
2050 for (i = 0; i < itemcount; i++) {
2051 PyObject *pyfloat = PyFloat_FromDouble(
2052 _PyFloat_Unpack8(&memstr[i * 8], le));
2053 if (pyfloat == NULL) {
2054 Py_DECREF(converted_items);
2055 return NULL;
2056 }
2057 PyList_SET_ITEM(converted_items, i, pyfloat);
2058 }
2059 break;
2060 }
2061 case UTF16_LE:
2062 case UTF16_BE: {
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002063 int byteorder = (mformat_code == UTF16_LE) ? -1 : 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002064 converted_items = PyUnicode_DecodeUTF16(
2065 PyBytes_AS_STRING(items), Py_SIZE(items),
2066 "strict", &byteorder);
2067 if (converted_items == NULL)
2068 return NULL;
2069 break;
2070 }
2071 case UTF32_LE:
2072 case UTF32_BE: {
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002073 int byteorder = (mformat_code == UTF32_LE) ? -1 : 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002074 converted_items = PyUnicode_DecodeUTF32(
2075 PyBytes_AS_STRING(items), Py_SIZE(items),
2076 "strict", &byteorder);
2077 if (converted_items == NULL)
2078 return NULL;
2079 break;
2080 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 case UNSIGNED_INT8:
2083 case SIGNED_INT8:
2084 case UNSIGNED_INT16_LE:
2085 case UNSIGNED_INT16_BE:
2086 case SIGNED_INT16_LE:
2087 case SIGNED_INT16_BE:
2088 case UNSIGNED_INT32_LE:
2089 case UNSIGNED_INT32_BE:
2090 case SIGNED_INT32_LE:
2091 case SIGNED_INT32_BE:
2092 case UNSIGNED_INT64_LE:
2093 case UNSIGNED_INT64_BE:
2094 case SIGNED_INT64_LE:
2095 case SIGNED_INT64_BE: {
sthaa3ecb82019-03-20 20:49:39 +01002096 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 const struct mformatdescr mf_descr =
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002098 mformat_descriptors[mformat_code];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 Py_ssize_t itemcount = Py_SIZE(items) / mf_descr.size;
2100 const unsigned char *memstr =
2101 (unsigned char *)PyBytes_AS_STRING(items);
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002102 const struct arraydescr *descr;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 /* If possible, try to pack array's items using a data type
2105 * that fits better. This may result in an array with narrower
2106 * or wider elements.
2107 *
Martin Panter4c359642016-05-08 13:53:41 +00002108 * For example, if a 32-bit machine pickles an L-code array of
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 * unsigned longs, then the array will be unpickled by 64-bit
2110 * machine as an I-code array of unsigned ints.
2111 *
2112 * XXX: Is it possible to write a unit test for this?
2113 */
2114 for (descr = descriptors; descr->typecode != '\0'; descr++) {
2115 if (descr->is_integer_type &&
Victor Stinner706768c2014-08-16 01:03:39 +02002116 (size_t)descr->itemsize == mf_descr.size &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002117 descr->is_signed == mf_descr.is_signed)
2118 typecode = descr->typecode;
2119 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 converted_items = PyList_New(itemcount);
2122 if (converted_items == NULL)
2123 return NULL;
2124 for (i = 0; i < itemcount; i++) {
2125 PyObject *pylong;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 pylong = _PyLong_FromByteArray(
2128 &memstr[i * mf_descr.size],
2129 mf_descr.size,
2130 !mf_descr.is_big_endian,
2131 mf_descr.is_signed);
2132 if (pylong == NULL) {
2133 Py_DECREF(converted_items);
2134 return NULL;
2135 }
2136 PyList_SET_ITEM(converted_items, i, pylong);
2137 }
2138 break;
2139 }
2140 case UNKNOWN_FORMAT:
2141 /* Impossible, but needed to shut up GCC about the unhandled
2142 * enumeration value.
2143 */
2144 default:
2145 PyErr_BadArgument();
2146 return NULL;
2147 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002148
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02002149 result = make_array(arraytype, (char)typecode, converted_items);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002150 Py_DECREF(converted_items);
2151 return result;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002152}
2153
Brett Cannon1eb32c22014-10-10 16:26:45 -04002154/*[clinic input]
2155array.array.__reduce_ex__
2156
2157 value: object
2158 /
2159
2160Return state information for pickling.
2161[clinic start generated code]*/
2162
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002163static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04002164array_array___reduce_ex__(arrayobject *self, PyObject *value)
2165/*[clinic end generated code: output=051e0a6175d0eddb input=c36c3f85de7df6cd]*/
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 PyObject *dict;
2168 PyObject *result;
2169 PyObject *array_str;
Brett Cannon1eb32c22014-10-10 16:26:45 -04002170 int typecode = self->ob_descr->typecode;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 int mformat_code;
2172 static PyObject *array_reconstructor = NULL;
2173 long protocol;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002174 _Py_IDENTIFIER(_array_reconstructor);
2175 _Py_IDENTIFIER(__dict__);
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002177 if (array_reconstructor == NULL) {
2178 PyObject *array_module = PyImport_ImportModule("array");
2179 if (array_module == NULL)
2180 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002181 array_reconstructor = _PyObject_GetAttrId(
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002182 array_module,
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002183 &PyId__array_reconstructor);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 Py_DECREF(array_module);
2185 if (array_reconstructor == NULL)
2186 return NULL;
2187 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 if (!PyLong_Check(value)) {
2190 PyErr_SetString(PyExc_TypeError,
Sylvaina90e64b2017-03-29 20:09:22 +02002191 "__reduce_ex__ argument should be an integer");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 return NULL;
2193 }
2194 protocol = PyLong_AsLong(value);
2195 if (protocol == -1 && PyErr_Occurred())
2196 return NULL;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002197
Serhiy Storchakaf320be72018-01-25 10:49:40 +02002198 if (_PyObject_LookupAttrId((PyObject *)self, &PyId___dict__, &dict) < 0) {
2199 return NULL;
2200 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002201 if (dict == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002202 dict = Py_None;
2203 Py_INCREF(dict);
2204 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 mformat_code = typecode_to_mformat_code(typecode);
2207 if (mformat_code == UNKNOWN_FORMAT || protocol < 3) {
2208 /* Convert the array to a list if we got something weird
2209 * (e.g., non-IEEE floats), or we are pickling the array using
2210 * a Python 2.x compatible protocol.
2211 *
2212 * It is necessary to use a list representation for Python 2.x
2213 * compatible pickle protocol, since Python 2's str objects
2214 * are unpickled as unicode by Python 3. Thus it is impossible
2215 * to make arrays unpicklable by Python 3 by using their memory
2216 * representation, unless we resort to ugly hacks such as
2217 * coercing unicode objects to bytes in array_reconstructor.
2218 */
2219 PyObject *list;
Brett Cannon1eb32c22014-10-10 16:26:45 -04002220 list = array_array_tolist_impl(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002221 if (list == NULL) {
2222 Py_DECREF(dict);
2223 return NULL;
2224 }
2225 result = Py_BuildValue(
Brett Cannon1eb32c22014-10-10 16:26:45 -04002226 "O(CO)O", Py_TYPE(self), typecode, list, dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002227 Py_DECREF(list);
2228 Py_DECREF(dict);
2229 return result;
2230 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002231
Brett Cannon1eb32c22014-10-10 16:26:45 -04002232 array_str = array_array_tobytes_impl(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002233 if (array_str == NULL) {
2234 Py_DECREF(dict);
2235 return NULL;
2236 }
2237 result = Py_BuildValue(
Brett Cannon1eb32c22014-10-10 16:26:45 -04002238 "O(OCiN)O", array_reconstructor, Py_TYPE(self), typecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002239 mformat_code, array_str, dict);
2240 Py_DECREF(dict);
2241 return result;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002242}
2243
Martin v. Löwis99866332002-03-01 10:27:01 +00002244static PyObject *
2245array_get_typecode(arrayobject *a, void *closure)
2246{
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02002247 char typecode = a->ob_descr->typecode;
2248 return PyUnicode_FromOrdinal(typecode);
Martin v. Löwis99866332002-03-01 10:27:01 +00002249}
2250
2251static PyObject *
2252array_get_itemsize(arrayobject *a, void *closure)
2253{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002254 return PyLong_FromLong((long)a->ob_descr->itemsize);
Martin v. Löwis99866332002-03-01 10:27:01 +00002255}
2256
2257static PyGetSetDef array_getsets [] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002258 {"typecode", (getter) array_get_typecode, NULL,
2259 "the typecode character used to create the array"},
2260 {"itemsize", (getter) array_get_itemsize, NULL,
2261 "the size, in bytes, of one array item"},
2262 {NULL}
Martin v. Löwis99866332002-03-01 10:27:01 +00002263};
2264
Martin v. Löwis59683e82008-06-13 07:50:45 +00002265static PyMethodDef array_methods[] = {
Brett Cannon1eb32c22014-10-10 16:26:45 -04002266 ARRAY_ARRAY_APPEND_METHODDEF
2267 ARRAY_ARRAY_BUFFER_INFO_METHODDEF
2268 ARRAY_ARRAY_BYTESWAP_METHODDEF
2269 ARRAY_ARRAY___COPY___METHODDEF
2270 ARRAY_ARRAY_COUNT_METHODDEF
2271 ARRAY_ARRAY___DEEPCOPY___METHODDEF
2272 ARRAY_ARRAY_EXTEND_METHODDEF
2273 ARRAY_ARRAY_FROMFILE_METHODDEF
2274 ARRAY_ARRAY_FROMLIST_METHODDEF
Brett Cannon1eb32c22014-10-10 16:26:45 -04002275 ARRAY_ARRAY_FROMBYTES_METHODDEF
2276 ARRAY_ARRAY_FROMUNICODE_METHODDEF
2277 ARRAY_ARRAY_INDEX_METHODDEF
2278 ARRAY_ARRAY_INSERT_METHODDEF
2279 ARRAY_ARRAY_POP_METHODDEF
2280 ARRAY_ARRAY___REDUCE_EX___METHODDEF
2281 ARRAY_ARRAY_REMOVE_METHODDEF
2282 ARRAY_ARRAY_REVERSE_METHODDEF
2283 ARRAY_ARRAY_TOFILE_METHODDEF
2284 ARRAY_ARRAY_TOLIST_METHODDEF
Brett Cannon1eb32c22014-10-10 16:26:45 -04002285 ARRAY_ARRAY_TOBYTES_METHODDEF
2286 ARRAY_ARRAY_TOUNICODE_METHODDEF
2287 ARRAY_ARRAY___SIZEOF___METHODDEF
2288 {NULL, NULL} /* sentinel */
Guido van Rossum778983b1993-02-19 15:55:02 +00002289};
2290
Roger E. Masse2919eaa1996-12-09 20:10:36 +00002291static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +00002292array_repr(arrayobject *a)
Guido van Rossum778983b1993-02-19 15:55:02 +00002293{
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02002294 char typecode;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002295 PyObject *s, *v = NULL;
2296 Py_ssize_t len;
Martin v. Löwis99866332002-03-01 10:27:01 +00002297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002298 len = Py_SIZE(a);
2299 typecode = a->ob_descr->typecode;
2300 if (len == 0) {
Serhiy Storchakab3a77962017-09-21 14:24:13 +03002301 return PyUnicode_FromFormat("%s('%c')",
2302 _PyType_Name(Py_TYPE(a)), (int)typecode);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002303 }
Gregory P. Smith9504b132012-12-10 20:20:20 -08002304 if (typecode == 'u') {
Brett Cannon1eb32c22014-10-10 16:26:45 -04002305 v = array_array_tounicode_impl(a);
Gregory P. Smith9504b132012-12-10 20:20:20 -08002306 } else {
Brett Cannon1eb32c22014-10-10 16:26:45 -04002307 v = array_array_tolist_impl(a);
Gregory P. Smith9504b132012-12-10 20:20:20 -08002308 }
Victor Stinner29ec5952013-02-26 00:27:38 +01002309 if (v == NULL)
2310 return NULL;
Raymond Hettinger88ba1e32003-04-23 17:27:00 +00002311
Serhiy Storchakab3a77962017-09-21 14:24:13 +03002312 s = PyUnicode_FromFormat("%s('%c', %R)",
2313 _PyType_Name(Py_TYPE(a)), (int)typecode, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002314 Py_DECREF(v);
2315 return s;
Guido van Rossum778983b1993-02-19 15:55:02 +00002316}
2317
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002318static PyObject*
2319array_subscr(arrayobject* self, PyObject* item)
2320{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002321 array_state *state = find_array_state_by_type(Py_TYPE(self));
2322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002323 if (PyIndex_Check(item)) {
2324 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
2325 if (i==-1 && PyErr_Occurred()) {
2326 return NULL;
2327 }
2328 if (i < 0)
2329 i += Py_SIZE(self);
2330 return array_item(self, i);
2331 }
2332 else if (PySlice_Check(item)) {
Zackery Spytz14514d92019-05-17 01:13:03 -06002333 Py_ssize_t start, stop, step, slicelength, i;
2334 size_t cur;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002335 PyObject* result;
2336 arrayobject* ar;
2337 int itemsize = self->ob_descr->itemsize;
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002338
Serhiy Storchakab879fe82017-04-08 09:53:51 +03002339 if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002340 return NULL;
2341 }
Serhiy Storchakab879fe82017-04-08 09:53:51 +03002342 slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop,
2343 step);
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345 if (slicelength <= 0) {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002346 return newarrayobject(state->ArrayType, 0, self->ob_descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002347 }
2348 else if (step == 1) {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002349 PyObject *result = newarrayobject(state->ArrayType,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002350 slicelength, self->ob_descr);
2351 if (result == NULL)
2352 return NULL;
2353 memcpy(((arrayobject *)result)->ob_item,
2354 self->ob_item + start * itemsize,
2355 slicelength * itemsize);
2356 return result;
2357 }
2358 else {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002359 result = newarrayobject(state->ArrayType, slicelength, self->ob_descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360 if (!result) return NULL;
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002362 ar = (arrayobject*)result;
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 for (cur = start, i = 0; i < slicelength;
2365 cur += step, i++) {
2366 memcpy(ar->ob_item + i*itemsize,
2367 self->ob_item + cur*itemsize,
2368 itemsize);
2369 }
2370
2371 return result;
2372 }
2373 }
2374 else {
2375 PyErr_SetString(PyExc_TypeError,
2376 "array indices must be integers");
2377 return NULL;
2378 }
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002379}
2380
2381static int
2382array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
2383{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384 Py_ssize_t start, stop, step, slicelength, needed;
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002385 array_state* state = find_array_state_by_type(Py_TYPE(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386 arrayobject* other;
2387 int itemsize;
Thomas Woutersed03b412007-08-28 21:37:11 +00002388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002389 if (PyIndex_Check(item)) {
2390 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
Alexandre Vassalotti47137252009-07-05 19:57:00 +00002391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002392 if (i == -1 && PyErr_Occurred())
2393 return -1;
2394 if (i < 0)
2395 i += Py_SIZE(self);
2396 if (i < 0 || i >= Py_SIZE(self)) {
2397 PyErr_SetString(PyExc_IndexError,
2398 "array assignment index out of range");
2399 return -1;
2400 }
2401 if (value == NULL) {
2402 /* Fall through to slice assignment */
2403 start = i;
2404 stop = i + 1;
2405 step = 1;
2406 slicelength = 1;
2407 }
2408 else
2409 return (*self->ob_descr->setitem)(self, i, value);
2410 }
2411 else if (PySlice_Check(item)) {
Serhiy Storchakab879fe82017-04-08 09:53:51 +03002412 if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002413 return -1;
2414 }
Serhiy Storchakab879fe82017-04-08 09:53:51 +03002415 slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop,
2416 step);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002417 }
2418 else {
2419 PyErr_SetString(PyExc_TypeError,
Sylvaina90e64b2017-03-29 20:09:22 +02002420 "array indices must be integers");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002421 return -1;
2422 }
2423 if (value == NULL) {
2424 other = NULL;
2425 needed = 0;
2426 }
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002427 else if (array_Check(value, state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002428 other = (arrayobject *)value;
2429 needed = Py_SIZE(other);
2430 if (self == other) {
2431 /* Special case "self[i:j] = self" -- copy self first */
2432 int ret;
2433 value = array_slice(other, 0, needed);
2434 if (value == NULL)
2435 return -1;
2436 ret = array_ass_subscr(self, item, value);
2437 Py_DECREF(value);
2438 return ret;
2439 }
2440 if (other->ob_descr != self->ob_descr) {
2441 PyErr_BadArgument();
2442 return -1;
2443 }
2444 }
2445 else {
2446 PyErr_Format(PyExc_TypeError,
2447 "can only assign array (not \"%.200s\") to array slice",
2448 Py_TYPE(value)->tp_name);
2449 return -1;
2450 }
2451 itemsize = self->ob_descr->itemsize;
2452 /* for 'a[2:1] = ...', the insertion point is 'start', not 'stop' */
2453 if ((step > 0 && stop < start) ||
2454 (step < 0 && stop > start))
2455 stop = start;
Alexandre Vassalotti47137252009-07-05 19:57:00 +00002456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002457 /* Issue #4509: If the array has exported buffers and the slice
2458 assignment would change the size of the array, fail early to make
2459 sure we don't modify it. */
2460 if ((needed == 0 || slicelength != needed) && self->ob_exports > 0) {
2461 PyErr_SetString(PyExc_BufferError,
2462 "cannot resize an array that is exporting buffers");
2463 return -1;
2464 }
Mark Dickinsonbc099642010-01-29 17:27:24 +00002465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002466 if (step == 1) {
2467 if (slicelength > needed) {
2468 memmove(self->ob_item + (start + needed) * itemsize,
2469 self->ob_item + stop * itemsize,
2470 (Py_SIZE(self) - stop) * itemsize);
2471 if (array_resize(self, Py_SIZE(self) +
2472 needed - slicelength) < 0)
2473 return -1;
2474 }
2475 else if (slicelength < needed) {
2476 if (array_resize(self, Py_SIZE(self) +
2477 needed - slicelength) < 0)
2478 return -1;
2479 memmove(self->ob_item + (start + needed) * itemsize,
2480 self->ob_item + stop * itemsize,
2481 (Py_SIZE(self) - start - needed) * itemsize);
2482 }
2483 if (needed > 0)
2484 memcpy(self->ob_item + start * itemsize,
2485 other->ob_item, needed * itemsize);
2486 return 0;
2487 }
2488 else if (needed == 0) {
2489 /* Delete slice */
2490 size_t cur;
2491 Py_ssize_t i;
Thomas Woutersed03b412007-08-28 21:37:11 +00002492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002493 if (step < 0) {
2494 stop = start + 1;
2495 start = stop + step * (slicelength - 1) - 1;
2496 step = -step;
2497 }
2498 for (cur = start, i = 0; i < slicelength;
2499 cur += step, i++) {
2500 Py_ssize_t lim = step - 1;
Thomas Woutersed03b412007-08-28 21:37:11 +00002501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002502 if (cur + step >= (size_t)Py_SIZE(self))
2503 lim = Py_SIZE(self) - cur - 1;
2504 memmove(self->ob_item + (cur - i) * itemsize,
2505 self->ob_item + (cur + 1) * itemsize,
2506 lim * itemsize);
2507 }
Mark Dickinsonc7d93b72011-09-25 15:34:32 +01002508 cur = start + (size_t)slicelength * step;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002509 if (cur < (size_t)Py_SIZE(self)) {
2510 memmove(self->ob_item + (cur-slicelength) * itemsize,
2511 self->ob_item + cur * itemsize,
2512 (Py_SIZE(self) - cur) * itemsize);
2513 }
2514 if (array_resize(self, Py_SIZE(self) - slicelength) < 0)
2515 return -1;
2516 return 0;
2517 }
2518 else {
Zackery Spytz14514d92019-05-17 01:13:03 -06002519 size_t cur;
2520 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002521
2522 if (needed != slicelength) {
2523 PyErr_Format(PyExc_ValueError,
2524 "attempt to assign array of size %zd "
2525 "to extended slice of size %zd",
2526 needed, slicelength);
2527 return -1;
2528 }
2529 for (cur = start, i = 0; i < slicelength;
2530 cur += step, i++) {
2531 memcpy(self->ob_item + cur * itemsize,
2532 other->ob_item + i * itemsize,
2533 itemsize);
2534 }
2535 return 0;
2536 }
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002537}
2538
Guido van Rossumd8faa362007-04-27 19:54:29 +00002539static const void *emptybuf = "";
2540
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002541
2542static int
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +00002543array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00002544{
Stefan Krah650c1e82015-02-03 21:43:23 +01002545 if (view == NULL) {
2546 PyErr_SetString(PyExc_BufferError,
2547 "array_buffer_getbuf: view==NULL argument is obsolete");
2548 return -1;
2549 }
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002551 view->buf = (void *)self->ob_item;
2552 view->obj = (PyObject*)self;
2553 Py_INCREF(self);
2554 if (view->buf == NULL)
2555 view->buf = (void *)emptybuf;
Victor Stinnerfe2978b2020-05-27 14:55:10 +02002556 view->len = Py_SIZE(self) * self->ob_descr->itemsize;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002557 view->readonly = 0;
2558 view->ndim = 1;
2559 view->itemsize = self->ob_descr->itemsize;
2560 view->suboffsets = NULL;
2561 view->shape = NULL;
2562 if ((flags & PyBUF_ND)==PyBUF_ND) {
Victor Stinnerfe2978b2020-05-27 14:55:10 +02002563 view->shape = &((PyVarObject*)self)->ob_size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002564 }
2565 view->strides = NULL;
2566 if ((flags & PyBUF_STRIDES)==PyBUF_STRIDES)
2567 view->strides = &(view->itemsize);
2568 view->format = NULL;
2569 view->internal = NULL;
Victor Stinner62bb3942012-08-06 00:46:05 +02002570 if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002571 view->format = (char *)self->ob_descr->formats;
Victor Stinner62bb3942012-08-06 00:46:05 +02002572#ifdef Py_UNICODE_WIDE
2573 if (self->ob_descr->typecode == 'u') {
2574 view->format = "w";
2575 }
2576#endif
2577 }
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002579 self->ob_exports++;
2580 return 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00002581}
2582
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002583static void
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +00002584array_buffer_relbuf(arrayobject *self, Py_buffer *view)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00002585{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002586 self->ob_exports--;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00002587}
2588
Roger E. Masse2919eaa1996-12-09 20:10:36 +00002589static PyObject *
Martin v. Löwis99866332002-03-01 10:27:01 +00002590array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Guido van Rossum778983b1993-02-19 15:55:02 +00002591{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002592 array_state *state = find_array_state_by_type(type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002593 int c;
2594 PyObject *initial = NULL, *it = NULL;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002595 const struct arraydescr *descr;
Martin v. Löwis99866332002-03-01 10:27:01 +00002596
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002597 if (type == state->ArrayType && !_PyArg_NoKeywords("array.array", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002598 return NULL;
Martin v. Löwis99866332002-03-01 10:27:01 +00002599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002600 if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial))
2601 return NULL;
Raymond Hettinger84fc9aa2003-04-24 10:41:55 +00002602
Steve Dowerb82e17e2019-05-23 08:45:22 -07002603 if (PySys_Audit("array.__new__", "CO",
2604 c, initial ? initial : Py_None) < 0) {
2605 return NULL;
2606 }
2607
Alexandre Vassalotti9730e332013-11-29 20:47:15 -08002608 if (initial && c != 'u') {
2609 if (PyUnicode_Check(initial)) {
2610 PyErr_Format(PyExc_TypeError, "cannot use a str to initialize "
2611 "an array with typecode '%c'", c);
2612 return NULL;
2613 }
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002614 else if (array_Check(initial, state) &&
Alexandre Vassalotti9730e332013-11-29 20:47:15 -08002615 ((arrayobject*)initial)->ob_descr->typecode == 'u') {
2616 PyErr_Format(PyExc_TypeError, "cannot use a unicode array to "
2617 "initialize an array with typecode '%c'", c);
2618 return NULL;
2619 }
2620 }
2621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002622 if (!(initial == NULL || PyList_Check(initial)
2623 || PyByteArray_Check(initial)
2624 || PyBytes_Check(initial)
2625 || PyTuple_Check(initial)
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002626 || ((c=='u') && PyUnicode_Check(initial))
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002627 || (array_Check(initial, state)
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002628 && c == ((arrayobject*)initial)->ob_descr->typecode))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002629 it = PyObject_GetIter(initial);
2630 if (it == NULL)
2631 return NULL;
2632 /* We set initial to NULL so that the subsequent code
2633 will create an empty array of the appropriate type
2634 and afterwards we can use array_iter_extend to populate
2635 the array.
2636 */
2637 initial = NULL;
2638 }
2639 for (descr = descriptors; descr->typecode != '\0'; descr++) {
2640 if (descr->typecode == c) {
2641 PyObject *a;
2642 Py_ssize_t len;
Martin v. Löwis99866332002-03-01 10:27:01 +00002643
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002644 if (initial == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002645 len = 0;
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002646 else if (PyList_Check(initial))
2647 len = PyList_GET_SIZE(initial);
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002648 else if (PyTuple_Check(initial) || array_Check(initial, state))
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002649 len = Py_SIZE(initial);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002650 else
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002651 len = 0;
Martin v. Löwis99866332002-03-01 10:27:01 +00002652
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002653 a = newarrayobject(type, len, descr);
2654 if (a == NULL)
2655 return NULL;
2656
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002657 if (len > 0 && !array_Check(initial, state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002658 Py_ssize_t i;
2659 for (i = 0; i < len; i++) {
2660 PyObject *v =
2661 PySequence_GetItem(initial, i);
2662 if (v == NULL) {
2663 Py_DECREF(a);
2664 return NULL;
2665 }
2666 if (setarrayitem(a, i, v) != 0) {
2667 Py_DECREF(v);
2668 Py_DECREF(a);
2669 return NULL;
2670 }
2671 Py_DECREF(v);
2672 }
2673 }
2674 else if (initial != NULL && (PyByteArray_Check(initial) ||
2675 PyBytes_Check(initial))) {
Serhiy Storchaka04e6dba2015-04-04 17:06:55 +03002676 PyObject *v;
Brett Cannon1eb32c22014-10-10 16:26:45 -04002677 v = array_array_frombytes((arrayobject *)a,
Serhiy Storchaka04e6dba2015-04-04 17:06:55 +03002678 initial);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002679 if (v == NULL) {
2680 Py_DECREF(a);
2681 return NULL;
2682 }
2683 Py_DECREF(v);
2684 }
2685 else if (initial != NULL && PyUnicode_Check(initial)) {
Victor Stinner1fbcaef2011-09-30 01:54:04 +02002686 Py_ssize_t n;
Inada Naokid5d9a712020-05-11 15:37:25 +09002687 wchar_t *ustr = PyUnicode_AsWideCharString(initial, &n);
Victor Stinner62bb3942012-08-06 00:46:05 +02002688 if (ustr == NULL) {
Victor Stinner1fbcaef2011-09-30 01:54:04 +02002689 Py_DECREF(a);
2690 return NULL;
2691 }
Victor Stinner62bb3942012-08-06 00:46:05 +02002692
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002693 if (n > 0) {
2694 arrayobject *self = (arrayobject *)a;
Inada Naokid5d9a712020-05-11 15:37:25 +09002695 // self->ob_item may be NULL but it is safe.
2696 PyMem_Free(self->ob_item);
2697 self->ob_item = (char *)ustr;
2698 Py_SET_SIZE(self, n);
2699 self->allocated = n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002700 }
2701 }
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002702 else if (initial != NULL && array_Check(initial, state) && len > 0) {
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002703 arrayobject *self = (arrayobject *)a;
2704 arrayobject *other = (arrayobject *)initial;
2705 memcpy(self->ob_item, other->ob_item, len * other->ob_descr->itemsize);
2706 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002707 if (it != NULL) {
2708 if (array_iter_extend((arrayobject *)a, it) == -1) {
2709 Py_DECREF(it);
2710 Py_DECREF(a);
2711 return NULL;
2712 }
2713 Py_DECREF(it);
2714 }
2715 return a;
2716 }
2717 }
2718 PyErr_SetString(PyExc_ValueError,
Meador Inge1c9f0c92011-09-20 19:55:51 -05002719 "bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002720 return NULL;
Guido van Rossum778983b1993-02-19 15:55:02 +00002721}
2722
Guido van Rossum778983b1993-02-19 15:55:02 +00002723
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002724PyDoc_STRVAR(module_doc,
Martin v. Löwis99866332002-03-01 10:27:01 +00002725"This module defines an object type which can efficiently represent\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002726an array of basic values: characters, integers, floating point\n\
2727numbers. Arrays are sequence types and behave very much like lists,\n\
Alexandre Vassalotti9730e332013-11-29 20:47:15 -08002728except that the type of objects stored in them is constrained.\n");
2729
2730PyDoc_STRVAR(arraytype_doc,
2731"array(typecode [, initializer]) -> array\n\
2732\n\
2733Return a new array whose items are restricted by typecode, and\n\
2734initialized from the optional initializer value, which must be a list,\n\
2735string or iterable over elements of the appropriate type.\n\
2736\n\
2737Arrays represent basic values and behave very much like lists, except\n\
2738the type of objects stored in them is constrained. The type is specified\n\
2739at object creation time by using a type code, which is a single character.\n\
2740The following type codes are defined:\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002741\n\
oldkaa0735f2018-02-02 16:52:55 +08002742 Type code C Type Minimum size in bytes\n\
2743 'b' signed integer 1\n\
2744 'B' unsigned integer 1\n\
2745 'u' Unicode character 2 (see note)\n\
2746 'h' signed integer 2\n\
2747 'H' unsigned integer 2\n\
2748 'i' signed integer 2\n\
2749 'I' unsigned integer 2\n\
2750 'l' signed integer 4\n\
2751 'L' unsigned integer 4\n\
2752 'q' signed integer 8 (see note)\n\
2753 'Q' unsigned integer 8 (see note)\n\
2754 'f' floating point 4\n\
2755 'd' floating point 8\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002756\n\
oldkaa0735f2018-02-02 16:52:55 +08002757NOTE: The 'u' typecode corresponds to Python's unicode character. On\n\
Victor Stinner62bb3942012-08-06 00:46:05 +02002758narrow builds this is 2-bytes on wide builds this is 4-bytes.\n\
2759\n\
oldkaa0735f2018-02-02 16:52:55 +08002760NOTE: The 'q' and 'Q' type codes are only available if the platform\n\
2761C compiler used to build Python supports 'long long', or, on Windows,\n\
Meador Inge1c9f0c92011-09-20 19:55:51 -05002762'__int64'.\n\
2763\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002764Methods:\n\
2765\n\
2766append() -- append a new item to the end of the array\n\
2767buffer_info() -- return information giving the current memory info\n\
2768byteswap() -- byteswap all the items of the array\n\
Mark Dickinson934896d2009-02-21 20:59:32 +00002769count() -- return number of occurrences of an object\n\
Raymond Hettinger49f9bd12004-03-14 05:43:59 +00002770extend() -- extend array by appending multiple elements from an iterable\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002771fromfile() -- read items from a file object\n\
2772fromlist() -- append items from the list\n\
Florent Xiclunac45fb252011-10-24 13:14:55 +02002773frombytes() -- append items from the string\n\
Mark Dickinson934896d2009-02-21 20:59:32 +00002774index() -- return index of first occurrence of an object\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002775insert() -- insert a new item into the array at a provided position\n\
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00002776pop() -- remove and return item (default last)\n\
Mark Dickinson934896d2009-02-21 20:59:32 +00002777remove() -- remove first occurrence of an object\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002778reverse() -- reverse the order of the items in the array\n\
2779tofile() -- write all items to a file object\n\
2780tolist() -- return the array converted to an ordinary list\n\
Florent Xiclunac45fb252011-10-24 13:14:55 +02002781tobytes() -- return the array converted to a string\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002782\n\
Martin v. Löwis99866332002-03-01 10:27:01 +00002783Attributes:\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002784\n\
2785typecode -- the typecode character used to create the array\n\
2786itemsize -- the length in bytes of one array item\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002787");
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002788
Raymond Hettinger625812f2003-01-07 01:58:52 +00002789static PyObject *array_iter(arrayobject *ao);
2790
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002791static struct PyMemberDef array_members[] = {
2792 {"__weaklistoffset__", T_PYSSIZET, offsetof(arrayobject, weakreflist), READONLY},
2793 {NULL},
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002794};
2795
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002796static PyType_Slot array_slots[] = {
2797 {Py_tp_dealloc, array_dealloc},
2798 {Py_tp_repr, array_repr},
2799 {Py_tp_getattro, PyObject_GenericGetAttr},
2800 {Py_tp_doc, (void *)arraytype_doc},
2801 {Py_tp_richcompare, array_richcompare},
2802 {Py_tp_iter, array_iter},
2803 {Py_tp_methods, array_methods},
2804 {Py_tp_members, array_members},
2805 {Py_tp_getset, array_getsets},
2806 {Py_tp_alloc, PyType_GenericAlloc},
2807 {Py_tp_new, array_new},
2808 {Py_tp_free, PyObject_Del},
2809
2810 /* as sequence */
2811 {Py_sq_length, array_length},
2812 {Py_sq_concat, array_concat},
2813 {Py_sq_repeat, array_repeat},
2814 {Py_sq_item, array_item},
2815 {Py_sq_ass_item, array_ass_item},
2816 {Py_sq_contains, array_contains},
2817 {Py_sq_inplace_concat, array_inplace_concat},
2818 {Py_sq_inplace_repeat, array_inplace_repeat},
2819
2820 /* as mapping */
2821 {Py_mp_length, array_length},
2822 {Py_mp_subscript, array_subscr},
2823 {Py_mp_ass_subscript, array_ass_subscr},
2824
2825 /* as buffer */
2826 {Py_bf_getbuffer, array_buffer_getbuf},
2827 {Py_bf_releasebuffer, array_buffer_relbuf},
2828
2829 {0, NULL},
2830};
2831
2832static PyType_Spec array_spec = {
2833 .name = "array.array",
2834 .basicsize = sizeof(arrayobject),
2835 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
2836 .slots = array_slots,
2837};
Raymond Hettinger625812f2003-01-07 01:58:52 +00002838
2839/*********************** Array Iterator **************************/
2840
Brett Cannon1eb32c22014-10-10 16:26:45 -04002841/*[clinic input]
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002842class array.arrayiterator "arrayiterobject *" "find_array_state_by_type(type)->ArrayIterType"
Brett Cannon1eb32c22014-10-10 16:26:45 -04002843[clinic start generated code]*/
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002844/*[clinic end generated code: output=da39a3ee5e6b4b0d input=fb46d5ef98dd95ff]*/
Raymond Hettinger625812f2003-01-07 01:58:52 +00002845
2846static PyObject *
2847array_iter(arrayobject *ao)
2848{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002849 array_state *state = find_array_state_by_type(Py_TYPE(ao));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002850 arrayiterobject *it;
Raymond Hettinger625812f2003-01-07 01:58:52 +00002851
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002852 if (!array_Check(ao, state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002853 PyErr_BadInternalCall();
2854 return NULL;
2855 }
Raymond Hettinger625812f2003-01-07 01:58:52 +00002856
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002857 it = PyObject_GC_New(arrayiterobject, state->ArrayIterType);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002858 if (it == NULL)
2859 return NULL;
Raymond Hettinger625812f2003-01-07 01:58:52 +00002860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002861 Py_INCREF(ao);
2862 it->ao = ao;
2863 it->index = 0;
2864 it->getitem = ao->ob_descr->getitem;
2865 PyObject_GC_Track(it);
2866 return (PyObject *)it;
Raymond Hettinger625812f2003-01-07 01:58:52 +00002867}
2868
2869static PyObject *
Raymond Hettinger625812f2003-01-07 01:58:52 +00002870arrayiter_next(arrayiterobject *it)
2871{
Serhiy Storchakaab0d1982016-03-30 21:11:16 +03002872 arrayobject *ao;
2873
2874 assert(it != NULL);
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002875#ifndef NDEBUG
2876 array_state *state = find_array_state_by_type(Py_TYPE(it));
2877 assert(PyObject_TypeCheck(it, state->ArrayIterType));
2878#endif
Serhiy Storchakaab0d1982016-03-30 21:11:16 +03002879 ao = it->ao;
2880 if (ao == NULL) {
2881 return NULL;
2882 }
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002883#ifndef NDEBUG
2884 assert(array_Check(ao, state));
2885#endif
Serhiy Storchakaab0d1982016-03-30 21:11:16 +03002886 if (it->index < Py_SIZE(ao)) {
2887 return (*it->getitem)(ao, it->index++);
2888 }
2889 it->ao = NULL;
2890 Py_DECREF(ao);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002891 return NULL;
Raymond Hettinger625812f2003-01-07 01:58:52 +00002892}
2893
2894static void
2895arrayiter_dealloc(arrayiterobject *it)
2896{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002897 PyTypeObject *tp = Py_TYPE(it);
2898
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002899 PyObject_GC_UnTrack(it);
2900 Py_XDECREF(it->ao);
2901 PyObject_GC_Del(it);
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002902 Py_DECREF(tp);
Raymond Hettinger625812f2003-01-07 01:58:52 +00002903}
2904
2905static int
2906arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
2907{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002908 Py_VISIT(it->ao);
2909 return 0;
Raymond Hettinger625812f2003-01-07 01:58:52 +00002910}
2911
Brett Cannon1eb32c22014-10-10 16:26:45 -04002912/*[clinic input]
2913array.arrayiterator.__reduce__
2914
2915Return state information for pickling.
2916[clinic start generated code]*/
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002917
2918static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04002919array_arrayiterator___reduce___impl(arrayiterobject *self)
2920/*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/
2921{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02002922 _Py_IDENTIFIER(iter);
2923 PyObject *func = _PyEval_GetBuiltinId(&PyId_iter);
Serhiy Storchakaab0d1982016-03-30 21:11:16 +03002924 if (self->ao == NULL) {
2925 return Py_BuildValue("N(())", func);
2926 }
2927 return Py_BuildValue("N(O)n", func, self->ao, self->index);
Brett Cannon1eb32c22014-10-10 16:26:45 -04002928}
2929
2930/*[clinic input]
2931array.arrayiterator.__setstate__
2932
2933 state: object
2934 /
2935
2936Set state information for unpickling.
2937[clinic start generated code]*/
2938
2939static PyObject *
2940array_arrayiterator___setstate__(arrayiterobject *self, PyObject *state)
2941/*[clinic end generated code: output=397da9904e443cbe input=f47d5ceda19e787b]*/
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002942{
2943 Py_ssize_t index = PyLong_AsSsize_t(state);
2944 if (index == -1 && PyErr_Occurred())
2945 return NULL;
2946 if (index < 0)
2947 index = 0;
Brett Cannon1eb32c22014-10-10 16:26:45 -04002948 else if (index > Py_SIZE(self->ao))
2949 index = Py_SIZE(self->ao); /* iterator exhausted */
2950 self->index = index;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002951 Py_RETURN_NONE;
2952}
2953
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002954static PyMethodDef arrayiter_methods[] = {
Brett Cannon1eb32c22014-10-10 16:26:45 -04002955 ARRAY_ARRAYITERATOR___REDUCE___METHODDEF
2956 ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002957 {NULL, NULL} /* sentinel */
2958};
2959
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002960static PyType_Slot arrayiter_slots[] = {
2961 {Py_tp_dealloc, arrayiter_dealloc},
2962 {Py_tp_getattro, PyObject_GenericGetAttr},
2963 {Py_tp_traverse, arrayiter_traverse},
2964 {Py_tp_iter, PyObject_SelfIter},
2965 {Py_tp_iternext, arrayiter_next},
2966 {Py_tp_methods, arrayiter_methods},
2967 {0, NULL},
2968};
2969
2970static PyType_Spec arrayiter_spec = {
2971 .name = "array.arrayiterator",
2972 .basicsize = sizeof(arrayiterobject),
2973 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
2974 .slots = arrayiter_slots,
Raymond Hettinger625812f2003-01-07 01:58:52 +00002975};
2976
2977
2978/*********************** Install Module **************************/
2979
Martin v. Löwis99866332002-03-01 10:27:01 +00002980/* No functions in array module. */
2981static PyMethodDef a_methods[] = {
Brett Cannon1eb32c22014-10-10 16:26:45 -04002982 ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF
Martin v. Löwis99866332002-03-01 10:27:01 +00002983 {NULL, NULL, 0, NULL} /* Sentinel */
2984};
2985
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002986#define CREATE_TYPE(module, type, spec) \
2987do { \
2988 type = (PyTypeObject *)PyType_FromModuleAndSpec(m, spec, NULL); \
2989 if (type == NULL) { \
2990 return -1; \
2991 } \
2992} while (0)
2993
Nick Coghland5cacbb2015-05-23 22:24:10 +10002994static int
2995array_modexec(PyObject *m)
Guido van Rossum778983b1993-02-19 15:55:02 +00002996{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002997 array_state *state = get_array_state(m);
Georg Brandl4cb0de22011-09-28 21:49:49 +02002998 char buffer[Py_ARRAY_LENGTH(descriptors)], *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002999 PyObject *typecodes;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003000 const struct arraydescr *descr;
Fred Drake0d40ba42000-02-04 20:33:49 +00003001
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003002 CREATE_TYPE(m, state->ArrayType, &array_spec);
3003 CREATE_TYPE(m, state->ArrayIterType, &arrayiter_spec);
3004 Py_SET_TYPE(state->ArrayIterType, &PyType_Type);
Fred Drakef4e34842002-04-01 03:45:06 +00003005
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003006 Py_INCREF((PyObject *)state->ArrayType);
3007 if (PyModule_AddObject(m, "ArrayType", (PyObject *)state->ArrayType) < 0) {
3008 Py_DECREF((PyObject *)state->ArrayType);
Marco Paolinib44ffc82019-11-15 08:42:51 +00003009 return -1;
3010 }
Pablo Galindoe51dd9d2020-07-05 22:43:14 +01003011
3012 PyObject *abc_mod = PyImport_ImportModule("collections.abc");
3013 if (!abc_mod) {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003014 Py_DECREF((PyObject *)state->ArrayType);
Pablo Galindoe51dd9d2020-07-05 22:43:14 +01003015 return -1;
3016 }
3017 PyObject *mutablesequence = PyObject_GetAttrString(abc_mod, "MutableSequence");
3018 Py_DECREF(abc_mod);
3019 if (!mutablesequence) {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003020 Py_DECREF((PyObject *)state->ArrayType);
Pablo Galindoe51dd9d2020-07-05 22:43:14 +01003021 return -1;
3022 }
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003023 PyObject *res = PyObject_CallMethod(mutablesequence, "register", "O",
3024 (PyObject *)state->ArrayType);
Pablo Galindoe51dd9d2020-07-05 22:43:14 +01003025 Py_DECREF(mutablesequence);
3026 if (!res) {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003027 Py_DECREF((PyObject *)state->ArrayType);
Pablo Galindoe51dd9d2020-07-05 22:43:14 +01003028 return -1;
3029 }
3030 Py_DECREF(res);
3031
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003032 if (PyModule_AddType(m, state->ArrayType) < 0) {
Marco Paolinib44ffc82019-11-15 08:42:51 +00003033 return -1;
3034 }
Travis E. Oliphantd5c0add2007-10-12 22:05:15 +00003035
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003036 p = buffer;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003037 for (descr = descriptors; descr->typecode != '\0'; descr++) {
3038 *p++ = (char)descr->typecode;
3039 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003040 typecodes = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Marco Paolinib44ffc82019-11-15 08:42:51 +00003041 if (PyModule_AddObject(m, "typecodes", typecodes) < 0) {
3042 Py_XDECREF(typecodes);
3043 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003044 }
Marco Paolinib44ffc82019-11-15 08:42:51 +00003045
Nick Coghland5cacbb2015-05-23 22:24:10 +10003046 return 0;
3047}
3048
3049static PyModuleDef_Slot arrayslots[] = {
3050 {Py_mod_exec, array_modexec},
3051 {0, NULL}
3052};
3053
3054
3055static struct PyModuleDef arraymodule = {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003056 .m_base = PyModuleDef_HEAD_INIT,
3057 .m_name = "array",
3058 .m_size = sizeof(array_state),
3059 .m_doc = module_doc,
3060 .m_methods = a_methods,
3061 .m_slots = arrayslots,
Nick Coghland5cacbb2015-05-23 22:24:10 +10003062};
3063
3064
3065PyMODINIT_FUNC
3066PyInit_array(void)
3067{
3068 return PyModuleDef_Init(&arraymodule);
Guido van Rossum778983b1993-02-19 15:55:02 +00003069}