blob: fb9ebbe9f4870f00afaaea4a1bf741f4df5b7c46 [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
Zackery Spytzafd12652021-04-02 09:28:35 -06001139 start: slice_index(accept={int}) = 0
1140 stop: slice_index(accept={int}, c_default="PY_SSIZE_T_MAX") = sys.maxsize
Brett Cannon1eb32c22014-10-10 16:26:45 -04001141 /
1142
1143Return index of first occurrence of v in the array.
Zackery Spytzafd12652021-04-02 09:28:35 -06001144
1145Raise ValueError if the value is not present.
Brett Cannon1eb32c22014-10-10 16:26:45 -04001146[clinic start generated code]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001147
1148static PyObject *
Zackery Spytzafd12652021-04-02 09:28:35 -06001149array_array_index_impl(arrayobject *self, PyObject *v, Py_ssize_t start,
1150 Py_ssize_t stop)
1151/*[clinic end generated code: output=c45e777880c99f52 input=089dff7baa7e5a7e]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001152{
Zackery Spytzafd12652021-04-02 09:28:35 -06001153 if (start < 0) {
1154 start += Py_SIZE(self);
1155 if (start < 0) {
1156 start = 0;
1157 }
1158 }
1159 if (stop < 0) {
1160 stop += Py_SIZE(self);
1161 }
1162 // Use Py_SIZE() for every iteration in case the array is mutated
1163 // during PyObject_RichCompareBool()
1164 for (Py_ssize_t i = start; i < stop && i < Py_SIZE(self); i++) {
Victor Stinner0b142e22013-07-17 23:01:30 +02001165 PyObject *selfi;
1166 int cmp;
1167
1168 selfi = getarrayitem((PyObject *)self, i);
1169 if (selfi == NULL)
1170 return NULL;
1171 cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 Py_DECREF(selfi);
1173 if (cmp > 0) {
WildCard651d3dad52020-06-23 09:21:16 -04001174 return PyLong_FromSsize_t(i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 }
1176 else if (cmp < 0)
1177 return NULL;
1178 }
Jim Fasarakis-Hilliarda4095ef2017-05-29 20:43:39 +03001179 PyErr_SetString(PyExc_ValueError, "array.index(x): x not in array");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 return NULL;
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001181}
1182
Raymond Hettinger625812f2003-01-07 01:58:52 +00001183static int
1184array_contains(arrayobject *self, PyObject *v)
1185{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 Py_ssize_t i;
1187 int cmp;
Raymond Hettinger625812f2003-01-07 01:58:52 +00001188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(self); i++) {
1190 PyObject *selfi = getarrayitem((PyObject *)self, i);
Victor Stinner0b142e22013-07-17 23:01:30 +02001191 if (selfi == NULL)
Victor Stinner4755bea2013-07-18 01:12:35 +02001192 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
1194 Py_DECREF(selfi);
1195 }
1196 return cmp;
Raymond Hettinger625812f2003-01-07 01:58:52 +00001197}
1198
Brett Cannon1eb32c22014-10-10 16:26:45 -04001199/*[clinic input]
1200array.array.remove
1201
1202 v: object
1203 /
1204
1205Remove the first occurrence of v in the array.
1206[clinic start generated code]*/
1207
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001208static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001209array_array_remove(arrayobject *self, PyObject *v)
1210/*[clinic end generated code: output=bef06be9fdf9dceb input=0b1e5aed25590027]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001211{
sthaa3ecb82019-03-20 20:49:39 +01001212 Py_ssize_t i;
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 for (i = 0; i < Py_SIZE(self); i++) {
Victor Stinner0b142e22013-07-17 23:01:30 +02001215 PyObject *selfi;
1216 int cmp;
1217
1218 selfi = getarrayitem((PyObject *)self,i);
1219 if (selfi == NULL)
1220 return NULL;
1221 cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001222 Py_DECREF(selfi);
1223 if (cmp > 0) {
Martin Panter996d72b2016-07-25 02:21:14 +00001224 if (array_del_slice(self, i, i+1) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 return NULL;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001226 Py_RETURN_NONE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001227 }
1228 else if (cmp < 0)
1229 return NULL;
1230 }
Jim Fasarakis-Hilliarda4095ef2017-05-29 20:43:39 +03001231 PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in array");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 return NULL;
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001233}
1234
Brett Cannon1eb32c22014-10-10 16:26:45 -04001235/*[clinic input]
1236array.array.pop
1237
1238 i: Py_ssize_t = -1
1239 /
1240
1241Return the i-th element and delete it from the array.
1242
1243i defaults to -1.
1244[clinic start generated code]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001245
1246static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001247array_array_pop_impl(arrayobject *self, Py_ssize_t i)
1248/*[clinic end generated code: output=bc1f0c54fe5308e4 input=8e5feb4c1a11cd44]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001249{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 PyObject *v;
Brett Cannon1eb32c22014-10-10 16:26:45 -04001251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 if (Py_SIZE(self) == 0) {
1253 /* Special-case most common failure cause */
1254 PyErr_SetString(PyExc_IndexError, "pop from empty array");
1255 return NULL;
1256 }
1257 if (i < 0)
1258 i += Py_SIZE(self);
1259 if (i < 0 || i >= Py_SIZE(self)) {
1260 PyErr_SetString(PyExc_IndexError, "pop index out of range");
1261 return NULL;
1262 }
Victor Stinner0b142e22013-07-17 23:01:30 +02001263 v = getarrayitem((PyObject *)self, i);
1264 if (v == NULL)
1265 return NULL;
Martin Panter996d72b2016-07-25 02:21:14 +00001266 if (array_del_slice(self, i, i+1) != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 Py_DECREF(v);
1268 return NULL;
1269 }
1270 return v;
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001271}
1272
Brett Cannon1eb32c22014-10-10 16:26:45 -04001273/*[clinic input]
1274array.array.extend
1275
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001276 cls: defining_class
Brett Cannon1eb32c22014-10-10 16:26:45 -04001277 bb: object
1278 /
1279
1280Append items to the end of the array.
1281[clinic start generated code]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001282
1283static PyObject *
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001284array_array_extend_impl(arrayobject *self, PyTypeObject *cls, PyObject *bb)
1285/*[clinic end generated code: output=e65eb7588f0bc266 input=8eb6817ec4d2cb62]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001286{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001287 array_state *state = get_array_state_by_class(cls);
1288
1289 if (array_do_extend(state, self, bb) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 return NULL;
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001291 Py_RETURN_NONE;
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001292}
1293
Brett Cannon1eb32c22014-10-10 16:26:45 -04001294/*[clinic input]
1295array.array.insert
1296
1297 i: Py_ssize_t
1298 v: object
1299 /
1300
1301Insert a new item v into the array before position i.
1302[clinic start generated code]*/
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001303
1304static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001305array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v)
1306/*[clinic end generated code: output=5a3648e278348564 input=5577d1b4383e9313]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 return ins(self, i, v);
Guido van Rossum778983b1993-02-19 15:55:02 +00001309}
1310
Brett Cannon1eb32c22014-10-10 16:26:45 -04001311/*[clinic input]
1312array.array.buffer_info
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001313
Brett Cannon1eb32c22014-10-10 16:26:45 -04001314Return a tuple (address, length) giving the current memory address and the length in items of the buffer used to hold array's contents.
1315
1316The length should be multiplied by the itemsize attribute to calculate
1317the buffer length in bytes.
1318[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001319
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001320static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001321array_array_buffer_info_impl(arrayobject *self)
1322/*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=a58bae5c6e1ac6a6]*/
Guido van Rossumde4a4ca1997-08-12 14:55:56 +00001323{
Victor Stinner541067a2013-11-14 01:27:12 +01001324 PyObject *retval = NULL, *v;
1325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 retval = PyTuple_New(2);
1327 if (!retval)
1328 return NULL;
Fred Drake541dc3b2000-06-28 17:49:30 +00001329
Victor Stinner541067a2013-11-14 01:27:12 +01001330 v = PyLong_FromVoidPtr(self->ob_item);
1331 if (v == NULL) {
1332 Py_DECREF(retval);
1333 return NULL;
1334 }
1335 PyTuple_SET_ITEM(retval, 0, v);
1336
Serhiy Storchaka9e941d62016-06-23 23:55:34 +03001337 v = PyLong_FromSsize_t(Py_SIZE(self));
Victor Stinner541067a2013-11-14 01:27:12 +01001338 if (v == NULL) {
1339 Py_DECREF(retval);
1340 return NULL;
1341 }
1342 PyTuple_SET_ITEM(retval, 1, v);
Fred Drake541dc3b2000-06-28 17:49:30 +00001343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 return retval;
Guido van Rossumde4a4ca1997-08-12 14:55:56 +00001345}
1346
Brett Cannon1eb32c22014-10-10 16:26:45 -04001347/*[clinic input]
1348array.array.append
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001349
Brett Cannon1eb32c22014-10-10 16:26:45 -04001350 v: object
1351 /
1352
1353Append new value v to the end of the array.
1354[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001355
Guido van Rossumde4a4ca1997-08-12 14:55:56 +00001356static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001357array_array_append(arrayobject *self, PyObject *v)
1358/*[clinic end generated code: output=745a0669bf8db0e2 input=0b98d9d78e78f0fa]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001359{
Mark Dickinson346f0af2010-08-06 09:36:57 +00001360 return ins(self, Py_SIZE(self), v);
Guido van Rossum778983b1993-02-19 15:55:02 +00001361}
1362
Brett Cannon1eb32c22014-10-10 16:26:45 -04001363/*[clinic input]
1364array.array.byteswap
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001365
Brett Cannon1eb32c22014-10-10 16:26:45 -04001366Byteswap all items of the array.
1367
1368If the items in the array are not 1, 2, 4, or 8 bytes in size, RuntimeError is
1369raised.
1370[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001371
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001372static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001373array_array_byteswap_impl(arrayobject *self)
1374/*[clinic end generated code: output=5f8236cbdf0d90b5 input=6a85591b950a0186]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001375{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 char *p;
1377 Py_ssize_t i;
Fred Drakebf272981999-12-03 17:15:30 +00001378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 switch (self->ob_descr->itemsize) {
1380 case 1:
1381 break;
1382 case 2:
1383 for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 2) {
1384 char p0 = p[0];
1385 p[0] = p[1];
1386 p[1] = p0;
1387 }
1388 break;
1389 case 4:
1390 for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 4) {
1391 char p0 = p[0];
1392 char p1 = p[1];
1393 p[0] = p[3];
1394 p[1] = p[2];
1395 p[2] = p1;
1396 p[3] = p0;
1397 }
1398 break;
1399 case 8:
1400 for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 8) {
1401 char p0 = p[0];
1402 char p1 = p[1];
1403 char p2 = p[2];
1404 char p3 = p[3];
1405 p[0] = p[7];
1406 p[1] = p[6];
1407 p[2] = p[5];
1408 p[3] = p[4];
1409 p[4] = p3;
1410 p[5] = p2;
1411 p[6] = p1;
1412 p[7] = p0;
1413 }
1414 break;
1415 default:
1416 PyErr_SetString(PyExc_RuntimeError,
1417 "don't know how to byteswap this array type");
1418 return NULL;
1419 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001420 Py_RETURN_NONE;
Guido van Rossum778983b1993-02-19 15:55:02 +00001421}
1422
Brett Cannon1eb32c22014-10-10 16:26:45 -04001423/*[clinic input]
1424array.array.reverse
1425
1426Reverse the order of the items in the array.
1427[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001428
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001429static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001430array_array_reverse_impl(arrayobject *self)
1431/*[clinic end generated code: output=c04868b36f6f4089 input=cd904f01b27d966a]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001432{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001433 Py_ssize_t itemsize = self->ob_descr->itemsize;
1434 char *p, *q;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 /* little buffer to hold items while swapping */
1436 char tmp[256]; /* 8 is probably enough -- but why skimp */
1437 assert((size_t)itemsize <= sizeof(tmp));
Guido van Rossume77a7571993-11-03 15:01:26 +00001438
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 if (Py_SIZE(self) > 1) {
1440 for (p = self->ob_item,
1441 q = self->ob_item + (Py_SIZE(self) - 1)*itemsize;
1442 p < q;
1443 p += itemsize, q -= itemsize) {
1444 /* memory areas guaranteed disjoint, so memcpy
1445 * is safe (& memmove may be slower).
1446 */
1447 memcpy(tmp, p, itemsize);
1448 memcpy(p, q, itemsize);
1449 memcpy(q, tmp, itemsize);
1450 }
1451 }
Tim Petersbb307342000-09-10 05:22:54 +00001452
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001453 Py_RETURN_NONE;
Guido van Rossum778983b1993-02-19 15:55:02 +00001454}
Guido van Rossume77a7571993-11-03 15:01:26 +00001455
Brett Cannon1eb32c22014-10-10 16:26:45 -04001456/*[clinic input]
1457array.array.fromfile
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001458
Brett Cannon1eb32c22014-10-10 16:26:45 -04001459 f: object
1460 n: Py_ssize_t
1461 /
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001462
Brett Cannon1eb32c22014-10-10 16:26:45 -04001463Read n objects from the file object f and append them to the end of the array.
1464[clinic start generated code]*/
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001465
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001466static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001467array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n)
1468/*[clinic end generated code: output=ec9f600e10f53510 input=e188afe8e58adf40]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001469{
Serhiy Storchaka04e6dba2015-04-04 17:06:55 +03001470 PyObject *b, *res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 Py_ssize_t itemsize = self->ob_descr->itemsize;
Brett Cannon1eb32c22014-10-10 16:26:45 -04001472 Py_ssize_t nbytes;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001473 _Py_IDENTIFIER(read);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 int not_enough_bytes;
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001475
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001476 if (n < 0) {
1477 PyErr_SetString(PyExc_ValueError, "negative count");
1478 return NULL;
1479 }
1480 if (n > PY_SSIZE_T_MAX / itemsize) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 PyErr_NoMemory();
1482 return NULL;
1483 }
Mark Dickinsonc04ddff2012-10-06 18:04:49 +01001484 nbytes = n * itemsize;
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001485
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001486 b = _PyObject_CallMethodId(f, &PyId_read, "n", nbytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 if (b == NULL)
1488 return NULL;
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001489
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 if (!PyBytes_Check(b)) {
1491 PyErr_SetString(PyExc_TypeError,
1492 "read() didn't return bytes");
1493 Py_DECREF(b);
1494 return NULL;
1495 }
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 not_enough_bytes = (PyBytes_GET_SIZE(b) != nbytes);
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001498
Serhiy Storchaka04e6dba2015-04-04 17:06:55 +03001499 res = array_array_frombytes(self, b);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 Py_DECREF(b);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 if (res == NULL)
1502 return NULL;
Hirokazu Yamamoto54d0df62009-03-06 03:04:07 +00001503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 if (not_enough_bytes) {
1505 PyErr_SetString(PyExc_EOFError,
1506 "read() didn't return enough bytes");
1507 Py_DECREF(res);
1508 return NULL;
1509 }
Guido van Rossum2c94aa52007-05-24 19:02:32 +00001510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 return res;
Guido van Rossum778983b1993-02-19 15:55:02 +00001512}
1513
Brett Cannon1eb32c22014-10-10 16:26:45 -04001514/*[clinic input]
1515array.array.tofile
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001516
Brett Cannon1eb32c22014-10-10 16:26:45 -04001517 f: object
1518 /
1519
1520Write all items (as machine values) to the file object f.
1521[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001522
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001523static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001524array_array_tofile(arrayobject *self, PyObject *f)
1525/*[clinic end generated code: output=3a2cfa8128df0777 input=b0669a484aab0831]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001526{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 Py_ssize_t nbytes = Py_SIZE(self) * self->ob_descr->itemsize;
1528 /* Write 64K blocks at a time */
1529 /* XXX Make the block size settable */
1530 int BLOCKSIZE = 64*1024;
1531 Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1) / BLOCKSIZE;
1532 Py_ssize_t i;
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +00001533
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 if (Py_SIZE(self) == 0)
1535 goto done;
Guido van Rossumb5ddcfd2007-04-11 17:08:28 +00001536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 for (i = 0; i < nblocks; i++) {
1538 char* ptr = self->ob_item + i*BLOCKSIZE;
1539 Py_ssize_t size = BLOCKSIZE;
1540 PyObject *bytes, *res;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001541 _Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001542
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 if (i*BLOCKSIZE + size > nbytes)
1544 size = nbytes - i*BLOCKSIZE;
1545 bytes = PyBytes_FromStringAndSize(ptr, size);
1546 if (bytes == NULL)
1547 return NULL;
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001548 res = _PyObject_CallMethodIdOneArg(f, &PyId_write, bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 Py_DECREF(bytes);
1550 if (res == NULL)
1551 return NULL;
1552 Py_DECREF(res); /* drop write result */
1553 }
Guido van Rossumb5ddcfd2007-04-11 17:08:28 +00001554
1555 done:
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001556 Py_RETURN_NONE;
Guido van Rossum778983b1993-02-19 15:55:02 +00001557}
1558
Brett Cannon1eb32c22014-10-10 16:26:45 -04001559/*[clinic input]
1560array.array.fromlist
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001561
Brett Cannon1eb32c22014-10-10 16:26:45 -04001562 list: object
1563 /
1564
1565Append items to array from list.
1566[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001567
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001568static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001569array_array_fromlist(arrayobject *self, PyObject *list)
1570/*[clinic end generated code: output=26411c2d228a3e3f input=be2605a96c49680f]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001571{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 Py_ssize_t n;
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +00001573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 if (!PyList_Check(list)) {
1575 PyErr_SetString(PyExc_TypeError, "arg must be list");
1576 return NULL;
1577 }
1578 n = PyList_Size(list);
1579 if (n > 0) {
1580 Py_ssize_t i, old_size;
1581 old_size = Py_SIZE(self);
1582 if (array_resize(self, old_size + n) == -1)
1583 return NULL;
1584 for (i = 0; i < n; i++) {
Zackery Spytz99d56b52018-12-08 07:16:55 -07001585 PyObject *v = PyList_GET_ITEM(list, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 if ((*self->ob_descr->setitem)(self,
1587 Py_SIZE(self) - n + i, v) != 0) {
1588 array_resize(self, old_size);
1589 return NULL;
1590 }
Zackery Spytz99d56b52018-12-08 07:16:55 -07001591 if (n != PyList_GET_SIZE(list)) {
1592 PyErr_SetString(PyExc_RuntimeError,
1593 "list changed size during iteration");
1594 array_resize(self, old_size);
1595 return NULL;
1596 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 }
1598 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001599 Py_RETURN_NONE;
Guido van Rossum778983b1993-02-19 15:55:02 +00001600}
1601
Brett Cannon1eb32c22014-10-10 16:26:45 -04001602/*[clinic input]
1603array.array.tolist
1604
1605Convert array to an ordinary list with the same items.
1606[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001607
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001608static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001609array_array_tolist_impl(arrayobject *self)
1610/*[clinic end generated code: output=00b60cc9eab8ef89 input=a8d7784a94f86b53]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001612 PyObject *list = PyList_New(Py_SIZE(self));
1613 Py_ssize_t i;
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +00001614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 if (list == NULL)
1616 return NULL;
1617 for (i = 0; i < Py_SIZE(self); i++) {
1618 PyObject *v = getarrayitem((PyObject *)self, i);
Victor Stinner4755bea2013-07-18 01:12:35 +02001619 if (v == NULL)
1620 goto error;
Zackery Spytz99d56b52018-12-08 07:16:55 -07001621 PyList_SET_ITEM(list, i, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 }
1623 return list;
Victor Stinner4755bea2013-07-18 01:12:35 +02001624
1625error:
1626 Py_DECREF(list);
1627 return NULL;
Guido van Rossum778983b1993-02-19 15:55:02 +00001628}
1629
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001630static PyObject *
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001631frombytes(arrayobject *self, Py_buffer *buffer)
Guido van Rossum778983b1993-02-19 15:55:02 +00001632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 int itemsize = self->ob_descr->itemsize;
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001634 Py_ssize_t n;
1635 if (buffer->itemsize != 1) {
1636 PyBuffer_Release(buffer);
Serhiy Storchakab757c832014-12-05 22:25:22 +02001637 PyErr_SetString(PyExc_TypeError, "a bytes-like object is required");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001638 return NULL;
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001639 }
1640 n = buffer->len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 if (n % itemsize != 0) {
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001642 PyBuffer_Release(buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 PyErr_SetString(PyExc_ValueError,
Serhiy Storchakab757c832014-12-05 22:25:22 +02001644 "bytes length not a multiple of item size");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001645 return NULL;
1646 }
1647 n = n / itemsize;
1648 if (n > 0) {
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001649 Py_ssize_t old_size = Py_SIZE(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001650 if ((n > PY_SSIZE_T_MAX - old_size) ||
1651 ((old_size + n) > PY_SSIZE_T_MAX / itemsize)) {
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001652 PyBuffer_Release(buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001653 return PyErr_NoMemory();
1654 }
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001655 if (array_resize(self, old_size + n) == -1) {
1656 PyBuffer_Release(buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001657 return NULL;
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001658 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659 memcpy(self->ob_item + old_size * itemsize,
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001660 buffer->buf, n * itemsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001661 }
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001662 PyBuffer_Release(buffer);
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001663 Py_RETURN_NONE;
Guido van Rossum778983b1993-02-19 15:55:02 +00001664}
1665
Brett Cannon1eb32c22014-10-10 16:26:45 -04001666/*[clinic input]
Brett Cannon1eb32c22014-10-10 16:26:45 -04001667array.array.frombytes
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001668
Brett Cannon1eb32c22014-10-10 16:26:45 -04001669 buffer: Py_buffer
1670 /
1671
1672Appends 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).
1673[clinic start generated code]*/
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001674
1675static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001676array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer)
1677/*[clinic end generated code: output=d9842c8f7510a516 input=2bbf2b53ebfcc988]*/
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001678{
Brett Cannon1eb32c22014-10-10 16:26:45 -04001679 return frombytes(self, buffer);
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001680}
1681
Brett Cannon1eb32c22014-10-10 16:26:45 -04001682/*[clinic input]
1683array.array.tobytes
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001684
Brett Cannon1eb32c22014-10-10 16:26:45 -04001685Convert the array to an array of machine values and return the bytes representation.
1686[clinic start generated code]*/
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001687
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001688static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001689array_array_tobytes_impl(arrayobject *self)
1690/*[clinic end generated code: output=87318e4edcdc2bb6 input=90ee495f96de34f5]*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001691{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001692 if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
1693 return PyBytes_FromStringAndSize(self->ob_item,
1694 Py_SIZE(self) * self->ob_descr->itemsize);
1695 } else {
1696 return PyErr_NoMemory();
1697 }
Guido van Rossum778983b1993-02-19 15:55:02 +00001698}
1699
Brett Cannon1eb32c22014-10-10 16:26:45 -04001700/*[clinic input]
Brett Cannon1eb32c22014-10-10 16:26:45 -04001701array.array.fromunicode
Antoine Pitrou1ce3eb52010-09-01 20:29:34 +00001702
Inada Naokid5d9a712020-05-11 15:37:25 +09001703 ustr: unicode
Brett Cannon1eb32c22014-10-10 16:26:45 -04001704 /
1705
1706Extends this array with data from the unicode string ustr.
1707
1708The array must be a unicode type array; otherwise a ValueError is raised.
1709Use array.frombytes(ustr.encode(...)) to append Unicode data to an array of
1710some other type.
1711[clinic start generated code]*/
Martin v. Löwis99866332002-03-01 10:27:01 +00001712
Martin v. Löwis99866332002-03-01 10:27:01 +00001713static PyObject *
Inada Naokid5d9a712020-05-11 15:37:25 +09001714array_array_fromunicode_impl(arrayobject *self, PyObject *ustr)
1715/*[clinic end generated code: output=24359f5e001a7f2b input=025db1fdade7a4ce]*/
Martin v. Löwis99866332002-03-01 10:27:01 +00001716{
Inada Naokid5d9a712020-05-11 15:37:25 +09001717 if (self->ob_descr->typecode != 'u') {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001718 PyErr_SetString(PyExc_ValueError,
1719 "fromunicode() may only be called on "
1720 "unicode type arrays");
1721 return NULL;
1722 }
Inada Naokid5d9a712020-05-11 15:37:25 +09001723
1724 Py_ssize_t ustr_length = PyUnicode_AsWideChar(ustr, NULL, 0);
1725 assert(ustr_length > 0);
1726 if (ustr_length > 1) {
1727 ustr_length--; /* trim trailing NUL character */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001728 Py_ssize_t old_size = Py_SIZE(self);
Inada Naokid5d9a712020-05-11 15:37:25 +09001729 if (array_resize(self, old_size + ustr_length) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 return NULL;
Inada Naokid5d9a712020-05-11 15:37:25 +09001731 }
1732
1733 // must not fail
1734 PyUnicode_AsWideChar(
1735 ustr, ((wchar_t *)self->ob_item) + old_size, ustr_length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 }
Martin v. Löwis99866332002-03-01 10:27:01 +00001737
Brett Cannon1eb32c22014-10-10 16:26:45 -04001738 Py_RETURN_NONE;
Martin v. Löwis99866332002-03-01 10:27:01 +00001739}
1740
Brett Cannon1eb32c22014-10-10 16:26:45 -04001741/*[clinic input]
1742array.array.tounicode
Martin v. Löwis99866332002-03-01 10:27:01 +00001743
Brett Cannon1eb32c22014-10-10 16:26:45 -04001744Extends this array with data from the unicode string ustr.
1745
1746Convert the array to a unicode string. The array must be a unicode type array;
1747otherwise a ValueError is raised. Use array.tobytes().decode() to obtain a
1748unicode string from an array of some other type.
1749[clinic start generated code]*/
Martin v. Löwis99866332002-03-01 10:27:01 +00001750
1751static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001752array_array_tounicode_impl(arrayobject *self)
1753/*[clinic end generated code: output=08e442378336e1ef input=127242eebe70b66d]*/
Martin v. Löwis99866332002-03-01 10:27:01 +00001754{
Inada Naokid5d9a712020-05-11 15:37:25 +09001755 if (self->ob_descr->typecode != 'u') {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 PyErr_SetString(PyExc_ValueError,
1757 "tounicode() may only be called on unicode type arrays");
1758 return NULL;
1759 }
Inada Naokid5d9a712020-05-11 15:37:25 +09001760 return PyUnicode_FromWideChar((wchar_t *) self->ob_item, Py_SIZE(self));
Martin v. Löwis99866332002-03-01 10:27:01 +00001761}
1762
Brett Cannon1eb32c22014-10-10 16:26:45 -04001763/*[clinic input]
1764array.array.__sizeof__
Martin v. Löwis99866332002-03-01 10:27:01 +00001765
Brett Cannon1eb32c22014-10-10 16:26:45 -04001766Size of the array in memory, in bytes.
1767[clinic start generated code]*/
Martin v. Löwis99866332002-03-01 10:27:01 +00001768
Meador Inge03b4d502012-08-10 22:35:45 -05001769static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04001770array_array___sizeof___impl(arrayobject *self)
1771/*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/
Meador Inge03b4d502012-08-10 22:35:45 -05001772{
1773 Py_ssize_t res;
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001774 res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * self->ob_descr->itemsize;
Meador Inge03b4d502012-08-10 22:35:45 -05001775 return PyLong_FromSsize_t(res);
1776}
1777
Martin v. Löwis99866332002-03-01 10:27:01 +00001778
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001779/*********************** Pickling support ************************/
1780
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001781static const struct mformatdescr {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 size_t size;
1783 int is_signed;
1784 int is_big_endian;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001785} mformat_descriptors[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 {1, 0, 0}, /* 0: UNSIGNED_INT8 */
1787 {1, 1, 0}, /* 1: SIGNED_INT8 */
1788 {2, 0, 0}, /* 2: UNSIGNED_INT16_LE */
1789 {2, 0, 1}, /* 3: UNSIGNED_INT16_BE */
1790 {2, 1, 0}, /* 4: SIGNED_INT16_LE */
1791 {2, 1, 1}, /* 5: SIGNED_INT16_BE */
1792 {4, 0, 0}, /* 6: UNSIGNED_INT32_LE */
1793 {4, 0, 1}, /* 7: UNSIGNED_INT32_BE */
1794 {4, 1, 0}, /* 8: SIGNED_INT32_LE */
1795 {4, 1, 1}, /* 9: SIGNED_INT32_BE */
1796 {8, 0, 0}, /* 10: UNSIGNED_INT64_LE */
1797 {8, 0, 1}, /* 11: UNSIGNED_INT64_BE */
1798 {8, 1, 0}, /* 12: SIGNED_INT64_LE */
1799 {8, 1, 1}, /* 13: SIGNED_INT64_BE */
1800 {4, 0, 0}, /* 14: IEEE_754_FLOAT_LE */
1801 {4, 0, 1}, /* 15: IEEE_754_FLOAT_BE */
1802 {8, 0, 0}, /* 16: IEEE_754_DOUBLE_LE */
1803 {8, 0, 1}, /* 17: IEEE_754_DOUBLE_BE */
1804 {4, 0, 0}, /* 18: UTF16_LE */
1805 {4, 0, 1}, /* 19: UTF16_BE */
1806 {8, 0, 0}, /* 20: UTF32_LE */
1807 {8, 0, 1} /* 21: UTF32_BE */
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001808};
1809
1810
1811/*
1812 * Internal: This function is used to find the machine format of a given
1813 * array type code. This returns UNKNOWN_FORMAT when the machine format cannot
1814 * be found.
1815 */
1816static enum machine_format_code
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02001817typecode_to_mformat_code(char typecode)
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001818{
Christian Heimes743e0cd2012-10-17 23:52:17 +02001819 const int is_big_endian = PY_BIG_ENDIAN;
1820
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 size_t intsize;
1822 int is_signed;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001823
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 switch (typecode) {
1825 case 'b':
1826 return SIGNED_INT8;
1827 case 'B':
1828 return UNSIGNED_INT8;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001829
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 case 'u':
Victor Stinner62bb3942012-08-06 00:46:05 +02001831 if (sizeof(Py_UNICODE) == 2) {
1832 return UTF16_LE + is_big_endian;
1833 }
1834 if (sizeof(Py_UNICODE) == 4) {
1835 return UTF32_LE + is_big_endian;
1836 }
1837 return UNKNOWN_FORMAT;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 case 'f':
1840 if (sizeof(float) == 4) {
1841 const float y = 16711938.0;
1842 if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
1843 return IEEE_754_FLOAT_BE;
1844 if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
1845 return IEEE_754_FLOAT_LE;
1846 }
1847 return UNKNOWN_FORMAT;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 case 'd':
1850 if (sizeof(double) == 8) {
1851 const double x = 9006104071832581.0;
1852 if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
1853 return IEEE_754_DOUBLE_BE;
1854 if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
1855 return IEEE_754_DOUBLE_LE;
1856 }
1857 return UNKNOWN_FORMAT;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 /* Integers */
1860 case 'h':
1861 intsize = sizeof(short);
1862 is_signed = 1;
1863 break;
1864 case 'H':
1865 intsize = sizeof(short);
1866 is_signed = 0;
1867 break;
1868 case 'i':
1869 intsize = sizeof(int);
1870 is_signed = 1;
1871 break;
1872 case 'I':
1873 intsize = sizeof(int);
1874 is_signed = 0;
1875 break;
1876 case 'l':
1877 intsize = sizeof(long);
1878 is_signed = 1;
1879 break;
1880 case 'L':
1881 intsize = sizeof(long);
1882 is_signed = 0;
1883 break;
Meador Inge1c9f0c92011-09-20 19:55:51 -05001884 case 'q':
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001885 intsize = sizeof(long long);
Meador Inge1c9f0c92011-09-20 19:55:51 -05001886 is_signed = 1;
1887 break;
1888 case 'Q':
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001889 intsize = sizeof(long long);
Meador Inge1c9f0c92011-09-20 19:55:51 -05001890 is_signed = 0;
1891 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 default:
1893 return UNKNOWN_FORMAT;
1894 }
1895 switch (intsize) {
1896 case 2:
1897 return UNSIGNED_INT16_LE + is_big_endian + (2 * is_signed);
1898 case 4:
1899 return UNSIGNED_INT32_LE + is_big_endian + (2 * is_signed);
1900 case 8:
1901 return UNSIGNED_INT64_LE + is_big_endian + (2 * is_signed);
1902 default:
1903 return UNKNOWN_FORMAT;
1904 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001905}
1906
1907/* Forward declaration. */
1908static PyObject *array_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
1909
1910/*
1911 * Internal: This function wraps the array constructor--i.e., array_new()--to
1912 * allow the creation of array objects from C code without having to deal
1913 * directly the tuple argument of array_new(). The typecode argument is a
1914 * Unicode character value, like 'i' or 'f' for example, representing an array
1915 * type code. The items argument is a bytes or a list object from which
1916 * contains the initial value of the array.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 *
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001918 * On success, this functions returns the array object created. Otherwise,
1919 * NULL is returned to indicate a failure.
1920 */
1921static PyObject *
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02001922make_array(PyTypeObject *arraytype, char typecode, PyObject *items)
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001923{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 PyObject *new_args;
1925 PyObject *array_obj;
1926 PyObject *typecode_obj;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 assert(arraytype != NULL);
1929 assert(items != NULL);
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001930
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02001931 typecode_obj = PyUnicode_FromOrdinal(typecode);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 if (typecode_obj == NULL)
1933 return NULL;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001934
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 new_args = PyTuple_New(2);
Mat M56935a52017-11-14 01:00:54 -05001936 if (new_args == NULL) {
1937 Py_DECREF(typecode_obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 return NULL;
Mat M56935a52017-11-14 01:00:54 -05001939 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 Py_INCREF(items);
1941 PyTuple_SET_ITEM(new_args, 0, typecode_obj);
1942 PyTuple_SET_ITEM(new_args, 1, items);
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001944 array_obj = array_new(arraytype, new_args, NULL);
1945 Py_DECREF(new_args);
1946 if (array_obj == NULL)
1947 return NULL;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 return array_obj;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001950}
1951
1952/*
1953 * This functions is a special constructor used when unpickling an array. It
1954 * provides a portable way to rebuild an array from its memory representation.
1955 */
Brett Cannon1eb32c22014-10-10 16:26:45 -04001956/*[clinic input]
1957array._array_reconstructor
1958
1959 arraytype: object(type="PyTypeObject *")
Larry Hastingsdbfdc382015-05-04 06:59:46 -07001960 typecode: int(accept={str})
Brett Cannon1eb32c22014-10-10 16:26:45 -04001961 mformat_code: int(type="enum machine_format_code")
1962 items: object
1963 /
1964
1965Internal. Used for pickling support.
1966[clinic start generated code]*/
1967
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001968static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001969array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype,
Larry Hastings89964c42015-04-14 18:07:59 -04001970 int typecode,
1971 enum machine_format_code mformat_code,
1972 PyObject *items)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03001973/*[clinic end generated code: output=e05263141ba28365 input=2464dc8f4c7736b5]*/
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001974{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001975 array_state *state = get_array_state(module);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 PyObject *converted_items;
1977 PyObject *result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001978 const struct arraydescr *descr;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00001979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001980 if (!PyType_Check(arraytype)) {
1981 PyErr_Format(PyExc_TypeError,
Sylvaina90e64b2017-03-29 20:09:22 +02001982 "first argument must be a type object, not %.200s",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 Py_TYPE(arraytype)->tp_name);
1984 return NULL;
1985 }
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001986 if (!PyType_IsSubtype(arraytype, state->ArrayType)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001987 PyErr_Format(PyExc_TypeError,
1988 "%.200s is not a subtype of %.200s",
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01001989 arraytype->tp_name, state->ArrayType->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 return NULL;
1991 }
1992 for (descr = descriptors; descr->typecode != '\0'; descr++) {
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02001993 if ((int)descr->typecode == typecode)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001994 break;
1995 }
1996 if (descr->typecode == '\0') {
1997 PyErr_SetString(PyExc_ValueError,
1998 "second argument must be a valid type code");
1999 return NULL;
2000 }
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002001 if (mformat_code < MACHINE_FORMAT_CODE_MIN ||
2002 mformat_code > MACHINE_FORMAT_CODE_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 PyErr_SetString(PyExc_ValueError,
2004 "third argument must be a valid machine format code.");
2005 return NULL;
2006 }
2007 if (!PyBytes_Check(items)) {
2008 PyErr_Format(PyExc_TypeError,
2009 "fourth argument should be bytes, not %.200s",
2010 Py_TYPE(items)->tp_name);
2011 return NULL;
2012 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 /* Fast path: No decoding has to be done. */
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002015 if (mformat_code == typecode_to_mformat_code((char)typecode) ||
2016 mformat_code == UNKNOWN_FORMAT) {
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02002017 return make_array(arraytype, (char)typecode, items);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002020 /* Slow path: Decode the byte string according to the given machine
2021 * format code. This occurs when the computer unpickling the array
2022 * object is architecturally different from the one that pickled the
2023 * array.
2024 */
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002025 if (Py_SIZE(items) % mformat_descriptors[mformat_code].size != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 PyErr_SetString(PyExc_ValueError,
2027 "string length not a multiple of item size");
2028 return NULL;
2029 }
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002030 switch (mformat_code) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002031 case IEEE_754_FLOAT_LE:
2032 case IEEE_754_FLOAT_BE: {
sthaa3ecb82019-03-20 20:49:39 +01002033 Py_ssize_t i;
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002034 int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002035 Py_ssize_t itemcount = Py_SIZE(items) / 4;
2036 const unsigned char *memstr =
2037 (unsigned char *)PyBytes_AS_STRING(items);
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002039 converted_items = PyList_New(itemcount);
2040 if (converted_items == NULL)
2041 return NULL;
2042 for (i = 0; i < itemcount; i++) {
2043 PyObject *pyfloat = PyFloat_FromDouble(
2044 _PyFloat_Unpack4(&memstr[i * 4], le));
2045 if (pyfloat == NULL) {
2046 Py_DECREF(converted_items);
2047 return NULL;
2048 }
2049 PyList_SET_ITEM(converted_items, i, pyfloat);
2050 }
2051 break;
2052 }
2053 case IEEE_754_DOUBLE_LE:
2054 case IEEE_754_DOUBLE_BE: {
sthaa3ecb82019-03-20 20:49:39 +01002055 Py_ssize_t i;
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002056 int le = (mformat_code == IEEE_754_DOUBLE_LE) ? 1 : 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002057 Py_ssize_t itemcount = Py_SIZE(items) / 8;
2058 const unsigned char *memstr =
2059 (unsigned char *)PyBytes_AS_STRING(items);
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 converted_items = PyList_New(itemcount);
2062 if (converted_items == NULL)
2063 return NULL;
2064 for (i = 0; i < itemcount; i++) {
2065 PyObject *pyfloat = PyFloat_FromDouble(
2066 _PyFloat_Unpack8(&memstr[i * 8], le));
2067 if (pyfloat == NULL) {
2068 Py_DECREF(converted_items);
2069 return NULL;
2070 }
2071 PyList_SET_ITEM(converted_items, i, pyfloat);
2072 }
2073 break;
2074 }
2075 case UTF16_LE:
2076 case UTF16_BE: {
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002077 int byteorder = (mformat_code == UTF16_LE) ? -1 : 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 converted_items = PyUnicode_DecodeUTF16(
2079 PyBytes_AS_STRING(items), Py_SIZE(items),
2080 "strict", &byteorder);
2081 if (converted_items == NULL)
2082 return NULL;
2083 break;
2084 }
2085 case UTF32_LE:
2086 case UTF32_BE: {
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002087 int byteorder = (mformat_code == UTF32_LE) ? -1 : 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 converted_items = PyUnicode_DecodeUTF32(
2089 PyBytes_AS_STRING(items), Py_SIZE(items),
2090 "strict", &byteorder);
2091 if (converted_items == NULL)
2092 return NULL;
2093 break;
2094 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 case UNSIGNED_INT8:
2097 case SIGNED_INT8:
2098 case UNSIGNED_INT16_LE:
2099 case UNSIGNED_INT16_BE:
2100 case SIGNED_INT16_LE:
2101 case SIGNED_INT16_BE:
2102 case UNSIGNED_INT32_LE:
2103 case UNSIGNED_INT32_BE:
2104 case SIGNED_INT32_LE:
2105 case SIGNED_INT32_BE:
2106 case UNSIGNED_INT64_LE:
2107 case UNSIGNED_INT64_BE:
2108 case SIGNED_INT64_LE:
2109 case SIGNED_INT64_BE: {
sthaa3ecb82019-03-20 20:49:39 +01002110 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002111 const struct mformatdescr mf_descr =
Larry Hastingsdfbeb162014-10-13 10:39:41 +01002112 mformat_descriptors[mformat_code];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 Py_ssize_t itemcount = Py_SIZE(items) / mf_descr.size;
2114 const unsigned char *memstr =
2115 (unsigned char *)PyBytes_AS_STRING(items);
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002116 const struct arraydescr *descr;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002118 /* If possible, try to pack array's items using a data type
2119 * that fits better. This may result in an array with narrower
2120 * or wider elements.
2121 *
Martin Panter4c359642016-05-08 13:53:41 +00002122 * For example, if a 32-bit machine pickles an L-code array of
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 * unsigned longs, then the array will be unpickled by 64-bit
2124 * machine as an I-code array of unsigned ints.
2125 *
2126 * XXX: Is it possible to write a unit test for this?
2127 */
2128 for (descr = descriptors; descr->typecode != '\0'; descr++) {
2129 if (descr->is_integer_type &&
Victor Stinner706768c2014-08-16 01:03:39 +02002130 (size_t)descr->itemsize == mf_descr.size &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002131 descr->is_signed == mf_descr.is_signed)
2132 typecode = descr->typecode;
2133 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 converted_items = PyList_New(itemcount);
2136 if (converted_items == NULL)
2137 return NULL;
2138 for (i = 0; i < itemcount; i++) {
2139 PyObject *pylong;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002141 pylong = _PyLong_FromByteArray(
2142 &memstr[i * mf_descr.size],
2143 mf_descr.size,
2144 !mf_descr.is_big_endian,
2145 mf_descr.is_signed);
2146 if (pylong == NULL) {
2147 Py_DECREF(converted_items);
2148 return NULL;
2149 }
2150 PyList_SET_ITEM(converted_items, i, pylong);
2151 }
2152 break;
2153 }
2154 case UNKNOWN_FORMAT:
2155 /* Impossible, but needed to shut up GCC about the unhandled
2156 * enumeration value.
2157 */
2158 default:
2159 PyErr_BadArgument();
2160 return NULL;
2161 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002162
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02002163 result = make_array(arraytype, (char)typecode, converted_items);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 Py_DECREF(converted_items);
2165 return result;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002166}
2167
Brett Cannon1eb32c22014-10-10 16:26:45 -04002168/*[clinic input]
2169array.array.__reduce_ex__
2170
2171 value: object
2172 /
2173
2174Return state information for pickling.
2175[clinic start generated code]*/
2176
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002177static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04002178array_array___reduce_ex__(arrayobject *self, PyObject *value)
2179/*[clinic end generated code: output=051e0a6175d0eddb input=c36c3f85de7df6cd]*/
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002181 PyObject *dict;
2182 PyObject *result;
2183 PyObject *array_str;
Brett Cannon1eb32c22014-10-10 16:26:45 -04002184 int typecode = self->ob_descr->typecode;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 int mformat_code;
2186 static PyObject *array_reconstructor = NULL;
2187 long protocol;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002188 _Py_IDENTIFIER(_array_reconstructor);
2189 _Py_IDENTIFIER(__dict__);
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 if (array_reconstructor == NULL) {
2192 PyObject *array_module = PyImport_ImportModule("array");
2193 if (array_module == NULL)
2194 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002195 array_reconstructor = _PyObject_GetAttrId(
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 array_module,
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002197 &PyId__array_reconstructor);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002198 Py_DECREF(array_module);
2199 if (array_reconstructor == NULL)
2200 return NULL;
2201 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002203 if (!PyLong_Check(value)) {
2204 PyErr_SetString(PyExc_TypeError,
Sylvaina90e64b2017-03-29 20:09:22 +02002205 "__reduce_ex__ argument should be an integer");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 return NULL;
2207 }
2208 protocol = PyLong_AsLong(value);
2209 if (protocol == -1 && PyErr_Occurred())
2210 return NULL;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002211
Serhiy Storchakaf320be72018-01-25 10:49:40 +02002212 if (_PyObject_LookupAttrId((PyObject *)self, &PyId___dict__, &dict) < 0) {
2213 return NULL;
2214 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002215 if (dict == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002216 dict = Py_None;
2217 Py_INCREF(dict);
2218 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002220 mformat_code = typecode_to_mformat_code(typecode);
2221 if (mformat_code == UNKNOWN_FORMAT || protocol < 3) {
2222 /* Convert the array to a list if we got something weird
2223 * (e.g., non-IEEE floats), or we are pickling the array using
2224 * a Python 2.x compatible protocol.
2225 *
2226 * It is necessary to use a list representation for Python 2.x
2227 * compatible pickle protocol, since Python 2's str objects
2228 * are unpickled as unicode by Python 3. Thus it is impossible
2229 * to make arrays unpicklable by Python 3 by using their memory
2230 * representation, unless we resort to ugly hacks such as
2231 * coercing unicode objects to bytes in array_reconstructor.
2232 */
2233 PyObject *list;
Brett Cannon1eb32c22014-10-10 16:26:45 -04002234 list = array_array_tolist_impl(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 if (list == NULL) {
2236 Py_DECREF(dict);
2237 return NULL;
2238 }
2239 result = Py_BuildValue(
Brett Cannon1eb32c22014-10-10 16:26:45 -04002240 "O(CO)O", Py_TYPE(self), typecode, list, dict);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 Py_DECREF(list);
2242 Py_DECREF(dict);
2243 return result;
2244 }
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002245
Brett Cannon1eb32c22014-10-10 16:26:45 -04002246 array_str = array_array_tobytes_impl(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 if (array_str == NULL) {
2248 Py_DECREF(dict);
2249 return NULL;
2250 }
2251 result = Py_BuildValue(
Brett Cannon1eb32c22014-10-10 16:26:45 -04002252 "O(OCiN)O", array_reconstructor, Py_TYPE(self), typecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002253 mformat_code, array_str, dict);
2254 Py_DECREF(dict);
2255 return result;
Alexandre Vassalottiad077152009-07-15 17:49:23 +00002256}
2257
Martin v. Löwis99866332002-03-01 10:27:01 +00002258static PyObject *
2259array_get_typecode(arrayobject *a, void *closure)
2260{
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02002261 char typecode = a->ob_descr->typecode;
2262 return PyUnicode_FromOrdinal(typecode);
Martin v. Löwis99866332002-03-01 10:27:01 +00002263}
2264
2265static PyObject *
2266array_get_itemsize(arrayobject *a, void *closure)
2267{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002268 return PyLong_FromLong((long)a->ob_descr->itemsize);
Martin v. Löwis99866332002-03-01 10:27:01 +00002269}
2270
2271static PyGetSetDef array_getsets [] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002272 {"typecode", (getter) array_get_typecode, NULL,
2273 "the typecode character used to create the array"},
2274 {"itemsize", (getter) array_get_itemsize, NULL,
2275 "the size, in bytes, of one array item"},
2276 {NULL}
Martin v. Löwis99866332002-03-01 10:27:01 +00002277};
2278
Martin v. Löwis59683e82008-06-13 07:50:45 +00002279static PyMethodDef array_methods[] = {
Brett Cannon1eb32c22014-10-10 16:26:45 -04002280 ARRAY_ARRAY_APPEND_METHODDEF
2281 ARRAY_ARRAY_BUFFER_INFO_METHODDEF
2282 ARRAY_ARRAY_BYTESWAP_METHODDEF
2283 ARRAY_ARRAY___COPY___METHODDEF
2284 ARRAY_ARRAY_COUNT_METHODDEF
2285 ARRAY_ARRAY___DEEPCOPY___METHODDEF
2286 ARRAY_ARRAY_EXTEND_METHODDEF
2287 ARRAY_ARRAY_FROMFILE_METHODDEF
2288 ARRAY_ARRAY_FROMLIST_METHODDEF
Brett Cannon1eb32c22014-10-10 16:26:45 -04002289 ARRAY_ARRAY_FROMBYTES_METHODDEF
2290 ARRAY_ARRAY_FROMUNICODE_METHODDEF
2291 ARRAY_ARRAY_INDEX_METHODDEF
2292 ARRAY_ARRAY_INSERT_METHODDEF
2293 ARRAY_ARRAY_POP_METHODDEF
2294 ARRAY_ARRAY___REDUCE_EX___METHODDEF
2295 ARRAY_ARRAY_REMOVE_METHODDEF
2296 ARRAY_ARRAY_REVERSE_METHODDEF
2297 ARRAY_ARRAY_TOFILE_METHODDEF
2298 ARRAY_ARRAY_TOLIST_METHODDEF
Brett Cannon1eb32c22014-10-10 16:26:45 -04002299 ARRAY_ARRAY_TOBYTES_METHODDEF
2300 ARRAY_ARRAY_TOUNICODE_METHODDEF
2301 ARRAY_ARRAY___SIZEOF___METHODDEF
2302 {NULL, NULL} /* sentinel */
Guido van Rossum778983b1993-02-19 15:55:02 +00002303};
2304
Roger E. Masse2919eaa1996-12-09 20:10:36 +00002305static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +00002306array_repr(arrayobject *a)
Guido van Rossum778983b1993-02-19 15:55:02 +00002307{
Victor Stinnerf8bb7d02011-09-30 00:03:59 +02002308 char typecode;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002309 PyObject *s, *v = NULL;
2310 Py_ssize_t len;
Martin v. Löwis99866332002-03-01 10:27:01 +00002311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 len = Py_SIZE(a);
2313 typecode = a->ob_descr->typecode;
2314 if (len == 0) {
Serhiy Storchakab3a77962017-09-21 14:24:13 +03002315 return PyUnicode_FromFormat("%s('%c')",
2316 _PyType_Name(Py_TYPE(a)), (int)typecode);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002317 }
Gregory P. Smith9504b132012-12-10 20:20:20 -08002318 if (typecode == 'u') {
Brett Cannon1eb32c22014-10-10 16:26:45 -04002319 v = array_array_tounicode_impl(a);
Gregory P. Smith9504b132012-12-10 20:20:20 -08002320 } else {
Brett Cannon1eb32c22014-10-10 16:26:45 -04002321 v = array_array_tolist_impl(a);
Gregory P. Smith9504b132012-12-10 20:20:20 -08002322 }
Victor Stinner29ec5952013-02-26 00:27:38 +01002323 if (v == NULL)
2324 return NULL;
Raymond Hettinger88ba1e32003-04-23 17:27:00 +00002325
Serhiy Storchakab3a77962017-09-21 14:24:13 +03002326 s = PyUnicode_FromFormat("%s('%c', %R)",
2327 _PyType_Name(Py_TYPE(a)), (int)typecode, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002328 Py_DECREF(v);
2329 return s;
Guido van Rossum778983b1993-02-19 15:55:02 +00002330}
2331
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002332static PyObject*
2333array_subscr(arrayobject* self, PyObject* item)
2334{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002335 array_state *state = find_array_state_by_type(Py_TYPE(self));
2336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002337 if (PyIndex_Check(item)) {
2338 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
2339 if (i==-1 && PyErr_Occurred()) {
2340 return NULL;
2341 }
2342 if (i < 0)
2343 i += Py_SIZE(self);
2344 return array_item(self, i);
2345 }
2346 else if (PySlice_Check(item)) {
Zackery Spytz14514d92019-05-17 01:13:03 -06002347 Py_ssize_t start, stop, step, slicelength, i;
2348 size_t cur;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002349 PyObject* result;
2350 arrayobject* ar;
2351 int itemsize = self->ob_descr->itemsize;
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002352
Serhiy Storchakab879fe82017-04-08 09:53:51 +03002353 if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002354 return NULL;
2355 }
Serhiy Storchakab879fe82017-04-08 09:53:51 +03002356 slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop,
2357 step);
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002359 if (slicelength <= 0) {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002360 return newarrayobject(state->ArrayType, 0, self->ob_descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 }
2362 else if (step == 1) {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002363 PyObject *result = newarrayobject(state->ArrayType,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 slicelength, self->ob_descr);
2365 if (result == NULL)
2366 return NULL;
2367 memcpy(((arrayobject *)result)->ob_item,
2368 self->ob_item + start * itemsize,
2369 slicelength * itemsize);
2370 return result;
2371 }
2372 else {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002373 result = newarrayobject(state->ArrayType, slicelength, self->ob_descr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002374 if (!result) return NULL;
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002376 ar = (arrayobject*)result;
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002378 for (cur = start, i = 0; i < slicelength;
2379 cur += step, i++) {
2380 memcpy(ar->ob_item + i*itemsize,
2381 self->ob_item + cur*itemsize,
2382 itemsize);
2383 }
2384
2385 return result;
2386 }
2387 }
2388 else {
2389 PyErr_SetString(PyExc_TypeError,
2390 "array indices must be integers");
2391 return NULL;
2392 }
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002393}
2394
2395static int
2396array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
2397{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 Py_ssize_t start, stop, step, slicelength, needed;
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002399 array_state* state = find_array_state_by_type(Py_TYPE(self));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400 arrayobject* other;
2401 int itemsize;
Thomas Woutersed03b412007-08-28 21:37:11 +00002402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 if (PyIndex_Check(item)) {
2404 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
Alexandre Vassalotti47137252009-07-05 19:57:00 +00002405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002406 if (i == -1 && PyErr_Occurred())
2407 return -1;
2408 if (i < 0)
2409 i += Py_SIZE(self);
2410 if (i < 0 || i >= Py_SIZE(self)) {
2411 PyErr_SetString(PyExc_IndexError,
2412 "array assignment index out of range");
2413 return -1;
2414 }
2415 if (value == NULL) {
2416 /* Fall through to slice assignment */
2417 start = i;
2418 stop = i + 1;
2419 step = 1;
2420 slicelength = 1;
2421 }
2422 else
2423 return (*self->ob_descr->setitem)(self, i, value);
2424 }
2425 else if (PySlice_Check(item)) {
Serhiy Storchakab879fe82017-04-08 09:53:51 +03002426 if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 return -1;
2428 }
Serhiy Storchakab879fe82017-04-08 09:53:51 +03002429 slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop,
2430 step);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002431 }
2432 else {
2433 PyErr_SetString(PyExc_TypeError,
Sylvaina90e64b2017-03-29 20:09:22 +02002434 "array indices must be integers");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002435 return -1;
2436 }
2437 if (value == NULL) {
2438 other = NULL;
2439 needed = 0;
2440 }
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002441 else if (array_Check(value, state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002442 other = (arrayobject *)value;
2443 needed = Py_SIZE(other);
2444 if (self == other) {
2445 /* Special case "self[i:j] = self" -- copy self first */
2446 int ret;
2447 value = array_slice(other, 0, needed);
2448 if (value == NULL)
2449 return -1;
2450 ret = array_ass_subscr(self, item, value);
2451 Py_DECREF(value);
2452 return ret;
2453 }
2454 if (other->ob_descr != self->ob_descr) {
2455 PyErr_BadArgument();
2456 return -1;
2457 }
2458 }
2459 else {
2460 PyErr_Format(PyExc_TypeError,
2461 "can only assign array (not \"%.200s\") to array slice",
2462 Py_TYPE(value)->tp_name);
2463 return -1;
2464 }
2465 itemsize = self->ob_descr->itemsize;
2466 /* for 'a[2:1] = ...', the insertion point is 'start', not 'stop' */
2467 if ((step > 0 && stop < start) ||
2468 (step < 0 && stop > start))
2469 stop = start;
Alexandre Vassalotti47137252009-07-05 19:57:00 +00002470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 /* Issue #4509: If the array has exported buffers and the slice
2472 assignment would change the size of the array, fail early to make
2473 sure we don't modify it. */
2474 if ((needed == 0 || slicelength != needed) && self->ob_exports > 0) {
2475 PyErr_SetString(PyExc_BufferError,
2476 "cannot resize an array that is exporting buffers");
2477 return -1;
2478 }
Mark Dickinsonbc099642010-01-29 17:27:24 +00002479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002480 if (step == 1) {
2481 if (slicelength > needed) {
2482 memmove(self->ob_item + (start + needed) * itemsize,
2483 self->ob_item + stop * itemsize,
2484 (Py_SIZE(self) - stop) * itemsize);
2485 if (array_resize(self, Py_SIZE(self) +
2486 needed - slicelength) < 0)
2487 return -1;
2488 }
2489 else if (slicelength < needed) {
2490 if (array_resize(self, Py_SIZE(self) +
2491 needed - slicelength) < 0)
2492 return -1;
2493 memmove(self->ob_item + (start + needed) * itemsize,
2494 self->ob_item + stop * itemsize,
2495 (Py_SIZE(self) - start - needed) * itemsize);
2496 }
2497 if (needed > 0)
2498 memcpy(self->ob_item + start * itemsize,
2499 other->ob_item, needed * itemsize);
2500 return 0;
2501 }
2502 else if (needed == 0) {
2503 /* Delete slice */
2504 size_t cur;
2505 Py_ssize_t i;
Thomas Woutersed03b412007-08-28 21:37:11 +00002506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002507 if (step < 0) {
2508 stop = start + 1;
2509 start = stop + step * (slicelength - 1) - 1;
2510 step = -step;
2511 }
2512 for (cur = start, i = 0; i < slicelength;
2513 cur += step, i++) {
2514 Py_ssize_t lim = step - 1;
Thomas Woutersed03b412007-08-28 21:37:11 +00002515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002516 if (cur + step >= (size_t)Py_SIZE(self))
2517 lim = Py_SIZE(self) - cur - 1;
2518 memmove(self->ob_item + (cur - i) * itemsize,
2519 self->ob_item + (cur + 1) * itemsize,
2520 lim * itemsize);
2521 }
Mark Dickinsonc7d93b72011-09-25 15:34:32 +01002522 cur = start + (size_t)slicelength * step;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002523 if (cur < (size_t)Py_SIZE(self)) {
2524 memmove(self->ob_item + (cur-slicelength) * itemsize,
2525 self->ob_item + cur * itemsize,
2526 (Py_SIZE(self) - cur) * itemsize);
2527 }
2528 if (array_resize(self, Py_SIZE(self) - slicelength) < 0)
2529 return -1;
2530 return 0;
2531 }
2532 else {
Zackery Spytz14514d92019-05-17 01:13:03 -06002533 size_t cur;
2534 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002535
2536 if (needed != slicelength) {
2537 PyErr_Format(PyExc_ValueError,
2538 "attempt to assign array of size %zd "
2539 "to extended slice of size %zd",
2540 needed, slicelength);
2541 return -1;
2542 }
2543 for (cur = start, i = 0; i < slicelength;
2544 cur += step, i++) {
2545 memcpy(self->ob_item + cur * itemsize,
2546 other->ob_item + i * itemsize,
2547 itemsize);
2548 }
2549 return 0;
2550 }
Michael W. Hudson9c14bad2002-06-19 15:44:15 +00002551}
2552
Guido van Rossumd8faa362007-04-27 19:54:29 +00002553static const void *emptybuf = "";
2554
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002555
2556static int
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +00002557array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00002558{
Stefan Krah650c1e82015-02-03 21:43:23 +01002559 if (view == NULL) {
2560 PyErr_SetString(PyExc_BufferError,
2561 "array_buffer_getbuf: view==NULL argument is obsolete");
2562 return -1;
2563 }
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002565 view->buf = (void *)self->ob_item;
2566 view->obj = (PyObject*)self;
2567 Py_INCREF(self);
2568 if (view->buf == NULL)
2569 view->buf = (void *)emptybuf;
Victor Stinnerfe2978b2020-05-27 14:55:10 +02002570 view->len = Py_SIZE(self) * self->ob_descr->itemsize;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002571 view->readonly = 0;
2572 view->ndim = 1;
2573 view->itemsize = self->ob_descr->itemsize;
2574 view->suboffsets = NULL;
2575 view->shape = NULL;
2576 if ((flags & PyBUF_ND)==PyBUF_ND) {
Victor Stinnerfe2978b2020-05-27 14:55:10 +02002577 view->shape = &((PyVarObject*)self)->ob_size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002578 }
2579 view->strides = NULL;
2580 if ((flags & PyBUF_STRIDES)==PyBUF_STRIDES)
2581 view->strides = &(view->itemsize);
2582 view->format = NULL;
2583 view->internal = NULL;
Victor Stinner62bb3942012-08-06 00:46:05 +02002584 if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002585 view->format = (char *)self->ob_descr->formats;
Victor Stinner62bb3942012-08-06 00:46:05 +02002586#ifdef Py_UNICODE_WIDE
2587 if (self->ob_descr->typecode == 'u') {
2588 view->format = "w";
2589 }
2590#endif
2591 }
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002593 self->ob_exports++;
2594 return 0;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00002595}
2596
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002597static void
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +00002598array_buffer_relbuf(arrayobject *self, Py_buffer *view)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00002599{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002600 self->ob_exports--;
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00002601}
2602
Roger E. Masse2919eaa1996-12-09 20:10:36 +00002603static PyObject *
Martin v. Löwis99866332002-03-01 10:27:01 +00002604array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Guido van Rossum778983b1993-02-19 15:55:02 +00002605{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002606 array_state *state = find_array_state_by_type(type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002607 int c;
2608 PyObject *initial = NULL, *it = NULL;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002609 const struct arraydescr *descr;
Martin v. Löwis99866332002-03-01 10:27:01 +00002610
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002611 if (type == state->ArrayType && !_PyArg_NoKeywords("array.array", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002612 return NULL;
Martin v. Löwis99866332002-03-01 10:27:01 +00002613
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002614 if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial))
2615 return NULL;
Raymond Hettinger84fc9aa2003-04-24 10:41:55 +00002616
Steve Dowerb82e17e2019-05-23 08:45:22 -07002617 if (PySys_Audit("array.__new__", "CO",
2618 c, initial ? initial : Py_None) < 0) {
2619 return NULL;
2620 }
2621
Alexandre Vassalotti9730e332013-11-29 20:47:15 -08002622 if (initial && c != 'u') {
2623 if (PyUnicode_Check(initial)) {
2624 PyErr_Format(PyExc_TypeError, "cannot use a str to initialize "
2625 "an array with typecode '%c'", c);
2626 return NULL;
2627 }
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002628 else if (array_Check(initial, state) &&
Alexandre Vassalotti9730e332013-11-29 20:47:15 -08002629 ((arrayobject*)initial)->ob_descr->typecode == 'u') {
2630 PyErr_Format(PyExc_TypeError, "cannot use a unicode array to "
2631 "initialize an array with typecode '%c'", c);
2632 return NULL;
2633 }
2634 }
2635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002636 if (!(initial == NULL || PyList_Check(initial)
2637 || PyByteArray_Check(initial)
2638 || PyBytes_Check(initial)
2639 || PyTuple_Check(initial)
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002640 || ((c=='u') && PyUnicode_Check(initial))
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002641 || (array_Check(initial, state)
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002642 && c == ((arrayobject*)initial)->ob_descr->typecode))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002643 it = PyObject_GetIter(initial);
2644 if (it == NULL)
2645 return NULL;
2646 /* We set initial to NULL so that the subsequent code
2647 will create an empty array of the appropriate type
2648 and afterwards we can use array_iter_extend to populate
2649 the array.
2650 */
2651 initial = NULL;
2652 }
2653 for (descr = descriptors; descr->typecode != '\0'; descr++) {
2654 if (descr->typecode == c) {
2655 PyObject *a;
2656 Py_ssize_t len;
Martin v. Löwis99866332002-03-01 10:27:01 +00002657
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002658 if (initial == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002659 len = 0;
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002660 else if (PyList_Check(initial))
2661 len = PyList_GET_SIZE(initial);
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002662 else if (PyTuple_Check(initial) || array_Check(initial, state))
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002663 len = Py_SIZE(initial);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002664 else
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002665 len = 0;
Martin v. Löwis99866332002-03-01 10:27:01 +00002666
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002667 a = newarrayobject(type, len, descr);
2668 if (a == NULL)
2669 return NULL;
2670
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002671 if (len > 0 && !array_Check(initial, state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002672 Py_ssize_t i;
2673 for (i = 0; i < len; i++) {
2674 PyObject *v =
2675 PySequence_GetItem(initial, i);
2676 if (v == NULL) {
2677 Py_DECREF(a);
2678 return NULL;
2679 }
2680 if (setarrayitem(a, i, v) != 0) {
2681 Py_DECREF(v);
2682 Py_DECREF(a);
2683 return NULL;
2684 }
2685 Py_DECREF(v);
2686 }
2687 }
2688 else if (initial != NULL && (PyByteArray_Check(initial) ||
2689 PyBytes_Check(initial))) {
Serhiy Storchaka04e6dba2015-04-04 17:06:55 +03002690 PyObject *v;
Brett Cannon1eb32c22014-10-10 16:26:45 -04002691 v = array_array_frombytes((arrayobject *)a,
Serhiy Storchaka04e6dba2015-04-04 17:06:55 +03002692 initial);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002693 if (v == NULL) {
2694 Py_DECREF(a);
2695 return NULL;
2696 }
2697 Py_DECREF(v);
2698 }
2699 else if (initial != NULL && PyUnicode_Check(initial)) {
Victor Stinner1fbcaef2011-09-30 01:54:04 +02002700 Py_ssize_t n;
Inada Naokid5d9a712020-05-11 15:37:25 +09002701 wchar_t *ustr = PyUnicode_AsWideCharString(initial, &n);
Victor Stinner62bb3942012-08-06 00:46:05 +02002702 if (ustr == NULL) {
Victor Stinner1fbcaef2011-09-30 01:54:04 +02002703 Py_DECREF(a);
2704 return NULL;
2705 }
Victor Stinner62bb3942012-08-06 00:46:05 +02002706
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002707 if (n > 0) {
2708 arrayobject *self = (arrayobject *)a;
Inada Naokid5d9a712020-05-11 15:37:25 +09002709 // self->ob_item may be NULL but it is safe.
2710 PyMem_Free(self->ob_item);
2711 self->ob_item = (char *)ustr;
2712 Py_SET_SIZE(self, n);
2713 self->allocated = n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002714 }
2715 }
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002716 else if (initial != NULL && array_Check(initial, state) && len > 0) {
Alexander Belopolskyef4a03f2011-01-11 21:44:00 +00002717 arrayobject *self = (arrayobject *)a;
2718 arrayobject *other = (arrayobject *)initial;
2719 memcpy(self->ob_item, other->ob_item, len * other->ob_descr->itemsize);
2720 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002721 if (it != NULL) {
2722 if (array_iter_extend((arrayobject *)a, it) == -1) {
2723 Py_DECREF(it);
2724 Py_DECREF(a);
2725 return NULL;
2726 }
2727 Py_DECREF(it);
2728 }
2729 return a;
2730 }
2731 }
2732 PyErr_SetString(PyExc_ValueError,
Meador Inge1c9f0c92011-09-20 19:55:51 -05002733 "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 +00002734 return NULL;
Guido van Rossum778983b1993-02-19 15:55:02 +00002735}
2736
Guido van Rossum778983b1993-02-19 15:55:02 +00002737
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002738PyDoc_STRVAR(module_doc,
Martin v. Löwis99866332002-03-01 10:27:01 +00002739"This module defines an object type which can efficiently represent\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002740an array of basic values: characters, integers, floating point\n\
2741numbers. Arrays are sequence types and behave very much like lists,\n\
Alexandre Vassalotti9730e332013-11-29 20:47:15 -08002742except that the type of objects stored in them is constrained.\n");
2743
2744PyDoc_STRVAR(arraytype_doc,
2745"array(typecode [, initializer]) -> array\n\
2746\n\
2747Return a new array whose items are restricted by typecode, and\n\
2748initialized from the optional initializer value, which must be a list,\n\
2749string or iterable over elements of the appropriate type.\n\
2750\n\
2751Arrays represent basic values and behave very much like lists, except\n\
2752the type of objects stored in them is constrained. The type is specified\n\
2753at object creation time by using a type code, which is a single character.\n\
2754The following type codes are defined:\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002755\n\
oldkaa0735f2018-02-02 16:52:55 +08002756 Type code C Type Minimum size in bytes\n\
2757 'b' signed integer 1\n\
2758 'B' unsigned integer 1\n\
2759 'u' Unicode character 2 (see note)\n\
2760 'h' signed integer 2\n\
2761 'H' unsigned integer 2\n\
2762 'i' signed integer 2\n\
2763 'I' unsigned integer 2\n\
2764 'l' signed integer 4\n\
2765 'L' unsigned integer 4\n\
2766 'q' signed integer 8 (see note)\n\
2767 'Q' unsigned integer 8 (see note)\n\
2768 'f' floating point 4\n\
2769 'd' floating point 8\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002770\n\
oldkaa0735f2018-02-02 16:52:55 +08002771NOTE: The 'u' typecode corresponds to Python's unicode character. On\n\
Victor Stinner62bb3942012-08-06 00:46:05 +02002772narrow builds this is 2-bytes on wide builds this is 4-bytes.\n\
2773\n\
oldkaa0735f2018-02-02 16:52:55 +08002774NOTE: The 'q' and 'Q' type codes are only available if the platform\n\
2775C compiler used to build Python supports 'long long', or, on Windows,\n\
Meador Inge1c9f0c92011-09-20 19:55:51 -05002776'__int64'.\n\
2777\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002778Methods:\n\
2779\n\
2780append() -- append a new item to the end of the array\n\
2781buffer_info() -- return information giving the current memory info\n\
2782byteswap() -- byteswap all the items of the array\n\
Mark Dickinson934896d2009-02-21 20:59:32 +00002783count() -- return number of occurrences of an object\n\
Raymond Hettinger49f9bd12004-03-14 05:43:59 +00002784extend() -- extend array by appending multiple elements from an iterable\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002785fromfile() -- read items from a file object\n\
2786fromlist() -- append items from the list\n\
Florent Xiclunac45fb252011-10-24 13:14:55 +02002787frombytes() -- append items from the string\n\
Mark Dickinson934896d2009-02-21 20:59:32 +00002788index() -- return index of first occurrence of an object\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002789insert() -- insert a new item into the array at a provided position\n\
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00002790pop() -- remove and return item (default last)\n\
Mark Dickinson934896d2009-02-21 20:59:32 +00002791remove() -- remove first occurrence of an object\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002792reverse() -- reverse the order of the items in the array\n\
2793tofile() -- write all items to a file object\n\
2794tolist() -- return the array converted to an ordinary list\n\
Florent Xiclunac45fb252011-10-24 13:14:55 +02002795tobytes() -- return the array converted to a string\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002796\n\
Martin v. Löwis99866332002-03-01 10:27:01 +00002797Attributes:\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002798\n\
2799typecode -- the typecode character used to create the array\n\
2800itemsize -- the length in bytes of one array item\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002801");
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002802
Raymond Hettinger625812f2003-01-07 01:58:52 +00002803static PyObject *array_iter(arrayobject *ao);
2804
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002805static struct PyMemberDef array_members[] = {
2806 {"__weaklistoffset__", T_PYSSIZET, offsetof(arrayobject, weakreflist), READONLY},
2807 {NULL},
Guido van Rossumb39b90d1998-10-13 14:27:22 +00002808};
2809
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002810static PyType_Slot array_slots[] = {
2811 {Py_tp_dealloc, array_dealloc},
2812 {Py_tp_repr, array_repr},
2813 {Py_tp_getattro, PyObject_GenericGetAttr},
2814 {Py_tp_doc, (void *)arraytype_doc},
2815 {Py_tp_richcompare, array_richcompare},
2816 {Py_tp_iter, array_iter},
2817 {Py_tp_methods, array_methods},
2818 {Py_tp_members, array_members},
2819 {Py_tp_getset, array_getsets},
2820 {Py_tp_alloc, PyType_GenericAlloc},
2821 {Py_tp_new, array_new},
2822 {Py_tp_free, PyObject_Del},
2823
2824 /* as sequence */
2825 {Py_sq_length, array_length},
2826 {Py_sq_concat, array_concat},
2827 {Py_sq_repeat, array_repeat},
2828 {Py_sq_item, array_item},
2829 {Py_sq_ass_item, array_ass_item},
2830 {Py_sq_contains, array_contains},
2831 {Py_sq_inplace_concat, array_inplace_concat},
2832 {Py_sq_inplace_repeat, array_inplace_repeat},
2833
2834 /* as mapping */
2835 {Py_mp_length, array_length},
2836 {Py_mp_subscript, array_subscr},
2837 {Py_mp_ass_subscript, array_ass_subscr},
2838
2839 /* as buffer */
2840 {Py_bf_getbuffer, array_buffer_getbuf},
2841 {Py_bf_releasebuffer, array_buffer_relbuf},
2842
2843 {0, NULL},
2844};
2845
2846static PyType_Spec array_spec = {
2847 .name = "array.array",
2848 .basicsize = sizeof(arrayobject),
2849 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
2850 .slots = array_slots,
2851};
Raymond Hettinger625812f2003-01-07 01:58:52 +00002852
2853/*********************** Array Iterator **************************/
2854
Brett Cannon1eb32c22014-10-10 16:26:45 -04002855/*[clinic input]
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002856class array.arrayiterator "arrayiterobject *" "find_array_state_by_type(type)->ArrayIterType"
Brett Cannon1eb32c22014-10-10 16:26:45 -04002857[clinic start generated code]*/
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002858/*[clinic end generated code: output=da39a3ee5e6b4b0d input=fb46d5ef98dd95ff]*/
Raymond Hettinger625812f2003-01-07 01:58:52 +00002859
2860static PyObject *
2861array_iter(arrayobject *ao)
2862{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002863 array_state *state = find_array_state_by_type(Py_TYPE(ao));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002864 arrayiterobject *it;
Raymond Hettinger625812f2003-01-07 01:58:52 +00002865
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002866 if (!array_Check(ao, state)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002867 PyErr_BadInternalCall();
2868 return NULL;
2869 }
Raymond Hettinger625812f2003-01-07 01:58:52 +00002870
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002871 it = PyObject_GC_New(arrayiterobject, state->ArrayIterType);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002872 if (it == NULL)
2873 return NULL;
Raymond Hettinger625812f2003-01-07 01:58:52 +00002874
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002875 Py_INCREF(ao);
2876 it->ao = ao;
2877 it->index = 0;
2878 it->getitem = ao->ob_descr->getitem;
2879 PyObject_GC_Track(it);
2880 return (PyObject *)it;
Raymond Hettinger625812f2003-01-07 01:58:52 +00002881}
2882
2883static PyObject *
Raymond Hettinger625812f2003-01-07 01:58:52 +00002884arrayiter_next(arrayiterobject *it)
2885{
Serhiy Storchakaab0d1982016-03-30 21:11:16 +03002886 arrayobject *ao;
2887
2888 assert(it != NULL);
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002889#ifndef NDEBUG
2890 array_state *state = find_array_state_by_type(Py_TYPE(it));
2891 assert(PyObject_TypeCheck(it, state->ArrayIterType));
2892#endif
Serhiy Storchakaab0d1982016-03-30 21:11:16 +03002893 ao = it->ao;
2894 if (ao == NULL) {
2895 return NULL;
2896 }
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002897#ifndef NDEBUG
2898 assert(array_Check(ao, state));
2899#endif
Serhiy Storchakaab0d1982016-03-30 21:11:16 +03002900 if (it->index < Py_SIZE(ao)) {
2901 return (*it->getitem)(ao, it->index++);
2902 }
2903 it->ao = NULL;
2904 Py_DECREF(ao);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002905 return NULL;
Raymond Hettinger625812f2003-01-07 01:58:52 +00002906}
2907
2908static void
2909arrayiter_dealloc(arrayiterobject *it)
2910{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002911 PyTypeObject *tp = Py_TYPE(it);
2912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002913 PyObject_GC_UnTrack(it);
2914 Py_XDECREF(it->ao);
2915 PyObject_GC_Del(it);
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002916 Py_DECREF(tp);
Raymond Hettinger625812f2003-01-07 01:58:52 +00002917}
2918
2919static int
2920arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
2921{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002922 Py_VISIT(it->ao);
2923 return 0;
Raymond Hettinger625812f2003-01-07 01:58:52 +00002924}
2925
Brett Cannon1eb32c22014-10-10 16:26:45 -04002926/*[clinic input]
2927array.arrayiterator.__reduce__
2928
2929Return state information for pickling.
2930[clinic start generated code]*/
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002931
2932static PyObject *
Brett Cannon1eb32c22014-10-10 16:26:45 -04002933array_arrayiterator___reduce___impl(arrayiterobject *self)
2934/*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/
2935{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02002936 _Py_IDENTIFIER(iter);
2937 PyObject *func = _PyEval_GetBuiltinId(&PyId_iter);
Serhiy Storchakaab0d1982016-03-30 21:11:16 +03002938 if (self->ao == NULL) {
2939 return Py_BuildValue("N(())", func);
2940 }
2941 return Py_BuildValue("N(O)n", func, self->ao, self->index);
Brett Cannon1eb32c22014-10-10 16:26:45 -04002942}
2943
2944/*[clinic input]
2945array.arrayiterator.__setstate__
2946
2947 state: object
2948 /
2949
2950Set state information for unpickling.
2951[clinic start generated code]*/
2952
2953static PyObject *
2954array_arrayiterator___setstate__(arrayiterobject *self, PyObject *state)
2955/*[clinic end generated code: output=397da9904e443cbe input=f47d5ceda19e787b]*/
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002956{
2957 Py_ssize_t index = PyLong_AsSsize_t(state);
2958 if (index == -1 && PyErr_Occurred())
2959 return NULL;
2960 if (index < 0)
2961 index = 0;
Brett Cannon1eb32c22014-10-10 16:26:45 -04002962 else if (index > Py_SIZE(self->ao))
2963 index = Py_SIZE(self->ao); /* iterator exhausted */
2964 self->index = index;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002965 Py_RETURN_NONE;
2966}
2967
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002968static PyMethodDef arrayiter_methods[] = {
Brett Cannon1eb32c22014-10-10 16:26:45 -04002969 ARRAY_ARRAYITERATOR___REDUCE___METHODDEF
2970 ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002971 {NULL, NULL} /* sentinel */
2972};
2973
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01002974static PyType_Slot arrayiter_slots[] = {
2975 {Py_tp_dealloc, arrayiter_dealloc},
2976 {Py_tp_getattro, PyObject_GenericGetAttr},
2977 {Py_tp_traverse, arrayiter_traverse},
2978 {Py_tp_iter, PyObject_SelfIter},
2979 {Py_tp_iternext, arrayiter_next},
2980 {Py_tp_methods, arrayiter_methods},
2981 {0, NULL},
2982};
2983
2984static PyType_Spec arrayiter_spec = {
2985 .name = "array.arrayiterator",
2986 .basicsize = sizeof(arrayiterobject),
2987 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
2988 .slots = arrayiter_slots,
Raymond Hettinger625812f2003-01-07 01:58:52 +00002989};
2990
2991
2992/*********************** Install Module **************************/
2993
Erlend Egeberg Aaslandb8eb3762021-01-03 14:11:15 +01002994static int
2995array_traverse(PyObject *module, visitproc visit, void *arg)
2996{
2997 array_state *state = get_array_state(module);
2998 Py_VISIT(state->ArrayType);
2999 Py_VISIT(state->ArrayIterType);
3000 return 0;
3001}
3002
3003static int
3004array_clear(PyObject *module)
3005{
3006 array_state *state = get_array_state(module);
3007 Py_CLEAR(state->ArrayType);
3008 Py_CLEAR(state->ArrayIterType);
3009 return 0;
3010}
3011
3012static void
3013array_free(void *module)
3014{
3015 array_clear((PyObject *)module);
3016}
3017
Martin v. Löwis99866332002-03-01 10:27:01 +00003018/* No functions in array module. */
3019static PyMethodDef a_methods[] = {
Brett Cannon1eb32c22014-10-10 16:26:45 -04003020 ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF
Martin v. Löwis99866332002-03-01 10:27:01 +00003021 {NULL, NULL, 0, NULL} /* Sentinel */
3022};
3023
Erlend Egeberg Aaslandb8eb3762021-01-03 14:11:15 +01003024#define CREATE_TYPE(module, type, spec) \
3025do { \
3026 type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \
3027 if (type == NULL) { \
3028 return -1; \
3029 } \
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003030} while (0)
3031
Nick Coghland5cacbb2015-05-23 22:24:10 +10003032static int
3033array_modexec(PyObject *m)
Guido van Rossum778983b1993-02-19 15:55:02 +00003034{
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003035 array_state *state = get_array_state(m);
Georg Brandl4cb0de22011-09-28 21:49:49 +02003036 char buffer[Py_ARRAY_LENGTH(descriptors)], *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003037 PyObject *typecodes;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02003038 const struct arraydescr *descr;
Fred Drake0d40ba42000-02-04 20:33:49 +00003039
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003040 CREATE_TYPE(m, state->ArrayType, &array_spec);
3041 CREATE_TYPE(m, state->ArrayIterType, &arrayiter_spec);
3042 Py_SET_TYPE(state->ArrayIterType, &PyType_Type);
Fred Drakef4e34842002-04-01 03:45:06 +00003043
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003044 Py_INCREF((PyObject *)state->ArrayType);
3045 if (PyModule_AddObject(m, "ArrayType", (PyObject *)state->ArrayType) < 0) {
3046 Py_DECREF((PyObject *)state->ArrayType);
Marco Paolinib44ffc82019-11-15 08:42:51 +00003047 return -1;
3048 }
Pablo Galindoe51dd9d2020-07-05 22:43:14 +01003049
3050 PyObject *abc_mod = PyImport_ImportModule("collections.abc");
3051 if (!abc_mod) {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003052 Py_DECREF((PyObject *)state->ArrayType);
Pablo Galindoe51dd9d2020-07-05 22:43:14 +01003053 return -1;
3054 }
3055 PyObject *mutablesequence = PyObject_GetAttrString(abc_mod, "MutableSequence");
3056 Py_DECREF(abc_mod);
3057 if (!mutablesequence) {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003058 Py_DECREF((PyObject *)state->ArrayType);
Pablo Galindoe51dd9d2020-07-05 22:43:14 +01003059 return -1;
3060 }
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003061 PyObject *res = PyObject_CallMethod(mutablesequence, "register", "O",
3062 (PyObject *)state->ArrayType);
Pablo Galindoe51dd9d2020-07-05 22:43:14 +01003063 Py_DECREF(mutablesequence);
3064 if (!res) {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003065 Py_DECREF((PyObject *)state->ArrayType);
Pablo Galindoe51dd9d2020-07-05 22:43:14 +01003066 return -1;
3067 }
3068 Py_DECREF(res);
3069
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003070 if (PyModule_AddType(m, state->ArrayType) < 0) {
Marco Paolinib44ffc82019-11-15 08:42:51 +00003071 return -1;
3072 }
Travis E. Oliphantd5c0add2007-10-12 22:05:15 +00003073
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003074 p = buffer;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003075 for (descr = descriptors; descr->typecode != '\0'; descr++) {
3076 *p++ = (char)descr->typecode;
3077 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003078 typecodes = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Marco Paolinib44ffc82019-11-15 08:42:51 +00003079 if (PyModule_AddObject(m, "typecodes", typecodes) < 0) {
3080 Py_XDECREF(typecodes);
3081 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003082 }
Marco Paolinib44ffc82019-11-15 08:42:51 +00003083
Nick Coghland5cacbb2015-05-23 22:24:10 +10003084 return 0;
3085}
3086
3087static PyModuleDef_Slot arrayslots[] = {
3088 {Py_mod_exec, array_modexec},
3089 {0, NULL}
3090};
3091
3092
3093static struct PyModuleDef arraymodule = {
Erlend Egeberg Aasland75bf1072021-01-02 17:38:47 +01003094 .m_base = PyModuleDef_HEAD_INIT,
3095 .m_name = "array",
3096 .m_size = sizeof(array_state),
3097 .m_doc = module_doc,
3098 .m_methods = a_methods,
3099 .m_slots = arrayslots,
Erlend Egeberg Aaslandb8eb3762021-01-03 14:11:15 +01003100 .m_traverse = array_traverse,
3101 .m_clear = array_clear,
3102 .m_free = array_free,
Nick Coghland5cacbb2015-05-23 22:24:10 +10003103};
3104
3105
3106PyMODINIT_FUNC
3107PyInit_array(void)
3108{
3109 return PyModuleDef_Init(&arraymodule);
Guido van Rossum778983b1993-02-19 15:55:02 +00003110}