LCOV - code coverage report
Current view: | top level - Modules - arraymodule.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 49 | 1353 | 3.6 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 6 | 104 | 5.8 %
|  |  | Branches: | 31 | 911 | 3.4 %

               Branch data     Line data    Source code
           1                 :            : /* 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                 :            :
           6                 :            : #ifndef Py_BUILD_CORE_BUILTIN
           7                 :            : #  define Py_BUILD_CORE_MODULE 1
           8                 :            : #endif
           9                 :            :
          10                 :            : #define PY_SSIZE_T_CLEAN
          11                 :            : #include "Python.h"
          12                 :            : #include "pycore_moduleobject.h"  // _PyModule_GetState()
          13                 :            : #include "pycore_bytesobject.h"   // _PyBytes_Repeat
          14                 :            : #include "structmember.h"         // PyMemberDef
          15                 :            : #include <stddef.h>               // offsetof()
          16                 :            :
          17                 :            : /*[clinic input]
          18                 :            : module array
          19                 :            : [clinic start generated code]*/
          20                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=7d1b8d7f5958fd83]*/
          21                 :            :
          22                 :            : struct arrayobject; /* Forward */
          23                 :            : static struct PyModuleDef arraymodule;
          24                 :            :
          25                 :            : /* All possible arraydescr values are defined in the vector "descriptors"
          26                 :            :  * below.  That's defined later because the appropriate get and set
          27                 :            :  * functions aren't visible yet.
          28                 :            :  */
          29                 :            : struct arraydescr {
          30                 :            :     char typecode;
          31                 :            :     int itemsize;
          32                 :            :     PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
          33                 :            :     int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
          34                 :            :     int (*compareitems)(const void *, const void *, Py_ssize_t);
          35                 :            :     const char *formats;
          36                 :            :     int is_integer_type;
          37                 :            :     int is_signed;
          38                 :            : };
          39                 :            :
          40                 :            : typedef struct arrayobject {
          41                 :            :     PyObject_VAR_HEAD
          42                 :            :     char *ob_item;
          43                 :            :     Py_ssize_t allocated;
          44                 :            :     const struct arraydescr *ob_descr;
          45                 :            :     PyObject *weakreflist; /* List of weak references */
          46                 :            :     Py_ssize_t ob_exports;  /* Number of exported buffers */
          47                 :            : } arrayobject;
          48                 :            :
          49                 :            : typedef struct {
          50                 :            :     PyObject_HEAD
          51                 :            :     Py_ssize_t index;
          52                 :            :     arrayobject *ao;
          53                 :            :     PyObject* (*getitem)(struct arrayobject *, Py_ssize_t);
          54                 :            : } arrayiterobject;
          55                 :            :
          56                 :            : typedef struct {
          57                 :            :     PyTypeObject *ArrayType;
          58                 :            :     PyTypeObject *ArrayIterType;
          59                 :            :
          60                 :            :     PyObject *array_reconstructor;
          61                 :            :
          62                 :            :     PyObject *str_read;
          63                 :            :     PyObject *str_write;
          64                 :            :     PyObject *str___dict__;
          65                 :            :     PyObject *str_iter;
          66                 :            : } array_state;
          67                 :            :
          68                 :            : static array_state *
          69                 :         22 : get_array_state(PyObject *module)
          70                 :            : {
          71                 :         22 :     return (array_state *)_PyModule_GetState(module);
          72                 :            : }
          73                 :            :
          74                 :            : #define find_array_state_by_type(tp) \
          75                 :            :     (get_array_state(PyType_GetModuleByDef(tp, &arraymodule)))
          76                 :            : #define get_array_state_by_class(cls) \
          77                 :            :     (get_array_state(PyType_GetModule(cls)))
          78                 :            :
          79                 :            : enum machine_format_code {
          80                 :            :     UNKNOWN_FORMAT = -1,
          81                 :            :     /* UNKNOWN_FORMAT is used to indicate that the machine format for an
          82                 :            :      * array type code cannot be interpreted. When this occurs, a list of
          83                 :            :      * Python objects is used to represent the content of the array
          84                 :            :      * instead of using the memory content of the array directly. In that
          85                 :            :      * case, the array_reconstructor mechanism is bypassed completely, and
          86                 :            :      * the standard array constructor is used instead.
          87                 :            :      *
          88                 :            :      * This is will most likely occur when the machine doesn't use IEEE
          89                 :            :      * floating-point numbers.
          90                 :            :      */
          91                 :            :
          92                 :            :     UNSIGNED_INT8 = 0,
          93                 :            :     SIGNED_INT8 = 1,
          94                 :            :     UNSIGNED_INT16_LE = 2,
          95                 :            :     UNSIGNED_INT16_BE = 3,
          96                 :            :     SIGNED_INT16_LE = 4,
          97                 :            :     SIGNED_INT16_BE = 5,
          98                 :            :     UNSIGNED_INT32_LE = 6,
          99                 :            :     UNSIGNED_INT32_BE = 7,
         100                 :            :     SIGNED_INT32_LE = 8,
         101                 :            :     SIGNED_INT32_BE = 9,
         102                 :            :     UNSIGNED_INT64_LE = 10,
         103                 :            :     UNSIGNED_INT64_BE = 11,
         104                 :            :     SIGNED_INT64_LE = 12,
         105                 :            :     SIGNED_INT64_BE = 13,
         106                 :            :     IEEE_754_FLOAT_LE = 14,
         107                 :            :     IEEE_754_FLOAT_BE = 15,
         108                 :            :     IEEE_754_DOUBLE_LE = 16,
         109                 :            :     IEEE_754_DOUBLE_BE = 17,
         110                 :            :     UTF16_LE = 18,
         111                 :            :     UTF16_BE = 19,
         112                 :            :     UTF32_LE = 20,
         113                 :            :     UTF32_BE = 21
         114                 :            : };
         115                 :            : #define MACHINE_FORMAT_CODE_MIN 0
         116                 :            : #define MACHINE_FORMAT_CODE_MAX 21
         117                 :            :
         118                 :            :
         119                 :            : /*
         120                 :            :  * Must come after arrayobject, arrayiterobject,
         121                 :            :  * and enum machine_code_type definitions.
         122                 :            :  */
         123                 :            : #include "clinic/arraymodule.c.h"
         124                 :            :
         125                 :            : #define array_Check(op, state) PyObject_TypeCheck(op, state->ArrayType)
         126                 :            :
         127                 :            : static int
         128                 :          0 : array_resize(arrayobject *self, Py_ssize_t newsize)
         129                 :            : {
         130                 :            :     char *items;
         131                 :            :     size_t _new_size;
         132                 :            :
         133   [ #  #  #  # ]:          0 :     if (self->ob_exports > 0 && newsize != Py_SIZE(self)) {
         134                 :          0 :         PyErr_SetString(PyExc_BufferError,
         135                 :            :             "cannot resize an array that is exporting buffers");
         136                 :          0 :         return -1;
         137                 :            :     }
         138                 :            :
         139                 :            :     /* Bypass realloc() when a previous overallocation is large enough
         140                 :            :        to accommodate the newsize.  If the newsize is 16 smaller than the
         141                 :            :        current size, then proceed with the realloc() to shrink the array.
         142                 :            :     */
         143                 :            :
         144         [ #  # ]:          0 :     if (self->allocated >= newsize &&
         145         [ #  # ]:          0 :         Py_SIZE(self) < newsize + 16 &&
         146         [ #  # ]:          0 :         self->ob_item != NULL) {
         147                 :          0 :         Py_SET_SIZE(self, newsize);
         148                 :          0 :         return 0;
         149                 :            :     }
         150                 :            :
         151         [ #  # ]:          0 :     if (newsize == 0) {
         152                 :          0 :         PyMem_Free(self->ob_item);
         153                 :          0 :         self->ob_item = NULL;
         154                 :          0 :         Py_SET_SIZE(self, 0);
         155                 :          0 :         self->allocated = 0;
         156                 :          0 :         return 0;
         157                 :            :     }
         158                 :            :
         159                 :            :     /* This over-allocates proportional to the array size, making room
         160                 :            :      * for additional growth.  The over-allocation is mild, but is
         161                 :            :      * enough to give linear-time amortized behavior over a long
         162                 :            :      * sequence of appends() in the presence of a poorly-performing
         163                 :            :      * system realloc().
         164                 :            :      * The growth pattern is:  0, 4, 8, 16, 25, 34, 46, 56, 67, 79, ...
         165                 :            :      * Note, the pattern starts out the same as for lists but then
         166                 :            :      * grows at a smaller rate so that larger arrays only overallocate
         167                 :            :      * by about 1/16th -- this is done because arrays are presumed to be more
         168                 :            :      * memory critical.
         169                 :            :      */
         170                 :            :
         171         [ #  # ]:          0 :     _new_size = (newsize >> 4) + (Py_SIZE(self) < 8 ? 3 : 7) + newsize;
         172                 :          0 :     items = self->ob_item;
         173                 :            :     /* XXX The following multiplication and division does not optimize away
         174                 :            :        like it does for lists since the size is not known at compile time */
         175         [ #  # ]:          0 :     if (_new_size <= ((~(size_t)0) / self->ob_descr->itemsize))
         176         [ #  # ]:          0 :         PyMem_RESIZE(items, char, (_new_size * self->ob_descr->itemsize));
         177                 :            :     else
         178                 :          0 :         items = NULL;
         179         [ #  # ]:          0 :     if (items == NULL) {
         180                 :          0 :         PyErr_NoMemory();
         181                 :          0 :         return -1;
         182                 :            :     }
         183                 :          0 :     self->ob_item = items;
         184                 :          0 :     Py_SET_SIZE(self, newsize);
         185                 :          0 :     self->allocated = _new_size;
         186                 :          0 :     return 0;
         187                 :            : }
         188                 :            :
         189                 :            : /****************************************************************************
         190                 :            : Get and Set functions for each type.
         191                 :            : A Get function takes an arrayobject* and an integer index, returning the
         192                 :            : array value at that index wrapped in an appropriate PyObject*.
         193                 :            : A Set function takes an arrayobject, integer index, and PyObject*; sets
         194                 :            : the array value at that index to the raw C data extracted from the PyObject*,
         195                 :            : and returns 0 if successful, else nonzero on failure (PyObject* not of an
         196                 :            : appropriate type or value).
         197                 :            : Note that the basic Get and Set functions do NOT check that the index is
         198                 :            : in bounds; that's the responsibility of the caller.
         199                 :            : ****************************************************************************/
         200                 :            :
         201                 :            : static PyObject *
         202                 :          0 : b_getitem(arrayobject *ap, Py_ssize_t i)
         203                 :            : {
         204                 :          0 :     long x = ((signed char *)ap->ob_item)[i];
         205                 :          0 :     return PyLong_FromLong(x);
         206                 :            : }
         207                 :            :
         208                 :            : static int
         209                 :          0 : b_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
         210                 :            : {
         211                 :            :     short x;
         212                 :            :     /* PyArg_Parse's 'b' formatter is for an unsigned char, therefore
         213                 :            :        must use the next size up that is signed ('h') and manually do
         214                 :            :        the overflow checking */
         215         [ #  # ]:          0 :     if (!PyArg_Parse(v, "h;array item must be integer", &x))
         216                 :          0 :         return -1;
         217         [ #  # ]:          0 :     else if (x < -128) {
         218                 :          0 :         PyErr_SetString(PyExc_OverflowError,
         219                 :            :             "signed char is less than minimum");
         220                 :          0 :         return -1;
         221                 :            :     }
         222         [ #  # ]:          0 :     else if (x > 127) {
         223                 :          0 :         PyErr_SetString(PyExc_OverflowError,
         224                 :            :             "signed char is greater than maximum");
         225                 :          0 :         return -1;
         226                 :            :     }
         227         [ #  # ]:          0 :     if (i >= 0)
         228                 :          0 :         ((char *)ap->ob_item)[i] = (char)x;
         229                 :          0 :     return 0;
         230                 :            : }
         231                 :            :
         232                 :            : static PyObject *
         233                 :          0 : BB_getitem(arrayobject *ap, Py_ssize_t i)
         234                 :            : {
         235                 :          0 :     long x = ((unsigned char *)ap->ob_item)[i];
         236                 :          0 :     return PyLong_FromLong(x);
         237                 :            : }
         238                 :            :
         239                 :            : static int
         240                 :          0 : BB_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
         241                 :            : {
         242                 :            :     unsigned char x;
         243                 :            :     /* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */
         244         [ #  # ]:          0 :     if (!PyArg_Parse(v, "b;array item must be integer", &x))
         245                 :          0 :         return -1;
         246         [ #  # ]:          0 :     if (i >= 0)
         247                 :          0 :         ((char *)ap->ob_item)[i] = x;
         248                 :          0 :     return 0;
         249                 :            : }
         250                 :            :
         251                 :            : static PyObject *
         252                 :          0 : u_getitem(arrayobject *ap, Py_ssize_t i)
         253                 :            : {
         254                 :          0 :     return PyUnicode_FromOrdinal(((wchar_t *) ap->ob_item)[i]);
         255                 :            : }
         256                 :            :
         257                 :            : static int
         258                 :          0 : u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
         259                 :            : {
         260                 :            :     PyObject *u;
         261         [ #  # ]:          0 :     if (!PyArg_Parse(v, "U;array item must be unicode character", &u)) {
         262                 :          0 :         return -1;
         263                 :            :     }
         264                 :            :
         265                 :          0 :     Py_ssize_t len = PyUnicode_AsWideChar(u, NULL, 0);
         266         [ #  # ]:          0 :     if (len != 2) {
         267                 :          0 :         PyErr_SetString(PyExc_TypeError,
         268                 :            :                         "array item must be unicode character");
         269                 :          0 :         return -1;
         270                 :            :     }
         271                 :            :
         272                 :            :     wchar_t w;
         273                 :          0 :     len = PyUnicode_AsWideChar(u, &w, 1);
         274                 :            :     assert(len == 1);
         275                 :            :
         276         [ #  # ]:          0 :     if (i >= 0) {
         277                 :          0 :         ((wchar_t *)ap->ob_item)[i] = w;
         278                 :            :     }
         279                 :          0 :     return 0;
         280                 :            : }
         281                 :            :
         282                 :            :
         283                 :            : static PyObject *
         284                 :          0 : h_getitem(arrayobject *ap, Py_ssize_t i)
         285                 :            : {
         286                 :          0 :     return PyLong_FromLong((long) ((short *)ap->ob_item)[i]);
         287                 :            : }
         288                 :            :
         289                 :            :
         290                 :            : static int
         291                 :          0 : h_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
         292                 :            : {
         293                 :            :     short x;
         294                 :            :     /* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */
         295         [ #  # ]:          0 :     if (!PyArg_Parse(v, "h;array item must be integer", &x))
         296                 :          0 :         return -1;
         297         [ #  # ]:          0 :     if (i >= 0)
         298                 :          0 :                  ((short *)ap->ob_item)[i] = x;
         299                 :          0 :     return 0;
         300                 :            : }
         301                 :            :
         302                 :            : static PyObject *
         303                 :          0 : HH_getitem(arrayobject *ap, Py_ssize_t i)
         304                 :            : {
         305                 :          0 :     return PyLong_FromLong((long) ((unsigned short *)ap->ob_item)[i]);
         306                 :            : }
         307                 :            :
         308                 :            : static int
         309                 :          0 : HH_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
         310                 :            : {
         311                 :            :     int x;
         312                 :            :     /* PyArg_Parse's 'h' formatter is for a signed short, therefore
         313                 :            :        must use the next size up and manually do the overflow checking */
         314         [ #  # ]:          0 :     if (!PyArg_Parse(v, "i;array item must be integer", &x))
         315                 :          0 :         return -1;
         316         [ #  # ]:          0 :     else if (x < 0) {
         317                 :          0 :         PyErr_SetString(PyExc_OverflowError,
         318                 :            :             "unsigned short is less than minimum");
         319                 :          0 :         return -1;
         320                 :            :     }
         321         [ #  # ]:          0 :     else if (x > USHRT_MAX) {
         322                 :          0 :         PyErr_SetString(PyExc_OverflowError,
         323                 :            :             "unsigned short is greater than maximum");
         324                 :          0 :         return -1;
         325                 :            :     }
         326         [ #  # ]:          0 :     if (i >= 0)
         327                 :          0 :         ((short *)ap->ob_item)[i] = (short)x;
         328                 :          0 :     return 0;
         329                 :            : }
         330                 :            :
         331                 :            : static PyObject *
         332                 :          0 : i_getitem(arrayobject *ap, Py_ssize_t i)
         333                 :            : {
         334                 :          0 :     return PyLong_FromLong((long) ((int *)ap->ob_item)[i]);
         335                 :            : }
         336                 :            :
         337                 :            : static int
         338                 :          0 : i_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
         339                 :            : {
         340                 :            :     int x;
         341                 :            :     /* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */
         342         [ #  # ]:          0 :     if (!PyArg_Parse(v, "i;array item must be integer", &x))
         343                 :          0 :         return -1;
         344         [ #  # ]:          0 :     if (i >= 0)
         345                 :          0 :                  ((int *)ap->ob_item)[i] = x;
         346                 :          0 :     return 0;
         347                 :            : }
         348                 :            :
         349                 :            : static PyObject *
         350                 :          0 : II_getitem(arrayobject *ap, Py_ssize_t i)
         351                 :            : {
         352                 :          0 :     return PyLong_FromUnsignedLong(
         353                 :          0 :         (unsigned long) ((unsigned int *)ap->ob_item)[i]);
         354                 :            : }
         355                 :            :
         356                 :            : static int
         357                 :          0 : II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
         358                 :            : {
         359                 :            :     unsigned long x;
         360                 :          0 :     int do_decref = 0; /* if nb_int was called */
         361                 :            :
         362         [ #  # ]:          0 :     if (!PyLong_Check(v)) {
         363                 :          0 :         v = _PyNumber_Index(v);
         364         [ #  # ]:          0 :         if (NULL == v) {
         365                 :          0 :             return -1;
         366                 :            :         }
         367                 :          0 :         do_decref = 1;
         368                 :            :     }
         369                 :          0 :     x = PyLong_AsUnsignedLong(v);
         370   [ #  #  #  # ]:          0 :     if (x == (unsigned long)-1 && PyErr_Occurred()) {
         371         [ #  # ]:          0 :         if (do_decref) {
         372                 :          0 :             Py_DECREF(v);
         373                 :            :         }
         374                 :          0 :         return -1;
         375                 :            :     }
         376         [ #  # ]:          0 :     if (x > UINT_MAX) {
         377                 :          0 :         PyErr_SetString(PyExc_OverflowError,
         378                 :            :                         "unsigned int is greater than maximum");
         379         [ #  # ]:          0 :         if (do_decref) {
         380                 :          0 :             Py_DECREF(v);
         381                 :            :         }
         382                 :          0 :         return -1;
         383                 :            :     }
         384         [ #  # ]:          0 :     if (i >= 0)
         385                 :          0 :         ((unsigned int *)ap->ob_item)[i] = (unsigned int)x;
         386                 :            :
         387         [ #  # ]:          0 :     if (do_decref) {
         388                 :          0 :         Py_DECREF(v);
         389                 :            :     }
         390                 :          0 :     return 0;
         391                 :            : }
         392                 :            :
         393                 :            : static PyObject *
         394                 :          0 : l_getitem(arrayobject *ap, Py_ssize_t i)
         395                 :            : {
         396                 :          0 :     return PyLong_FromLong(((long *)ap->ob_item)[i]);
         397                 :            : }
         398                 :            :
         399                 :            : static int
         400                 :          0 : l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
         401                 :            : {
         402                 :            :     long x;
         403         [ #  # ]:          0 :     if (!PyArg_Parse(v, "l;array item must be integer", &x))
         404                 :          0 :         return -1;
         405         [ #  # ]:          0 :     if (i >= 0)
         406                 :          0 :                  ((long *)ap->ob_item)[i] = x;
         407                 :          0 :     return 0;
         408                 :            : }
         409                 :            :
         410                 :            : static PyObject *
         411                 :          0 : LL_getitem(arrayobject *ap, Py_ssize_t i)
         412                 :            : {
         413                 :          0 :     return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]);
         414                 :            : }
         415                 :            :
         416                 :            : static int
         417                 :          0 : LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
         418                 :            : {
         419                 :            :     unsigned long x;
         420                 :          0 :     int do_decref = 0; /* if nb_int was called */
         421                 :            :
         422         [ #  # ]:          0 :     if (!PyLong_Check(v)) {
         423                 :          0 :         v = _PyNumber_Index(v);
         424         [ #  # ]:          0 :         if (NULL == v) {
         425                 :          0 :             return -1;
         426                 :            :         }
         427                 :          0 :         do_decref = 1;
         428                 :            :     }
         429                 :          0 :     x = PyLong_AsUnsignedLong(v);
         430   [ #  #  #  # ]:          0 :     if (x == (unsigned long)-1 && PyErr_Occurred()) {
         431         [ #  # ]:          0 :         if (do_decref) {
         432                 :          0 :             Py_DECREF(v);
         433                 :            :         }
         434                 :          0 :         return -1;
         435                 :            :     }
         436         [ #  # ]:          0 :     if (i >= 0)
         437                 :          0 :         ((unsigned long *)ap->ob_item)[i] = x;
         438                 :            :
         439         [ #  # ]:          0 :     if (do_decref) {
         440                 :          0 :         Py_DECREF(v);
         441                 :            :     }
         442                 :          0 :     return 0;
         443                 :            : }
         444                 :            :
         445                 :            : static PyObject *
         446                 :          0 : q_getitem(arrayobject *ap, Py_ssize_t i)
         447                 :            : {
         448                 :          0 :     return PyLong_FromLongLong(((long long *)ap->ob_item)[i]);
         449                 :            : }
         450                 :            :
         451                 :            : static int
         452                 :          0 : q_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
         453                 :            : {
         454                 :            :     long long x;
         455         [ #  # ]:          0 :     if (!PyArg_Parse(v, "L;array item must be integer", &x))
         456                 :          0 :         return -1;
         457         [ #  # ]:          0 :     if (i >= 0)
         458                 :          0 :         ((long long *)ap->ob_item)[i] = x;
         459                 :          0 :     return 0;
         460                 :            : }
         461                 :            :
         462                 :            : static PyObject *
         463                 :          0 : QQ_getitem(arrayobject *ap, Py_ssize_t i)
         464                 :            : {
         465                 :          0 :     return PyLong_FromUnsignedLongLong(
         466                 :          0 :         ((unsigned long long *)ap->ob_item)[i]);
         467                 :            : }
         468                 :            :
         469                 :            : static int
         470                 :          0 : QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
         471                 :            : {
         472                 :            :     unsigned long long x;
         473                 :          0 :     int do_decref = 0; /* if nb_int was called */
         474                 :            :
         475         [ #  # ]:          0 :     if (!PyLong_Check(v)) {
         476                 :          0 :         v = _PyNumber_Index(v);
         477         [ #  # ]:          0 :         if (NULL == v) {
         478                 :          0 :             return -1;
         479                 :            :         }
         480                 :          0 :         do_decref = 1;
         481                 :            :     }
         482                 :          0 :     x = PyLong_AsUnsignedLongLong(v);
         483   [ #  #  #  # ]:          0 :     if (x == (unsigned long long)-1 && PyErr_Occurred()) {
         484         [ #  # ]:          0 :         if (do_decref) {
         485                 :          0 :             Py_DECREF(v);
         486                 :            :         }
         487                 :          0 :         return -1;
         488                 :            :     }
         489         [ #  # ]:          0 :     if (i >= 0)
         490                 :          0 :         ((unsigned long long *)ap->ob_item)[i] = x;
         491                 :            :
         492         [ #  # ]:          0 :     if (do_decref) {
         493                 :          0 :         Py_DECREF(v);
         494                 :            :     }
         495                 :          0 :     return 0;
         496                 :            : }
         497                 :            :
         498                 :            : static PyObject *
         499                 :          0 : f_getitem(arrayobject *ap, Py_ssize_t i)
         500                 :            : {
         501                 :          0 :     return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]);
         502                 :            : }
         503                 :            :
         504                 :            : static int
         505                 :          0 : f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
         506                 :            : {
         507                 :            :     float x;
         508         [ #  # ]:          0 :     if (!PyArg_Parse(v, "f;array item must be float", &x))
         509                 :          0 :         return -1;
         510         [ #  # ]:          0 :     if (i >= 0)
         511                 :          0 :                  ((float *)ap->ob_item)[i] = x;
         512                 :          0 :     return 0;
         513                 :            : }
         514                 :            :
         515                 :            : static PyObject *
         516                 :          0 : d_getitem(arrayobject *ap, Py_ssize_t i)
         517                 :            : {
         518                 :          0 :     return PyFloat_FromDouble(((double *)ap->ob_item)[i]);
         519                 :            : }
         520                 :            :
         521                 :            : static int
         522                 :          0 : d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
         523                 :            : {
         524                 :            :     double x;
         525         [ #  # ]:          0 :     if (!PyArg_Parse(v, "d;array item must be float", &x))
         526                 :          0 :         return -1;
         527         [ #  # ]:          0 :     if (i >= 0)
         528                 :          0 :                  ((double *)ap->ob_item)[i] = x;
         529                 :          0 :     return 0;
         530                 :            : }
         531                 :            :
         532                 :            : #define DEFINE_COMPAREITEMS(code, type) \
         533                 :            :     static int \
         534                 :            :     code##_compareitems(const void *lhs, const void *rhs, Py_ssize_t length) \
         535                 :            :     { \
         536                 :            :         const type *a = lhs, *b = rhs; \
         537                 :            :         for (Py_ssize_t i = 0; i < length; ++i) \
         538                 :            :             if (a[i] != b[i]) \
         539                 :            :                 return a[i] < b[i] ? -1 : 1; \
         540                 :            :         return 0; \
         541                 :            :     }
         542                 :            :
         543   [ #  #  #  #  :          0 : DEFINE_COMPAREITEMS(b, signed char)
                       #  # ]
         544   [ #  #  #  #  :          0 : DEFINE_COMPAREITEMS(BB, unsigned char)
                       #  # ]
         545   [ #  #  #  #  :          0 : DEFINE_COMPAREITEMS(u, wchar_t)
                       #  # ]
         546   [ #  #  #  #  :          0 : DEFINE_COMPAREITEMS(h, short)
                       #  # ]
         547   [ #  #  #  #  :          0 : DEFINE_COMPAREITEMS(HH, unsigned short)
                       #  # ]
         548   [ #  #  #  #  :          0 : DEFINE_COMPAREITEMS(i, int)
                       #  # ]
         549   [ #  #  #  #  :          0 : DEFINE_COMPAREITEMS(II, unsigned int)
                       #  # ]
         550   [ #  #  #  #  :          0 : DEFINE_COMPAREITEMS(l, long)
                       #  # ]
         551   [ #  #  #  #  :          0 : DEFINE_COMPAREITEMS(LL, unsigned long)
                       #  # ]
         552   [ #  #  #  #  :          0 : DEFINE_COMPAREITEMS(q, long long)
                       #  # ]
         553   [ #  #  #  #  :          0 : DEFINE_COMPAREITEMS(QQ, unsigned long long)
                       #  # ]
         554                 :            :
         555                 :            : /* Description of types.
         556                 :            :  *
         557                 :            :  * Don't forget to update typecode_to_mformat_code() if you add a new
         558                 :            :  * typecode.
         559                 :            :  */
         560                 :            : static const struct arraydescr descriptors[] = {
         561                 :            :     {'b', 1, b_getitem, b_setitem, b_compareitems, "b", 1, 1},
         562                 :            :     {'B', 1, BB_getitem, BB_setitem, BB_compareitems, "B", 1, 0},
         563                 :            :     {'u', sizeof(wchar_t), u_getitem, u_setitem, u_compareitems, "u", 0, 0},
         564                 :            :     {'h', sizeof(short), h_getitem, h_setitem, h_compareitems, "h", 1, 1},
         565                 :            :     {'H', sizeof(short), HH_getitem, HH_setitem, HH_compareitems, "H", 1, 0},
         566                 :            :     {'i', sizeof(int), i_getitem, i_setitem, i_compareitems, "i", 1, 1},
         567                 :            :     {'I', sizeof(int), II_getitem, II_setitem, II_compareitems, "I", 1, 0},
         568                 :            :     {'l', sizeof(long), l_getitem, l_setitem, l_compareitems, "l", 1, 1},
         569                 :            :     {'L', sizeof(long), LL_getitem, LL_setitem, LL_compareitems, "L", 1, 0},
         570                 :            :     {'q', sizeof(long long), q_getitem, q_setitem, q_compareitems, "q", 1, 1},
         571                 :            :     {'Q', sizeof(long long), QQ_getitem, QQ_setitem, QQ_compareitems, "Q", 1, 0},
         572                 :            :     {'f', sizeof(float), f_getitem, f_setitem, NULL, "f", 0, 0},
         573                 :            :     {'d', sizeof(double), d_getitem, d_setitem, NULL, "d", 0, 0},
         574                 :            :     {'\0', 0, 0, 0, 0, 0, 0} /* Sentinel */
         575                 :            : };
         576                 :            :
         577                 :            : /****************************************************************************
         578                 :            : Implementations of array object methods.
         579                 :            : ****************************************************************************/
         580                 :            : /*[clinic input]
         581                 :            : class array.array "arrayobject *" "ArrayType"
         582                 :            : [clinic start generated code]*/
         583                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=a5c29edf59f176a3]*/
         584                 :            :
         585                 :            : static PyObject *
         586                 :          0 : newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr)
         587                 :            : {
         588                 :            :     arrayobject *op;
         589                 :            :     size_t nbytes;
         590                 :            :
         591         [ #  # ]:          0 :     if (size < 0) {
         592                 :          0 :         PyErr_BadInternalCall();
         593                 :          0 :         return NULL;
         594                 :            :     }
         595                 :            :
         596                 :            :     /* Check for overflow */
         597         [ #  # ]:          0 :     if (size > PY_SSIZE_T_MAX / descr->itemsize) {
         598                 :          0 :         return PyErr_NoMemory();
         599                 :            :     }
         600                 :          0 :     nbytes = size * descr->itemsize;
         601                 :          0 :     op = (arrayobject *) type->tp_alloc(type, 0);
         602         [ #  # ]:          0 :     if (op == NULL) {
         603                 :          0 :         return NULL;
         604                 :            :     }
         605                 :          0 :     op->ob_descr = descr;
         606                 :          0 :     op->allocated = size;
         607                 :          0 :     op->weakreflist = NULL;
         608                 :          0 :     Py_SET_SIZE(op, size);
         609         [ #  # ]:          0 :     if (size <= 0) {
         610                 :          0 :         op->ob_item = NULL;
         611                 :            :     }
         612                 :            :     else {
         613         [ #  # ]:          0 :         op->ob_item = PyMem_NEW(char, nbytes);
         614         [ #  # ]:          0 :         if (op->ob_item == NULL) {
         615                 :          0 :             Py_DECREF(op);
         616                 :          0 :             return PyErr_NoMemory();
         617                 :            :         }
         618                 :            :     }
         619                 :          0 :     op->ob_exports = 0;
         620                 :          0 :     return (PyObject *) op;
         621                 :            : }
         622                 :            :
         623                 :            : static PyObject *
         624                 :          0 : getarrayitem(PyObject *op, Py_ssize_t i)
         625                 :            : {
         626                 :            : #ifndef NDEBUG
         627                 :            :     array_state *state = find_array_state_by_type(Py_TYPE(op));
         628                 :            :     assert(array_Check(op, state));
         629                 :            : #endif
         630                 :            :     arrayobject *ap;
         631                 :          0 :     ap = (arrayobject *)op;
         632                 :            :     assert(i>=0 && i<Py_SIZE(ap));
         633                 :          0 :     return (*ap->ob_descr->getitem)(ap, i);
         634                 :            : }
         635                 :            :
         636                 :            : static int
         637                 :          0 : ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
         638                 :            : {
         639                 :            :     char *items;
         640                 :          0 :     Py_ssize_t n = Py_SIZE(self);
         641         [ #  # ]:          0 :     if (v == NULL) {
         642                 :          0 :         PyErr_BadInternalCall();
         643                 :          0 :         return -1;
         644                 :            :     }
         645         [ #  # ]:          0 :     if ((*self->ob_descr->setitem)(self, -1, v) < 0)
         646                 :          0 :         return -1;
         647                 :            :
         648         [ #  # ]:          0 :     if (array_resize(self, n+1) == -1)
         649                 :          0 :         return -1;
         650                 :          0 :     items = self->ob_item;
         651         [ #  # ]:          0 :     if (where < 0) {
         652                 :          0 :         where += n;
         653         [ #  # ]:          0 :         if (where < 0)
         654                 :          0 :             where = 0;
         655                 :            :     }
         656         [ #  # ]:          0 :     if (where > n)
         657                 :          0 :         where = n;
         658                 :            :     /* appends don't need to call memmove() */
         659         [ #  # ]:          0 :     if (where != n)
         660                 :          0 :         memmove(items + (where+1)*self->ob_descr->itemsize,
         661                 :          0 :             items + where*self->ob_descr->itemsize,
         662                 :          0 :             (n-where)*self->ob_descr->itemsize);
         663                 :          0 :     return (*self->ob_descr->setitem)(self, where, v);
         664                 :            : }
         665                 :            :
         666                 :            : /* Methods */
         667                 :            :
         668                 :            : static int
         669                 :          0 : array_tp_traverse(arrayobject *op, visitproc visit, void *arg)
         670                 :            : {
         671   [ #  #  #  # ]:          0 :     Py_VISIT(Py_TYPE(op));
         672                 :          0 :     return 0;
         673                 :            : }
         674                 :            :
         675                 :            : static void
         676                 :          0 : array_dealloc(arrayobject *op)
         677                 :            : {
         678                 :          0 :     PyTypeObject *tp = Py_TYPE(op);
         679                 :          0 :     PyObject_GC_UnTrack(op);
         680                 :            :
         681         [ #  # ]:          0 :     if (op->weakreflist != NULL)
         682                 :          0 :         PyObject_ClearWeakRefs((PyObject *) op);
         683         [ #  # ]:          0 :     if (op->ob_item != NULL)
         684                 :          0 :         PyMem_Free(op->ob_item);
         685                 :          0 :     tp->tp_free(op);
         686                 :          0 :     Py_DECREF(tp);
         687                 :          0 : }
         688                 :            :
         689                 :            : static PyObject *
         690                 :          0 : array_richcompare(PyObject *v, PyObject *w, int op)
         691                 :            : {
         692                 :          0 :     array_state *state = find_array_state_by_type(Py_TYPE(v));
         693                 :            :     arrayobject *va, *wa;
         694                 :          0 :     PyObject *vi = NULL;
         695                 :          0 :     PyObject *wi = NULL;
         696                 :            :     Py_ssize_t i, k;
         697                 :            :     PyObject *res;
         698                 :            :
         699   [ #  #  #  # ]:          0 :     if (!array_Check(v, state) || !array_Check(w, state))
         700                 :          0 :         Py_RETURN_NOTIMPLEMENTED;
         701                 :            :
         702                 :          0 :     va = (arrayobject *)v;
         703                 :          0 :     wa = (arrayobject *)w;
         704                 :            :
         705   [ #  #  #  #  :          0 :     if (Py_SIZE(va) != Py_SIZE(wa) && (op == Py_EQ || op == Py_NE)) {
                       #  # ]
         706                 :            :         /* Shortcut: if the lengths differ, the arrays differ */
         707         [ #  # ]:          0 :         if (op == Py_EQ)
         708                 :          0 :             res = Py_False;
         709                 :            :         else
         710                 :          0 :             res = Py_True;
         711                 :          0 :         return Py_NewRef(res);
         712                 :            :     }
         713                 :            :
         714   [ #  #  #  # ]:          0 :     if (va->ob_descr == wa->ob_descr && va->ob_descr->compareitems != NULL) {
         715                 :            :         /* Fast path:
         716                 :            :            arrays with same types can have their buffers compared directly */
         717         [ #  # ]:          0 :         Py_ssize_t common_length = Py_MIN(Py_SIZE(va), Py_SIZE(wa));
         718                 :          0 :         int result = va->ob_descr->compareitems(va->ob_item, wa->ob_item,
         719                 :            :                                                 common_length);
         720         [ #  # ]:          0 :         if (result == 0)
         721                 :          0 :             goto compare_sizes;
         722                 :            :
         723                 :            :         int cmp;
         724   [ #  #  #  #  :          0 :         switch (op) {
                    #  #  # ]
         725                 :          0 :         case Py_LT: cmp = result < 0; break;
         726                 :          0 :         case Py_LE: cmp = result <= 0; break;
         727                 :          0 :         case Py_EQ: cmp = result == 0; break;
         728                 :          0 :         case Py_NE: cmp = result != 0; break;
         729                 :          0 :         case Py_GT: cmp = result > 0; break;
         730                 :          0 :         case Py_GE: cmp = result >= 0; break;
         731                 :          0 :         default: return NULL; /* cannot happen */
         732                 :            :         }
         733         [ #  # ]:          0 :         PyObject *res = cmp ? Py_True : Py_False;
         734                 :          0 :         return Py_NewRef(res);
         735                 :            :     }
         736                 :            :
         737                 :            :
         738                 :            :     /* Search for the first index where items are different */
         739                 :          0 :     k = 1;
         740   [ #  #  #  # ]:          0 :     for (i = 0; i < Py_SIZE(va) && i < Py_SIZE(wa); i++) {
         741                 :          0 :         vi = getarrayitem(v, i);
         742                 :          0 :         wi = getarrayitem(w, i);
         743   [ #  #  #  # ]:          0 :         if (vi == NULL || wi == NULL) {
         744                 :          0 :             Py_XDECREF(vi);
         745                 :          0 :             Py_XDECREF(wi);
         746                 :          0 :             return NULL;
         747                 :            :         }
         748                 :          0 :         k = PyObject_RichCompareBool(vi, wi, Py_EQ);
         749         [ #  # ]:          0 :         if (k == 0)
         750                 :          0 :             break; /* Keeping vi and wi alive! */
         751                 :          0 :         Py_DECREF(vi);
         752                 :          0 :         Py_DECREF(wi);
         753         [ #  # ]:          0 :         if (k < 0)
         754                 :          0 :             return NULL;
         755                 :            :     }
         756                 :            :
         757         [ #  # ]:          0 :     if (k) {
         758                 :            :         /* No more items to compare -- compare sizes */
         759                 :          0 :         compare_sizes: ;
         760                 :          0 :         Py_ssize_t vs = Py_SIZE(va);
         761                 :          0 :         Py_ssize_t ws = Py_SIZE(wa);
         762                 :            :         int cmp;
         763   [ #  #  #  #  :          0 :         switch (op) {
                    #  #  # ]
         764                 :          0 :         case Py_LT: cmp = vs <  ws; break;
         765                 :          0 :         case Py_LE: cmp = vs <= ws; break;
         766                 :            :         /* If the lengths were not equal,
         767                 :            :            the earlier fast-path check would have caught that. */
         768                 :          0 :         case Py_EQ: assert(vs == ws); cmp = 1; break;
         769                 :          0 :         case Py_NE: assert(vs == ws); cmp = 0; break;
         770                 :          0 :         case Py_GT: cmp = vs >  ws; break;
         771                 :          0 :         case Py_GE: cmp = vs >= ws; break;
         772                 :          0 :         default: return NULL; /* cannot happen */
         773                 :            :         }
         774         [ #  # ]:          0 :         if (cmp)
         775                 :          0 :             res = Py_True;
         776                 :            :         else
         777                 :          0 :             res = Py_False;
         778                 :          0 :         return Py_NewRef(res);
         779                 :            :     }
         780                 :            :
         781                 :            :     /* We have an item that differs.  First, shortcuts for EQ/NE */
         782         [ #  # ]:          0 :     if (op == Py_EQ) {
         783                 :          0 :         res = Py_NewRef(Py_False);
         784                 :            :     }
         785         [ #  # ]:          0 :     else if (op == Py_NE) {
         786                 :          0 :         res = Py_NewRef(Py_True);
         787                 :            :     }
         788                 :            :     else {
         789                 :            :         /* Compare the final item again using the proper operator */
         790                 :          0 :         res = PyObject_RichCompare(vi, wi, op);
         791                 :            :     }
         792                 :          0 :     Py_DECREF(vi);
         793                 :          0 :     Py_DECREF(wi);
         794                 :          0 :     return res;
         795                 :            : }
         796                 :            :
         797                 :            : static Py_ssize_t
         798                 :          0 : array_length(arrayobject *a)
         799                 :            : {
         800                 :          0 :     return Py_SIZE(a);
         801                 :            : }
         802                 :            :
         803                 :            : static PyObject *
         804                 :          0 : array_item(arrayobject *a, Py_ssize_t i)
         805                 :            : {
         806   [ #  #  #  # ]:          0 :     if (i < 0 || i >= Py_SIZE(a)) {
         807                 :          0 :         PyErr_SetString(PyExc_IndexError, "array index out of range");
         808                 :          0 :         return NULL;
         809                 :            :     }
         810                 :          0 :     return getarrayitem((PyObject *)a, i);
         811                 :            : }
         812                 :            :
         813                 :            : static PyObject *
         814                 :          0 : array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
         815                 :            : {
         816                 :          0 :     array_state *state = find_array_state_by_type(Py_TYPE(a));
         817                 :            :     arrayobject *np;
         818                 :            :
         819         [ #  # ]:          0 :     if (ilow < 0)
         820                 :          0 :         ilow = 0;
         821         [ #  # ]:          0 :     else if (ilow > Py_SIZE(a))
         822                 :          0 :         ilow = Py_SIZE(a);
         823         [ #  # ]:          0 :     if (ihigh < 0)
         824                 :          0 :         ihigh = 0;
         825         [ #  # ]:          0 :     if (ihigh < ilow)
         826                 :          0 :         ihigh = ilow;
         827         [ #  # ]:          0 :     else if (ihigh > Py_SIZE(a))
         828                 :          0 :         ihigh = Py_SIZE(a);
         829                 :          0 :     np = (arrayobject *) newarrayobject(state->ArrayType, ihigh - ilow, a->ob_descr);
         830         [ #  # ]:          0 :     if (np == NULL)
         831                 :          0 :         return NULL;
         832         [ #  # ]:          0 :     if (ihigh > ilow) {
         833                 :          0 :         memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
         834                 :          0 :                (ihigh-ilow) * a->ob_descr->itemsize);
         835                 :            :     }
         836                 :          0 :     return (PyObject *)np;
         837                 :            : }
         838                 :            :
         839                 :            :
         840                 :            : /*[clinic input]
         841                 :            : array.array.__copy__
         842                 :            :
         843                 :            : Return a copy of the array.
         844                 :            : [clinic start generated code]*/
         845                 :            :
         846                 :            : static PyObject *
         847                 :          0 : array_array___copy___impl(arrayobject *self)
         848                 :            : /*[clinic end generated code: output=dec7c3f925d9619e input=ad1ee5b086965f09]*/
         849                 :            : {
         850                 :          0 :     return array_slice(self, 0, Py_SIZE(self));
         851                 :            : }
         852                 :            :
         853                 :            : /*[clinic input]
         854                 :            : array.array.__deepcopy__
         855                 :            :
         856                 :            :     unused: object
         857                 :            :     /
         858                 :            :
         859                 :            : Return a copy of the array.
         860                 :            : [clinic start generated code]*/
         861                 :            :
         862                 :            : static PyObject *
         863                 :          0 : array_array___deepcopy__(arrayobject *self, PyObject *unused)
         864                 :            : /*[clinic end generated code: output=1ec748d8e14a9faa input=2405ecb4933748c4]*/
         865                 :            : {
         866                 :          0 :     return array_array___copy___impl(self);
         867                 :            : }
         868                 :            :
         869                 :            : static PyObject *
         870                 :          0 : array_concat(arrayobject *a, PyObject *bb)
         871                 :            : {
         872                 :          0 :     array_state *state = find_array_state_by_type(Py_TYPE(a));
         873                 :            :     Py_ssize_t size;
         874                 :            :     arrayobject *np;
         875         [ #  # ]:          0 :     if (!array_Check(bb, state)) {
         876                 :          0 :         PyErr_Format(PyExc_TypeError,
         877                 :            :              "can only append array (not \"%.200s\") to array",
         878                 :          0 :                  Py_TYPE(bb)->tp_name);
         879                 :          0 :         return NULL;
         880                 :            :     }
         881                 :            : #define b ((arrayobject *)bb)
         882         [ #  # ]:          0 :     if (a->ob_descr != b->ob_descr) {
         883                 :          0 :         PyErr_BadArgument();
         884                 :          0 :         return NULL;
         885                 :            :     }
         886         [ #  # ]:          0 :     if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) {
         887                 :          0 :         return PyErr_NoMemory();
         888                 :            :     }
         889                 :          0 :     size = Py_SIZE(a) + Py_SIZE(b);
         890                 :          0 :     np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr);
         891         [ #  # ]:          0 :     if (np == NULL) {
         892                 :          0 :         return NULL;
         893                 :            :     }
         894         [ #  # ]:          0 :     if (Py_SIZE(a) > 0) {
         895                 :          0 :         memcpy(np->ob_item, a->ob_item, Py_SIZE(a)*a->ob_descr->itemsize);
         896                 :            :     }
         897         [ #  # ]:          0 :     if (Py_SIZE(b) > 0) {
         898                 :          0 :         memcpy(np->ob_item + Py_SIZE(a)*a->ob_descr->itemsize,
         899                 :          0 :                b->ob_item, Py_SIZE(b)*b->ob_descr->itemsize);
         900                 :            :     }
         901                 :          0 :     return (PyObject *)np;
         902                 :            : #undef b
         903                 :            : }
         904                 :            :
         905                 :            : static PyObject *
         906                 :          0 : array_repeat(arrayobject *a, Py_ssize_t n)
         907                 :            : {
         908                 :          0 :     array_state *state = find_array_state_by_type(Py_TYPE(a));
         909                 :            :
         910         [ #  # ]:          0 :     if (n < 0)
         911                 :          0 :         n = 0;
         912                 :          0 :     const Py_ssize_t array_length = Py_SIZE(a);
         913   [ #  #  #  # ]:          0 :     if ((array_length != 0) && (n > PY_SSIZE_T_MAX / array_length)) {
         914                 :          0 :         return PyErr_NoMemory();
         915                 :            :     }
         916                 :          0 :     Py_ssize_t size = array_length * n;
         917                 :          0 :     arrayobject* np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr);
         918         [ #  # ]:          0 :     if (np == NULL)
         919                 :          0 :         return NULL;
         920         [ #  # ]:          0 :     if (size == 0)
         921                 :          0 :         return (PyObject *)np;
         922                 :            :
         923                 :          0 :     const Py_ssize_t oldbytes = array_length * a->ob_descr->itemsize;
         924                 :          0 :     const Py_ssize_t newbytes = oldbytes * n;
         925                 :          0 :     _PyBytes_Repeat(np->ob_item, newbytes, a->ob_item, oldbytes);
         926                 :            :
         927                 :          0 :     return (PyObject *)np;
         928                 :            : }
         929                 :            :
         930                 :            : static int
         931                 :          0 : array_del_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
         932                 :            : {
         933                 :            :     char *item;
         934                 :            :     Py_ssize_t d; /* Change in size */
         935         [ #  # ]:          0 :     if (ilow < 0)
         936                 :          0 :         ilow = 0;
         937         [ #  # ]:          0 :     else if (ilow > Py_SIZE(a))
         938                 :          0 :         ilow = Py_SIZE(a);
         939         [ #  # ]:          0 :     if (ihigh < 0)
         940                 :          0 :         ihigh = 0;
         941         [ #  # ]:          0 :     if (ihigh < ilow)
         942                 :          0 :         ihigh = ilow;
         943         [ #  # ]:          0 :     else if (ihigh > Py_SIZE(a))
         944                 :          0 :         ihigh = Py_SIZE(a);
         945                 :          0 :     item = a->ob_item;
         946                 :          0 :     d = ihigh-ilow;
         947                 :            :     /* Issue #4509: If the array has exported buffers and the slice
         948                 :            :        assignment would change the size of the array, fail early to make
         949                 :            :        sure we don't modify it. */
         950   [ #  #  #  # ]:          0 :     if (d != 0 && a->ob_exports > 0) {
         951                 :          0 :         PyErr_SetString(PyExc_BufferError,
         952                 :            :             "cannot resize an array that is exporting buffers");
         953                 :          0 :         return -1;
         954                 :            :     }
         955         [ #  # ]:          0 :     if (d > 0) { /* Delete d items */
         956                 :          0 :         memmove(item + (ihigh-d)*a->ob_descr->itemsize,
         957                 :          0 :             item + ihigh*a->ob_descr->itemsize,
         958                 :          0 :             (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize);
         959         [ #  # ]:          0 :         if (array_resize(a, Py_SIZE(a) - d) == -1)
         960                 :          0 :             return -1;
         961                 :            :     }
         962                 :          0 :     return 0;
         963                 :            : }
         964                 :            :
         965                 :            : static int
         966                 :          0 : array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v)
         967                 :            : {
         968   [ #  #  #  # ]:          0 :     if (i < 0 || i >= Py_SIZE(a)) {
         969                 :          0 :         PyErr_SetString(PyExc_IndexError,
         970                 :            :                          "array assignment index out of range");
         971                 :          0 :         return -1;
         972                 :            :     }
         973         [ #  # ]:          0 :     if (v == NULL)
         974                 :          0 :         return array_del_slice(a, i, i+1);
         975                 :          0 :     return (*a->ob_descr->setitem)(a, i, v);
         976                 :            : }
         977                 :            :
         978                 :            : static int
         979                 :          0 : setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v)
         980                 :            : {
         981                 :            : #ifndef NDEBUG
         982                 :            :     array_state *state = find_array_state_by_type(Py_TYPE(a));
         983                 :            :     assert(array_Check(a, state));
         984                 :            : #endif
         985                 :          0 :     return array_ass_item((arrayobject *)a, i, v);
         986                 :            : }
         987                 :            :
         988                 :            : static int
         989                 :          0 : array_iter_extend(arrayobject *self, PyObject *bb)
         990                 :            : {
         991                 :            :     PyObject *it, *v;
         992                 :            :
         993                 :          0 :     it = PyObject_GetIter(bb);
         994         [ #  # ]:          0 :     if (it == NULL)
         995                 :          0 :         return -1;
         996                 :            :
         997         [ #  # ]:          0 :     while ((v = PyIter_Next(it)) != NULL) {
         998         [ #  # ]:          0 :         if (ins1(self, Py_SIZE(self), v) != 0) {
         999                 :          0 :             Py_DECREF(v);
        1000                 :          0 :             Py_DECREF(it);
        1001                 :          0 :             return -1;
        1002                 :            :         }
        1003                 :          0 :         Py_DECREF(v);
        1004                 :            :     }
        1005                 :          0 :     Py_DECREF(it);
        1006         [ #  # ]:          0 :     if (PyErr_Occurred())
        1007                 :          0 :         return -1;
        1008                 :          0 :     return 0;
        1009                 :            : }
        1010                 :            :
        1011                 :            : static int
        1012                 :          0 : array_do_extend(array_state *state, arrayobject *self, PyObject *bb)
        1013                 :            : {
        1014                 :            :     Py_ssize_t size, oldsize, bbsize;
        1015                 :            :
        1016         [ #  # ]:          0 :     if (!array_Check(bb, state))
        1017                 :          0 :         return array_iter_extend(self, bb);
        1018                 :            : #define b ((arrayobject *)bb)
        1019         [ #  # ]:          0 :     if (self->ob_descr != b->ob_descr) {
        1020                 :          0 :         PyErr_SetString(PyExc_TypeError,
        1021                 :            :                      "can only extend with array of same kind");
        1022                 :          0 :         return -1;
        1023                 :            :     }
        1024         [ #  # ]:          0 :     if ((Py_SIZE(self) > PY_SSIZE_T_MAX - Py_SIZE(b)) ||
        1025         [ #  # ]:          0 :         ((Py_SIZE(self) + Py_SIZE(b)) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
        1026                 :          0 :         PyErr_NoMemory();
        1027                 :          0 :         return -1;
        1028                 :            :     }
        1029                 :          0 :     oldsize = Py_SIZE(self);
        1030                 :            :     /* Get the size of bb before resizing the array since bb could be self. */
        1031                 :          0 :     bbsize = Py_SIZE(bb);
        1032                 :          0 :     size = oldsize + Py_SIZE(b);
        1033         [ #  # ]:          0 :     if (array_resize(self, size) == -1)
        1034                 :          0 :         return -1;
        1035         [ #  # ]:          0 :     if (bbsize > 0) {
        1036                 :          0 :         memcpy(self->ob_item + oldsize * self->ob_descr->itemsize,
        1037                 :          0 :             b->ob_item, bbsize * b->ob_descr->itemsize);
        1038                 :            :     }
        1039                 :            :
        1040                 :          0 :     return 0;
        1041                 :            : #undef b
        1042                 :            : }
        1043                 :            :
        1044                 :            : static PyObject *
        1045                 :          0 : array_inplace_concat(arrayobject *self, PyObject *bb)
        1046                 :            : {
        1047                 :          0 :     array_state *state = find_array_state_by_type(Py_TYPE(self));
        1048                 :            :
        1049         [ #  # ]:          0 :     if (!array_Check(bb, state)) {
        1050                 :          0 :         PyErr_Format(PyExc_TypeError,
        1051                 :            :             "can only extend array with array (not \"%.200s\")",
        1052                 :          0 :             Py_TYPE(bb)->tp_name);
        1053                 :          0 :         return NULL;
        1054                 :            :     }
        1055         [ #  # ]:          0 :     if (array_do_extend(state, self, bb) == -1)
        1056                 :          0 :         return NULL;
        1057                 :          0 :     return Py_NewRef(self);
        1058                 :            : }
        1059                 :            :
        1060                 :            : static PyObject *
        1061                 :          0 : array_inplace_repeat(arrayobject *self, Py_ssize_t n)
        1062                 :            : {
        1063                 :          0 :     const Py_ssize_t array_size = Py_SIZE(self);
        1064                 :            :
        1065   [ #  #  #  # ]:          0 :     if (array_size > 0 && n != 1 ) {
        1066         [ #  # ]:          0 :         if (n < 0)
        1067                 :          0 :             n = 0;
        1068         [ #  # ]:          0 :         if ((self->ob_descr->itemsize != 0) &&
        1069         [ #  # ]:          0 :             (array_size > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
        1070                 :          0 :             return PyErr_NoMemory();
        1071                 :            :         }
        1072                 :          0 :         Py_ssize_t size = array_size * self->ob_descr->itemsize;
        1073   [ #  #  #  # ]:          0 :         if (n > 0 && size > PY_SSIZE_T_MAX / n) {
        1074                 :          0 :             return PyErr_NoMemory();
        1075                 :            :         }
        1076         [ #  # ]:          0 :         if (array_resize(self, n * array_size) == -1)
        1077                 :          0 :             return NULL;
        1078                 :            :
        1079                 :          0 :         _PyBytes_Repeat(self->ob_item, n*size, self->ob_item, size);
        1080                 :            :     }
        1081                 :          0 :     return Py_NewRef(self);
        1082                 :            : }
        1083                 :            :
        1084                 :            :
        1085                 :            : static PyObject *
        1086                 :          0 : ins(arrayobject *self, Py_ssize_t where, PyObject *v)
        1087                 :            : {
        1088         [ #  # ]:          0 :     if (ins1(self, where, v) != 0)
        1089                 :          0 :         return NULL;
        1090                 :          0 :     Py_RETURN_NONE;
        1091                 :            : }
        1092                 :            :
        1093                 :            : /*[clinic input]
        1094                 :            : array.array.count
        1095                 :            :
        1096                 :            :     v: object
        1097                 :            :     /
        1098                 :            :
        1099                 :            : Return number of occurrences of v in the array.
        1100                 :            : [clinic start generated code]*/
        1101                 :            :
        1102                 :            : static PyObject *
        1103                 :          0 : array_array_count(arrayobject *self, PyObject *v)
        1104                 :            : /*[clinic end generated code: output=3dd3624bf7135a3a input=d9bce9d65e39d1f5]*/
        1105                 :            : {
        1106                 :          0 :     Py_ssize_t count = 0;
        1107                 :            :     Py_ssize_t i;
        1108                 :            :
        1109         [ #  # ]:          0 :     for (i = 0; i < Py_SIZE(self); i++) {
        1110                 :            :         PyObject *selfi;
        1111                 :            :         int cmp;
        1112                 :            :
        1113                 :          0 :         selfi = getarrayitem((PyObject *)self, i);
        1114         [ #  # ]:          0 :         if (selfi == NULL)
        1115                 :          0 :             return NULL;
        1116                 :          0 :         cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
        1117                 :          0 :         Py_DECREF(selfi);
        1118         [ #  # ]:          0 :         if (cmp > 0)
        1119                 :          0 :             count++;
        1120         [ #  # ]:          0 :         else if (cmp < 0)
        1121                 :          0 :             return NULL;
        1122                 :            :     }
        1123                 :          0 :     return PyLong_FromSsize_t(count);
        1124                 :            : }
        1125                 :            :
        1126                 :            :
        1127                 :            : /*[clinic input]
        1128                 :            : array.array.index
        1129                 :            :
        1130                 :            :     v: object
        1131                 :            :     start: slice_index(accept={int}) = 0
        1132                 :            :     stop: slice_index(accept={int}, c_default="PY_SSIZE_T_MAX") = sys.maxsize
        1133                 :            :     /
        1134                 :            :
        1135                 :            : Return index of first occurrence of v in the array.
        1136                 :            :
        1137                 :            : Raise ValueError if the value is not present.
        1138                 :            : [clinic start generated code]*/
        1139                 :            :
        1140                 :            : static PyObject *
        1141                 :          0 : array_array_index_impl(arrayobject *self, PyObject *v, Py_ssize_t start,
        1142                 :            :                        Py_ssize_t stop)
        1143                 :            : /*[clinic end generated code: output=c45e777880c99f52 input=089dff7baa7e5a7e]*/
        1144                 :            : {
        1145         [ #  # ]:          0 :     if (start < 0) {
        1146                 :          0 :         start += Py_SIZE(self);
        1147         [ #  # ]:          0 :         if (start < 0) {
        1148                 :          0 :             start = 0;
        1149                 :            :         }
        1150                 :            :     }
        1151         [ #  # ]:          0 :     if (stop < 0) {
        1152                 :          0 :         stop += Py_SIZE(self);
        1153                 :            :     }
        1154                 :            :     // Use Py_SIZE() for every iteration in case the array is mutated
        1155                 :            :     // during PyObject_RichCompareBool()
        1156   [ #  #  #  # ]:          0 :     for (Py_ssize_t i = start; i < stop && i < Py_SIZE(self); i++) {
        1157                 :            :         PyObject *selfi;
        1158                 :            :         int cmp;
        1159                 :            :
        1160                 :          0 :         selfi = getarrayitem((PyObject *)self, i);
        1161         [ #  # ]:          0 :         if (selfi == NULL)
        1162                 :          0 :             return NULL;
        1163                 :          0 :         cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
        1164                 :          0 :         Py_DECREF(selfi);
        1165         [ #  # ]:          0 :         if (cmp > 0) {
        1166                 :          0 :             return PyLong_FromSsize_t(i);
        1167                 :            :         }
        1168         [ #  # ]:          0 :         else if (cmp < 0)
        1169                 :          0 :             return NULL;
        1170                 :            :     }
        1171                 :          0 :     PyErr_SetString(PyExc_ValueError, "array.index(x): x not in array");
        1172                 :          0 :     return NULL;
        1173                 :            : }
        1174                 :            :
        1175                 :            : static int
        1176                 :          0 : array_contains(arrayobject *self, PyObject *v)
        1177                 :            : {
        1178                 :            :     Py_ssize_t i;
        1179                 :            :     int cmp;
        1180                 :            :
        1181   [ #  #  #  # ]:          0 :     for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(self); i++) {
        1182                 :          0 :         PyObject *selfi = getarrayitem((PyObject *)self, i);
        1183         [ #  # ]:          0 :         if (selfi == NULL)
        1184                 :          0 :             return -1;
        1185                 :          0 :         cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
        1186                 :          0 :         Py_DECREF(selfi);
        1187                 :            :     }
        1188                 :          0 :     return cmp;
        1189                 :            : }
        1190                 :            :
        1191                 :            : /*[clinic input]
        1192                 :            : array.array.remove
        1193                 :            :
        1194                 :            :     v: object
        1195                 :            :     /
        1196                 :            :
        1197                 :            : Remove the first occurrence of v in the array.
        1198                 :            : [clinic start generated code]*/
        1199                 :            :
        1200                 :            : static PyObject *
        1201                 :          0 : array_array_remove(arrayobject *self, PyObject *v)
        1202                 :            : /*[clinic end generated code: output=bef06be9fdf9dceb input=0b1e5aed25590027]*/
        1203                 :            : {
        1204                 :            :     Py_ssize_t i;
        1205                 :            :
        1206         [ #  # ]:          0 :     for (i = 0; i < Py_SIZE(self); i++) {
        1207                 :            :         PyObject *selfi;
        1208                 :            :         int cmp;
        1209                 :            :
        1210                 :          0 :         selfi = getarrayitem((PyObject *)self,i);
        1211         [ #  # ]:          0 :         if (selfi == NULL)
        1212                 :          0 :             return NULL;
        1213                 :          0 :         cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
        1214                 :          0 :         Py_DECREF(selfi);
        1215         [ #  # ]:          0 :         if (cmp > 0) {
        1216         [ #  # ]:          0 :             if (array_del_slice(self, i, i+1) != 0)
        1217                 :          0 :                 return NULL;
        1218                 :          0 :             Py_RETURN_NONE;
        1219                 :            :         }
        1220         [ #  # ]:          0 :         else if (cmp < 0)
        1221                 :          0 :             return NULL;
        1222                 :            :     }
        1223                 :          0 :     PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in array");
        1224                 :          0 :     return NULL;
        1225                 :            : }
        1226                 :            :
        1227                 :            : /*[clinic input]
        1228                 :            : array.array.pop
        1229                 :            :
        1230                 :            :     i: Py_ssize_t = -1
        1231                 :            :     /
        1232                 :            :
        1233                 :            : Return the i-th element and delete it from the array.
        1234                 :            :
        1235                 :            : i defaults to -1.
        1236                 :            : [clinic start generated code]*/
        1237                 :            :
        1238                 :            : static PyObject *
        1239                 :          0 : array_array_pop_impl(arrayobject *self, Py_ssize_t i)
        1240                 :            : /*[clinic end generated code: output=bc1f0c54fe5308e4 input=8e5feb4c1a11cd44]*/
        1241                 :            : {
        1242                 :            :     PyObject *v;
        1243                 :            :
        1244         [ #  # ]:          0 :     if (Py_SIZE(self) == 0) {
        1245                 :            :         /* Special-case most common failure cause */
        1246                 :          0 :         PyErr_SetString(PyExc_IndexError, "pop from empty array");
        1247                 :          0 :         return NULL;
        1248                 :            :     }
        1249         [ #  # ]:          0 :     if (i < 0)
        1250                 :          0 :         i += Py_SIZE(self);
        1251   [ #  #  #  # ]:          0 :     if (i < 0 || i >= Py_SIZE(self)) {
        1252                 :          0 :         PyErr_SetString(PyExc_IndexError, "pop index out of range");
        1253                 :          0 :         return NULL;
        1254                 :            :     }
        1255                 :          0 :     v = getarrayitem((PyObject *)self, i);
        1256         [ #  # ]:          0 :     if (v == NULL)
        1257                 :          0 :         return NULL;
        1258         [ #  # ]:          0 :     if (array_del_slice(self, i, i+1) != 0) {
        1259                 :          0 :         Py_DECREF(v);
        1260                 :          0 :         return NULL;
        1261                 :            :     }
        1262                 :          0 :     return v;
        1263                 :            : }
        1264                 :            :
        1265                 :            : /*[clinic input]
        1266                 :            : array.array.extend
        1267                 :            :
        1268                 :            :     cls: defining_class
        1269                 :            :     bb: object
        1270                 :            :     /
        1271                 :            :
        1272                 :            : Append items to the end of the array.
        1273                 :            : [clinic start generated code]*/
        1274                 :            :
        1275                 :            : static PyObject *
        1276                 :          0 : array_array_extend_impl(arrayobject *self, PyTypeObject *cls, PyObject *bb)
        1277                 :            : /*[clinic end generated code: output=e65eb7588f0bc266 input=8eb6817ec4d2cb62]*/
        1278                 :            : {
        1279                 :          0 :     array_state *state = get_array_state_by_class(cls);
        1280                 :            :
        1281         [ #  # ]:          0 :     if (array_do_extend(state, self, bb) == -1)
        1282                 :          0 :         return NULL;
        1283                 :          0 :     Py_RETURN_NONE;
        1284                 :            : }
        1285                 :            :
        1286                 :            : /*[clinic input]
        1287                 :            : array.array.insert
        1288                 :            :
        1289                 :            :     i: Py_ssize_t
        1290                 :            :     v: object
        1291                 :            :     /
        1292                 :            :
        1293                 :            : Insert a new item v into the array before position i.
        1294                 :            : [clinic start generated code]*/
        1295                 :            :
        1296                 :            : static PyObject *
        1297                 :          0 : array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v)
        1298                 :            : /*[clinic end generated code: output=5a3648e278348564 input=5577d1b4383e9313]*/
        1299                 :            : {
        1300                 :          0 :     return ins(self, i, v);
        1301                 :            : }
        1302                 :            :
        1303                 :            : /*[clinic input]
        1304                 :            : array.array.buffer_info
        1305                 :            :
        1306                 :            : Return a tuple (address, length) giving the current memory address and the length in items of the buffer used to hold array's contents.
        1307                 :            :
        1308                 :            : The length should be multiplied by the itemsize attribute to calculate
        1309                 :            : the buffer length in bytes.
        1310                 :            : [clinic start generated code]*/
        1311                 :            :
        1312                 :            : static PyObject *
        1313                 :          0 : array_array_buffer_info_impl(arrayobject *self)
        1314                 :            : /*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=a58bae5c6e1ac6a6]*/
        1315                 :            : {
        1316                 :          0 :     PyObject *retval = NULL, *v;
        1317                 :            :
        1318                 :          0 :     retval = PyTuple_New(2);
        1319         [ #  # ]:          0 :     if (!retval)
        1320                 :          0 :         return NULL;
        1321                 :            :
        1322                 :          0 :     v = PyLong_FromVoidPtr(self->ob_item);
        1323         [ #  # ]:          0 :     if (v == NULL) {
        1324                 :          0 :         Py_DECREF(retval);
        1325                 :          0 :         return NULL;
        1326                 :            :     }
        1327                 :          0 :     PyTuple_SET_ITEM(retval, 0, v);
        1328                 :            :
        1329                 :          0 :     v = PyLong_FromSsize_t(Py_SIZE(self));
        1330         [ #  # ]:          0 :     if (v == NULL) {
        1331                 :          0 :         Py_DECREF(retval);
        1332                 :          0 :         return NULL;
        1333                 :            :     }
        1334                 :          0 :     PyTuple_SET_ITEM(retval, 1, v);
        1335                 :            :
        1336                 :          0 :     return retval;
        1337                 :            : }
        1338                 :            :
        1339                 :            : /*[clinic input]
        1340                 :            : array.array.append
        1341                 :            :
        1342                 :            :     v: object
        1343                 :            :     /
        1344                 :            :
        1345                 :            : Append new value v to the end of the array.
        1346                 :            : [clinic start generated code]*/
        1347                 :            :
        1348                 :            : static PyObject *
        1349                 :          0 : array_array_append(arrayobject *self, PyObject *v)
        1350                 :            : /*[clinic end generated code: output=745a0669bf8db0e2 input=0b98d9d78e78f0fa]*/
        1351                 :            : {
        1352                 :          0 :     return ins(self, Py_SIZE(self), v);
        1353                 :            : }
        1354                 :            :
        1355                 :            : /*[clinic input]
        1356                 :            : array.array.byteswap
        1357                 :            :
        1358                 :            : Byteswap all items of the array.
        1359                 :            :
        1360                 :            : If the items in the array are not 1, 2, 4, or 8 bytes in size, RuntimeError is
        1361                 :            : raised.
        1362                 :            : [clinic start generated code]*/
        1363                 :            :
        1364                 :            : static PyObject *
        1365                 :          0 : array_array_byteswap_impl(arrayobject *self)
        1366                 :            : /*[clinic end generated code: output=5f8236cbdf0d90b5 input=6a85591b950a0186]*/
        1367                 :            : {
        1368                 :            :     char *p;
        1369                 :            :     Py_ssize_t i;
        1370                 :            :
        1371   [ #  #  #  #  :          0 :     switch (self->ob_descr->itemsize) {
                          # ]
        1372                 :          0 :     case 1:
        1373                 :          0 :         break;
        1374                 :          0 :     case 2:
        1375         [ #  # ]:          0 :         for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 2) {
        1376                 :          0 :             char p0 = p[0];
        1377                 :          0 :             p[0] = p[1];
        1378                 :          0 :             p[1] = p0;
        1379                 :            :         }
        1380                 :          0 :         break;
        1381                 :          0 :     case 4:
        1382         [ #  # ]:          0 :         for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 4) {
        1383                 :          0 :             char p0 = p[0];
        1384                 :          0 :             char p1 = p[1];
        1385                 :          0 :             p[0] = p[3];
        1386                 :          0 :             p[1] = p[2];
        1387                 :          0 :             p[2] = p1;
        1388                 :          0 :             p[3] = p0;
        1389                 :            :         }
        1390                 :          0 :         break;
        1391                 :          0 :     case 8:
        1392         [ #  # ]:          0 :         for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 8) {
        1393                 :          0 :             char p0 = p[0];
        1394                 :          0 :             char p1 = p[1];
        1395                 :          0 :             char p2 = p[2];
        1396                 :          0 :             char p3 = p[3];
        1397                 :          0 :             p[0] = p[7];
        1398                 :          0 :             p[1] = p[6];
        1399                 :          0 :             p[2] = p[5];
        1400                 :          0 :             p[3] = p[4];
        1401                 :          0 :             p[4] = p3;
        1402                 :          0 :             p[5] = p2;
        1403                 :          0 :             p[6] = p1;
        1404                 :          0 :             p[7] = p0;
        1405                 :            :         }
        1406                 :          0 :         break;
        1407                 :          0 :     default:
        1408                 :          0 :         PyErr_SetString(PyExc_RuntimeError,
        1409                 :            :                    "don't know how to byteswap this array type");
        1410                 :          0 :         return NULL;
        1411                 :            :     }
        1412                 :          0 :     Py_RETURN_NONE;
        1413                 :            : }
        1414                 :            :
        1415                 :            : /*[clinic input]
        1416                 :            : array.array.reverse
        1417                 :            :
        1418                 :            : Reverse the order of the items in the array.
        1419                 :            : [clinic start generated code]*/
        1420                 :            :
        1421                 :            : static PyObject *
        1422                 :          0 : array_array_reverse_impl(arrayobject *self)
        1423                 :            : /*[clinic end generated code: output=c04868b36f6f4089 input=cd904f01b27d966a]*/
        1424                 :            : {
        1425                 :          0 :     Py_ssize_t itemsize = self->ob_descr->itemsize;
        1426                 :            :     char *p, *q;
        1427                 :            :     /* little buffer to hold items while swapping */
        1428                 :            :     char tmp[256];      /* 8 is probably enough -- but why skimp */
        1429                 :            :     assert((size_t)itemsize <= sizeof(tmp));
        1430                 :            :
        1431         [ #  # ]:          0 :     if (Py_SIZE(self) > 1) {
        1432         [ #  # ]:          0 :         for (p = self->ob_item,
        1433                 :          0 :              q = self->ob_item + (Py_SIZE(self) - 1)*itemsize;
        1434                 :            :              p < q;
        1435                 :          0 :              p += itemsize, q -= itemsize) {
        1436                 :            :             /* memory areas guaranteed disjoint, so memcpy
        1437                 :            :              * is safe (& memmove may be slower).
        1438                 :            :              */
        1439                 :          0 :             memcpy(tmp, p, itemsize);
        1440                 :          0 :             memcpy(p, q, itemsize);
        1441                 :          0 :             memcpy(q, tmp, itemsize);
        1442                 :            :         }
        1443                 :            :     }
        1444                 :            :
        1445                 :          0 :     Py_RETURN_NONE;
        1446                 :            : }
        1447                 :            :
        1448                 :            : /*[clinic input]
        1449                 :            : array.array.fromfile
        1450                 :            :
        1451                 :            :     cls: defining_class
        1452                 :            :     f: object
        1453                 :            :     n: Py_ssize_t
        1454                 :            :     /
        1455                 :            :
        1456                 :            : Read n objects from the file object f and append them to the end of the array.
        1457                 :            : [clinic start generated code]*/
        1458                 :            :
        1459                 :            : static PyObject *
        1460                 :          0 : array_array_fromfile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f,
        1461                 :            :                           Py_ssize_t n)
        1462                 :            : /*[clinic end generated code: output=83a667080b345ebc input=3822e907c1c11f1a]*/
        1463                 :            : {
        1464                 :            :     PyObject *b, *res;
        1465                 :          0 :     Py_ssize_t itemsize = self->ob_descr->itemsize;
        1466                 :            :     Py_ssize_t nbytes;
        1467                 :            :     int not_enough_bytes;
        1468                 :            :
        1469         [ #  # ]:          0 :     if (n < 0) {
        1470                 :          0 :         PyErr_SetString(PyExc_ValueError, "negative count");
        1471                 :          0 :         return NULL;
        1472                 :            :     }
        1473         [ #  # ]:          0 :     if (n > PY_SSIZE_T_MAX / itemsize) {
        1474                 :          0 :         PyErr_NoMemory();
        1475                 :          0 :         return NULL;
        1476                 :            :     }
        1477                 :            :
        1478                 :            :
        1479                 :          0 :     array_state *state = get_array_state_by_class(cls);
        1480                 :            :     assert(state != NULL);
        1481                 :            :
        1482                 :          0 :     nbytes = n * itemsize;
        1483                 :            :
        1484                 :          0 :     b = _PyObject_CallMethod(f, state->str_read, "n", nbytes);
        1485         [ #  # ]:          0 :     if (b == NULL)
        1486                 :          0 :         return NULL;
        1487                 :            :
        1488         [ #  # ]:          0 :     if (!PyBytes_Check(b)) {
        1489                 :          0 :         PyErr_SetString(PyExc_TypeError,
        1490                 :            :                         "read() didn't return bytes");
        1491                 :          0 :         Py_DECREF(b);
        1492                 :          0 :         return NULL;
        1493                 :            :     }
        1494                 :            :
        1495                 :          0 :     not_enough_bytes = (PyBytes_GET_SIZE(b) != nbytes);
        1496                 :            :
        1497                 :          0 :     res = array_array_frombytes(self, b);
        1498                 :          0 :     Py_DECREF(b);
        1499         [ #  # ]:          0 :     if (res == NULL)
        1500                 :          0 :         return NULL;
        1501                 :            :
        1502         [ #  # ]:          0 :     if (not_enough_bytes) {
        1503                 :          0 :         PyErr_SetString(PyExc_EOFError,
        1504                 :            :                         "read() didn't return enough bytes");
        1505                 :          0 :         Py_DECREF(res);
        1506                 :          0 :         return NULL;
        1507                 :            :     }
        1508                 :            :
        1509                 :          0 :     return res;
        1510                 :            : }
        1511                 :            :
        1512                 :            : /*[clinic input]
        1513                 :            : array.array.tofile
        1514                 :            :
        1515                 :            :     cls: defining_class
        1516                 :            :     f: object
        1517                 :            :     /
        1518                 :            :
        1519                 :            : Write all items (as machine values) to the file object f.
        1520                 :            : [clinic start generated code]*/
        1521                 :            :
        1522                 :            : static PyObject *
        1523                 :          0 : array_array_tofile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f)
        1524                 :            : /*[clinic end generated code: output=4560c628d9c18bc2 input=5a24da7a7b407b52]*/
        1525                 :            : {
        1526                 :          0 :     Py_ssize_t nbytes = Py_SIZE(self) * self->ob_descr->itemsize;
        1527                 :            :     /* Write 64K blocks at a time */
        1528                 :            :     /* XXX Make the block size settable */
        1529                 :          0 :     int BLOCKSIZE = 64*1024;
        1530                 :          0 :     Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1) / BLOCKSIZE;
        1531                 :            :     Py_ssize_t i;
        1532                 :            :
        1533         [ #  # ]:          0 :     if (Py_SIZE(self) == 0)
        1534                 :          0 :         goto done;
        1535                 :            :
        1536                 :            :
        1537                 :          0 :     array_state *state = get_array_state_by_class(cls);
        1538                 :            :     assert(state != NULL);
        1539                 :            :
        1540         [ #  # ]:          0 :     for (i = 0; i < nblocks; i++) {
        1541                 :          0 :         char* ptr = self->ob_item + i*BLOCKSIZE;
        1542                 :          0 :         Py_ssize_t size = BLOCKSIZE;
        1543                 :            :         PyObject *bytes, *res;
        1544                 :            :
        1545         [ #  # ]:          0 :         if (i*BLOCKSIZE + size > nbytes)
        1546                 :          0 :             size = nbytes - i*BLOCKSIZE;
        1547                 :          0 :         bytes = PyBytes_FromStringAndSize(ptr, size);
        1548         [ #  # ]:          0 :         if (bytes == NULL)
        1549                 :          0 :             return NULL;
        1550                 :          0 :         res = PyObject_CallMethodOneArg(f, state->str_write, bytes);
        1551                 :          0 :         Py_DECREF(bytes);
        1552         [ #  # ]:          0 :         if (res == NULL)
        1553                 :          0 :             return NULL;
        1554                 :          0 :         Py_DECREF(res); /* drop write result */
        1555                 :            :     }
        1556                 :            :
        1557                 :          0 :   done:
        1558                 :          0 :     Py_RETURN_NONE;
        1559                 :            : }
        1560                 :            :
        1561                 :            : /*[clinic input]
        1562                 :            : array.array.fromlist
        1563                 :            :
        1564                 :            :     list: object
        1565                 :            :     /
        1566                 :            :
        1567                 :            : Append items to array from list.
        1568                 :            : [clinic start generated code]*/
        1569                 :            :
        1570                 :            : static PyObject *
        1571                 :          0 : array_array_fromlist(arrayobject *self, PyObject *list)
        1572                 :            : /*[clinic end generated code: output=26411c2d228a3e3f input=be2605a96c49680f]*/
        1573                 :            : {
        1574                 :            :     Py_ssize_t n;
        1575                 :            :
        1576         [ #  # ]:          0 :     if (!PyList_Check(list)) {
        1577                 :          0 :         PyErr_SetString(PyExc_TypeError, "arg must be list");
        1578                 :          0 :         return NULL;
        1579                 :            :     }
        1580                 :          0 :     n = PyList_Size(list);
        1581         [ #  # ]:          0 :     if (n > 0) {
        1582                 :            :         Py_ssize_t i, old_size;
        1583                 :          0 :         old_size = Py_SIZE(self);
        1584         [ #  # ]:          0 :         if (array_resize(self, old_size + n) == -1)
        1585                 :          0 :             return NULL;
        1586         [ #  # ]:          0 :         for (i = 0; i < n; i++) {
        1587                 :          0 :             PyObject *v = PyList_GET_ITEM(list, i);
        1588         [ #  # ]:          0 :             if ((*self->ob_descr->setitem)(self,
        1589                 :          0 :                             Py_SIZE(self) - n + i, v) != 0) {
        1590                 :          0 :                 array_resize(self, old_size);
        1591                 :          0 :                 return NULL;
        1592                 :            :             }
        1593         [ #  # ]:          0 :             if (n != PyList_GET_SIZE(list)) {
        1594                 :          0 :                 PyErr_SetString(PyExc_RuntimeError,
        1595                 :            :                                 "list changed size during iteration");
        1596                 :          0 :                 array_resize(self, old_size);
        1597                 :          0 :                 return NULL;
        1598                 :            :             }
        1599                 :            :         }
        1600                 :            :     }
        1601                 :          0 :     Py_RETURN_NONE;
        1602                 :            : }
        1603                 :            :
        1604                 :            : /*[clinic input]
        1605                 :            : array.array.tolist
        1606                 :            :
        1607                 :            : Convert array to an ordinary list with the same items.
        1608                 :            : [clinic start generated code]*/
        1609                 :            :
        1610                 :            : static PyObject *
        1611                 :          0 : array_array_tolist_impl(arrayobject *self)
        1612                 :            : /*[clinic end generated code: output=00b60cc9eab8ef89 input=a8d7784a94f86b53]*/
        1613                 :            : {
        1614                 :          0 :     PyObject *list = PyList_New(Py_SIZE(self));
        1615                 :            :     Py_ssize_t i;
        1616                 :            :
        1617         [ #  # ]:          0 :     if (list == NULL)
        1618                 :          0 :         return NULL;
        1619         [ #  # ]:          0 :     for (i = 0; i < Py_SIZE(self); i++) {
        1620                 :          0 :         PyObject *v = getarrayitem((PyObject *)self, i);
        1621         [ #  # ]:          0 :         if (v == NULL)
        1622                 :          0 :             goto error;
        1623                 :          0 :         PyList_SET_ITEM(list, i, v);
        1624                 :            :     }
        1625                 :          0 :     return list;
        1626                 :            :
        1627                 :          0 : error:
        1628                 :          0 :     Py_DECREF(list);
        1629                 :          0 :     return NULL;
        1630                 :            : }
        1631                 :            :
        1632                 :            : static PyObject *
        1633                 :          0 : frombytes(arrayobject *self, Py_buffer *buffer)
        1634                 :            : {
        1635                 :          0 :     int itemsize = self->ob_descr->itemsize;
        1636                 :            :     Py_ssize_t n;
        1637         [ #  # ]:          0 :     if (buffer->itemsize != 1) {
        1638                 :          0 :         PyBuffer_Release(buffer);
        1639                 :          0 :         PyErr_SetString(PyExc_TypeError, "a bytes-like object is required");
        1640                 :          0 :         return NULL;
        1641                 :            :     }
        1642                 :          0 :     n = buffer->len;
        1643         [ #  # ]:          0 :     if (n % itemsize != 0) {
        1644                 :          0 :         PyBuffer_Release(buffer);
        1645                 :          0 :         PyErr_SetString(PyExc_ValueError,
        1646                 :            :                    "bytes length not a multiple of item size");
        1647                 :          0 :         return NULL;
        1648                 :            :     }
        1649                 :          0 :     n = n / itemsize;
        1650         [ #  # ]:          0 :     if (n > 0) {
        1651                 :          0 :         Py_ssize_t old_size = Py_SIZE(self);
        1652         [ #  # ]:          0 :         if ((n > PY_SSIZE_T_MAX - old_size) ||
        1653         [ #  # ]:          0 :             ((old_size + n) > PY_SSIZE_T_MAX / itemsize)) {
        1654                 :          0 :                 PyBuffer_Release(buffer);
        1655                 :          0 :                 return PyErr_NoMemory();
        1656                 :            :         }
        1657         [ #  # ]:          0 :         if (array_resize(self, old_size + n) == -1) {
        1658                 :          0 :             PyBuffer_Release(buffer);
        1659                 :          0 :             return NULL;
        1660                 :            :         }
        1661                 :          0 :         memcpy(self->ob_item + old_size * itemsize,
        1662                 :          0 :             buffer->buf, n * itemsize);
        1663                 :            :     }
        1664                 :          0 :     PyBuffer_Release(buffer);
        1665                 :          0 :     Py_RETURN_NONE;
        1666                 :            : }
        1667                 :            :
        1668                 :            : /*[clinic input]
        1669                 :            : array.array.frombytes
        1670                 :            :
        1671                 :            :     buffer: Py_buffer
        1672                 :            :     /
        1673                 :            :
        1674                 :            : Appends items from the string, interpreting it as an array of machine values, as if it had been read from a file using the fromfile() method.
        1675                 :            : [clinic start generated code]*/
        1676                 :            :
        1677                 :            : static PyObject *
        1678                 :          0 : array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer)
        1679                 :            : /*[clinic end generated code: output=d9842c8f7510a516 input=378db226dfac949e]*/
        1680                 :            : {
        1681                 :          0 :     return frombytes(self, buffer);
        1682                 :            : }
        1683                 :            :
        1684                 :            : /*[clinic input]
        1685                 :            : array.array.tobytes
        1686                 :            :
        1687                 :            : Convert the array to an array of machine values and return the bytes representation.
        1688                 :            : [clinic start generated code]*/
        1689                 :            :
        1690                 :            : static PyObject *
        1691                 :          0 : array_array_tobytes_impl(arrayobject *self)
        1692                 :            : /*[clinic end generated code: output=87318e4edcdc2bb6 input=90ee495f96de34f5]*/
        1693                 :            : {
        1694         [ #  # ]:          0 :     if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
        1695                 :          0 :         return PyBytes_FromStringAndSize(self->ob_item,
        1696                 :          0 :                             Py_SIZE(self) * self->ob_descr->itemsize);
        1697                 :            :     } else {
        1698                 :          0 :         return PyErr_NoMemory();
        1699                 :            :     }
        1700                 :            : }
        1701                 :            :
        1702                 :            : /*[clinic input]
        1703                 :            : array.array.fromunicode
        1704                 :            :
        1705                 :            :     ustr: unicode
        1706                 :            :     /
        1707                 :            :
        1708                 :            : Extends this array with data from the unicode string ustr.
        1709                 :            :
        1710                 :            : The array must be a unicode type array; otherwise a ValueError is raised.
        1711                 :            : Use array.frombytes(ustr.encode(...)) to append Unicode data to an array of
        1712                 :            : some other type.
        1713                 :            : [clinic start generated code]*/
        1714                 :            :
        1715                 :            : static PyObject *
        1716                 :          0 : array_array_fromunicode_impl(arrayobject *self, PyObject *ustr)
        1717                 :            : /*[clinic end generated code: output=24359f5e001a7f2b input=025db1fdade7a4ce]*/
        1718                 :            : {
        1719         [ #  # ]:          0 :     if (self->ob_descr->typecode != 'u') {
        1720                 :          0 :         PyErr_SetString(PyExc_ValueError,
        1721                 :            :             "fromunicode() may only be called on "
        1722                 :            :             "unicode type arrays");
        1723                 :          0 :         return NULL;
        1724                 :            :     }
        1725                 :            :
        1726                 :          0 :     Py_ssize_t ustr_length = PyUnicode_AsWideChar(ustr, NULL, 0);
        1727                 :            :     assert(ustr_length > 0);
        1728         [ #  # ]:          0 :     if (ustr_length > 1) {
        1729                 :          0 :         ustr_length--; /* trim trailing NUL character */
        1730                 :          0 :         Py_ssize_t old_size = Py_SIZE(self);
        1731         [ #  # ]:          0 :         if (array_resize(self, old_size + ustr_length) == -1) {
        1732                 :          0 :             return NULL;
        1733                 :            :         }
        1734                 :            :
        1735                 :            :         // must not fail
        1736                 :          0 :         PyUnicode_AsWideChar(
        1737                 :          0 :             ustr, ((wchar_t *)self->ob_item) + old_size, ustr_length);
        1738                 :            :     }
        1739                 :            :
        1740                 :          0 :     Py_RETURN_NONE;
        1741                 :            : }
        1742                 :            :
        1743                 :            : /*[clinic input]
        1744                 :            : array.array.tounicode
        1745                 :            :
        1746                 :            : Extends this array with data from the unicode string ustr.
        1747                 :            :
        1748                 :            : Convert the array to a unicode string.  The array must be a unicode type array;
        1749                 :            : otherwise a ValueError is raised.  Use array.tobytes().decode() to obtain a
        1750                 :            : unicode string from an array of some other type.
        1751                 :            : [clinic start generated code]*/
        1752                 :            :
        1753                 :            : static PyObject *
        1754                 :          0 : array_array_tounicode_impl(arrayobject *self)
        1755                 :            : /*[clinic end generated code: output=08e442378336e1ef input=127242eebe70b66d]*/
        1756                 :            : {
        1757         [ #  # ]:          0 :     if (self->ob_descr->typecode != 'u') {
        1758                 :          0 :         PyErr_SetString(PyExc_ValueError,
        1759                 :            :              "tounicode() may only be called on unicode type arrays");
        1760                 :          0 :         return NULL;
        1761                 :            :     }
        1762                 :          0 :     return PyUnicode_FromWideChar((wchar_t *) self->ob_item, Py_SIZE(self));
        1763                 :            : }
        1764                 :            :
        1765                 :            : /*[clinic input]
        1766                 :            : array.array.__sizeof__
        1767                 :            :
        1768                 :            : Size of the array in memory, in bytes.
        1769                 :            : [clinic start generated code]*/
        1770                 :            :
        1771                 :            : static PyObject *
        1772                 :          0 : array_array___sizeof___impl(arrayobject *self)
        1773                 :            : /*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/
        1774                 :            : {
        1775                 :          0 :     size_t res = _PyObject_SIZE(Py_TYPE(self));
        1776                 :          0 :     res += (size_t)self->allocated * (size_t)self->ob_descr->itemsize;
        1777                 :          0 :     return PyLong_FromSize_t(res);
        1778                 :            : }
        1779                 :            :
        1780                 :            :
        1781                 :            : /*********************** Pickling support ************************/
        1782                 :            :
        1783                 :            : static const struct mformatdescr {
        1784                 :            :     size_t size;
        1785                 :            :     int is_signed;
        1786                 :            :     int is_big_endian;
        1787                 :            : } mformat_descriptors[] = {
        1788                 :            :     {1, 0, 0},                  /* 0: UNSIGNED_INT8 */
        1789                 :            :     {1, 1, 0},                  /* 1: SIGNED_INT8 */
        1790                 :            :     {2, 0, 0},                  /* 2: UNSIGNED_INT16_LE */
        1791                 :            :     {2, 0, 1},                  /* 3: UNSIGNED_INT16_BE */
        1792                 :            :     {2, 1, 0},                  /* 4: SIGNED_INT16_LE */
        1793                 :            :     {2, 1, 1},                  /* 5: SIGNED_INT16_BE */
        1794                 :            :     {4, 0, 0},                  /* 6: UNSIGNED_INT32_LE */
        1795                 :            :     {4, 0, 1},                  /* 7: UNSIGNED_INT32_BE */
        1796                 :            :     {4, 1, 0},                  /* 8: SIGNED_INT32_LE */
        1797                 :            :     {4, 1, 1},                  /* 9: SIGNED_INT32_BE */
        1798                 :            :     {8, 0, 0},                  /* 10: UNSIGNED_INT64_LE */
        1799                 :            :     {8, 0, 1},                  /* 11: UNSIGNED_INT64_BE */
        1800                 :            :     {8, 1, 0},                  /* 12: SIGNED_INT64_LE */
        1801                 :            :     {8, 1, 1},                  /* 13: SIGNED_INT64_BE */
        1802                 :            :     {4, 0, 0},                  /* 14: IEEE_754_FLOAT_LE */
        1803                 :            :     {4, 0, 1},                  /* 15: IEEE_754_FLOAT_BE */
        1804                 :            :     {8, 0, 0},                  /* 16: IEEE_754_DOUBLE_LE */
        1805                 :            :     {8, 0, 1},                  /* 17: IEEE_754_DOUBLE_BE */
        1806                 :            :     {4, 0, 0},                  /* 18: UTF16_LE */
        1807                 :            :     {4, 0, 1},                  /* 19: UTF16_BE */
        1808                 :            :     {8, 0, 0},                  /* 20: UTF32_LE */
        1809                 :            :     {8, 0, 1}                   /* 21: UTF32_BE */
        1810                 :            : };
        1811                 :            :
        1812                 :            :
        1813                 :            : /*
        1814                 :            :  * Internal: This function is used to find the machine format of a given
        1815                 :            :  * array type code. This returns UNKNOWN_FORMAT when the machine format cannot
        1816                 :            :  * be found.
        1817                 :            :  */
        1818                 :            : static enum machine_format_code
        1819                 :          0 : typecode_to_mformat_code(char typecode)
        1820                 :            : {
        1821                 :          0 :     const int is_big_endian = PY_BIG_ENDIAN;
        1822                 :            :
        1823                 :            :     size_t intsize;
        1824                 :            :     int is_signed;
        1825                 :            :
        1826   [ #  #  #  #  :          0 :     switch (typecode) {
              #  #  #  #  #
                 #  #  #  #
                          # ]
        1827                 :          0 :     case 'b':
        1828                 :          0 :         return SIGNED_INT8;
        1829                 :          0 :     case 'B':
        1830                 :          0 :         return UNSIGNED_INT8;
        1831                 :            :
        1832                 :          0 :     case 'u':
        1833                 :            :         if (sizeof(Py_UNICODE) == 2) {
        1834                 :            :             return UTF16_LE + is_big_endian;
        1835                 :            :         }
        1836                 :            :         if (sizeof(Py_UNICODE) == 4) {
        1837                 :          0 :             return UTF32_LE + is_big_endian;
        1838                 :            :         }
        1839                 :            :         return UNKNOWN_FORMAT;
        1840                 :            :
        1841                 :          0 :     case 'f':
        1842                 :            :         if (sizeof(float) == 4) {
        1843                 :          0 :             const float y = 16711938.0;
        1844         [ #  # ]:          0 :             if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
        1845                 :          0 :                 return IEEE_754_FLOAT_BE;
        1846         [ #  # ]:          0 :             if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
        1847                 :          0 :                 return IEEE_754_FLOAT_LE;
        1848                 :            :         }
        1849                 :          0 :         return UNKNOWN_FORMAT;
        1850                 :            :
        1851                 :          0 :     case 'd':
        1852                 :            :         if (sizeof(double) == 8) {
        1853                 :          0 :             const double x = 9006104071832581.0;
        1854         [ #  # ]:          0 :             if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
        1855                 :          0 :                 return IEEE_754_DOUBLE_BE;
        1856         [ #  # ]:          0 :             if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
        1857                 :          0 :                 return IEEE_754_DOUBLE_LE;
        1858                 :            :         }
        1859                 :          0 :         return UNKNOWN_FORMAT;
        1860                 :            :
        1861                 :            :     /* Integers */
        1862                 :          0 :     case 'h':
        1863                 :          0 :         intsize = sizeof(short);
        1864                 :          0 :         is_signed = 1;
        1865                 :          0 :         break;
        1866                 :          0 :     case 'H':
        1867                 :          0 :         intsize = sizeof(short);
        1868                 :          0 :         is_signed = 0;
        1869                 :          0 :         break;
        1870                 :          0 :     case 'i':
        1871                 :          0 :         intsize = sizeof(int);
        1872                 :          0 :         is_signed = 1;
        1873                 :          0 :         break;
        1874                 :          0 :     case 'I':
        1875                 :          0 :         intsize = sizeof(int);
        1876                 :          0 :         is_signed = 0;
        1877                 :          0 :         break;
        1878                 :          0 :     case 'l':
        1879                 :          0 :         intsize = sizeof(long);
        1880                 :          0 :         is_signed = 1;
        1881                 :          0 :         break;
        1882                 :          0 :     case 'L':
        1883                 :          0 :         intsize = sizeof(long);
        1884                 :          0 :         is_signed = 0;
        1885                 :          0 :         break;
        1886                 :          0 :     case 'q':
        1887                 :          0 :         intsize = sizeof(long long);
        1888                 :          0 :         is_signed = 1;
        1889                 :          0 :         break;
        1890                 :          0 :     case 'Q':
        1891                 :          0 :         intsize = sizeof(long long);
        1892                 :          0 :         is_signed = 0;
        1893                 :          0 :         break;
        1894                 :          0 :     default:
        1895                 :          0 :         return UNKNOWN_FORMAT;
        1896                 :            :     }
        1897   [ #  #  #  # ]:          0 :     switch (intsize) {
        1898                 :          0 :     case 2:
        1899                 :          0 :         return UNSIGNED_INT16_LE + is_big_endian + (2 * is_signed);
        1900                 :          0 :     case 4:
        1901                 :          0 :         return UNSIGNED_INT32_LE + is_big_endian + (2 * is_signed);
        1902                 :          0 :     case 8:
        1903                 :          0 :         return UNSIGNED_INT64_LE + is_big_endian + (2 * is_signed);
        1904                 :          0 :     default:
        1905                 :          0 :         return UNKNOWN_FORMAT;
        1906                 :            :     }
        1907                 :            : }
        1908                 :            :
        1909                 :            : /* Forward declaration. */
        1910                 :            : static PyObject *array_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
        1911                 :            :
        1912                 :            : /*
        1913                 :            :  * Internal: This function wraps the array constructor--i.e., array_new()--to
        1914                 :            :  * allow the creation of array objects from C code without having to deal
        1915                 :            :  * directly the tuple argument of array_new(). The typecode argument is a
        1916                 :            :  * Unicode character value, like 'i' or 'f' for example, representing an array
        1917                 :            :  * type code. The items argument is a bytes or a list object from which
        1918                 :            :  * contains the initial value of the array.
        1919                 :            :  *
        1920                 :            :  * On success, this functions returns the array object created. Otherwise,
        1921                 :            :  * NULL is returned to indicate a failure.
        1922                 :            :  */
        1923                 :            : static PyObject *
        1924                 :          0 : make_array(PyTypeObject *arraytype, char typecode, PyObject *items)
        1925                 :            : {
        1926                 :            :     PyObject *new_args;
        1927                 :            :     PyObject *array_obj;
        1928                 :            :     PyObject *typecode_obj;
        1929                 :            :
        1930                 :            :     assert(arraytype != NULL);
        1931                 :            :     assert(items != NULL);
        1932                 :            :
        1933                 :          0 :     typecode_obj = PyUnicode_FromOrdinal(typecode);
        1934         [ #  # ]:          0 :     if (typecode_obj == NULL)
        1935                 :          0 :         return NULL;
        1936                 :            :
        1937                 :          0 :     new_args = PyTuple_New(2);
        1938         [ #  # ]:          0 :     if (new_args == NULL) {
        1939                 :          0 :         Py_DECREF(typecode_obj);
        1940                 :          0 :         return NULL;
        1941                 :            :     }
        1942                 :          0 :     PyTuple_SET_ITEM(new_args, 0, typecode_obj);
        1943                 :          0 :     PyTuple_SET_ITEM(new_args, 1, Py_NewRef(items));
        1944                 :            :
        1945                 :          0 :     array_obj = array_new(arraytype, new_args, NULL);
        1946                 :          0 :     Py_DECREF(new_args);
        1947         [ #  # ]:          0 :     if (array_obj == NULL)
        1948                 :          0 :         return NULL;
        1949                 :            :
        1950                 :          0 :     return array_obj;
        1951                 :            : }
        1952                 :            :
        1953                 :            : /*
        1954                 :            :  * This functions is a special constructor used when unpickling an array. It
        1955                 :            :  * provides a portable way to rebuild an array from its memory representation.
        1956                 :            :  */
        1957                 :            : /*[clinic input]
        1958                 :            : array._array_reconstructor
        1959                 :            :
        1960                 :            :     arraytype: object(type="PyTypeObject *")
        1961                 :            :     typecode: int(accept={str})
        1962                 :            :     mformat_code: int(type="enum machine_format_code")
        1963                 :            :     items: object
        1964                 :            :     /
        1965                 :            :
        1966                 :            : Internal. Used for pickling support.
        1967                 :            : [clinic start generated code]*/
        1968                 :            :
        1969                 :            : static PyObject *
        1970                 :          0 : array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype,
        1971                 :            :                                 int typecode,
        1972                 :            :                                 enum machine_format_code mformat_code,
        1973                 :            :                                 PyObject *items)
        1974                 :            : /*[clinic end generated code: output=e05263141ba28365 input=2464dc8f4c7736b5]*/
        1975                 :            : {
        1976                 :          0 :     array_state *state = get_array_state(module);
        1977                 :            :     PyObject *converted_items;
        1978                 :            :     PyObject *result;
        1979                 :            :     const struct arraydescr *descr;
        1980                 :            :
        1981         [ #  # ]:          0 :     if (!PyType_Check(arraytype)) {
        1982                 :          0 :         PyErr_Format(PyExc_TypeError,
        1983                 :            :             "first argument must be a type object, not %.200s",
        1984                 :          0 :             Py_TYPE(arraytype)->tp_name);
        1985                 :          0 :         return NULL;
        1986                 :            :     }
        1987         [ #  # ]:          0 :     if (!PyType_IsSubtype(arraytype, state->ArrayType)) {
        1988                 :          0 :         PyErr_Format(PyExc_TypeError,
        1989                 :            :             "%.200s is not a subtype of %.200s",
        1990                 :          0 :             arraytype->tp_name, state->ArrayType->tp_name);
        1991                 :          0 :         return NULL;
        1992                 :            :     }
        1993         [ #  # ]:          0 :     for (descr = descriptors; descr->typecode != '\0'; descr++) {
        1994         [ #  # ]:          0 :         if ((int)descr->typecode == typecode)
        1995                 :          0 :             break;
        1996                 :            :     }
        1997         [ #  # ]:          0 :     if (descr->typecode == '\0') {
        1998                 :          0 :         PyErr_SetString(PyExc_ValueError,
        1999                 :            :                         "second argument must be a valid type code");
        2000                 :          0 :         return NULL;
        2001                 :            :     }
        2002   [ #  #  #  # ]:          0 :     if (mformat_code < MACHINE_FORMAT_CODE_MIN ||
        2003                 :            :         mformat_code > MACHINE_FORMAT_CODE_MAX) {
        2004                 :          0 :         PyErr_SetString(PyExc_ValueError,
        2005                 :            :             "third argument must be a valid machine format code.");
        2006                 :          0 :         return NULL;
        2007                 :            :     }
        2008         [ #  # ]:          0 :     if (!PyBytes_Check(items)) {
        2009                 :          0 :         PyErr_Format(PyExc_TypeError,
        2010                 :            :             "fourth argument should be bytes, not %.200s",
        2011                 :          0 :             Py_TYPE(items)->tp_name);
        2012                 :          0 :         return NULL;
        2013                 :            :     }
        2014                 :            :
        2015                 :            :     /* Fast path: No decoding has to be done. */
        2016   [ #  #  #  # ]:          0 :     if (mformat_code == typecode_to_mformat_code((char)typecode) ||
        2017                 :            :         mformat_code == UNKNOWN_FORMAT) {
        2018                 :          0 :         return make_array(arraytype, (char)typecode, items);
        2019                 :            :     }
        2020                 :            :
        2021                 :            :     /* Slow path: Decode the byte string according to the given machine
        2022                 :            :      * format code. This occurs when the computer unpickling the array
        2023                 :            :      * object is architecturally different from the one that pickled the
        2024                 :            :      * array.
        2025                 :            :      */
        2026         [ #  # ]:          0 :     if (Py_SIZE(items) % mformat_descriptors[mformat_code].size != 0) {
        2027                 :          0 :         PyErr_SetString(PyExc_ValueError,
        2028                 :            :                         "string length not a multiple of item size");
        2029                 :          0 :         return NULL;
        2030                 :            :     }
        2031   [ #  #  #  #  :          0 :     switch (mformat_code) {
                       #  # ]
        2032                 :          0 :     case IEEE_754_FLOAT_LE:
        2033                 :            :     case IEEE_754_FLOAT_BE: {
        2034                 :            :         Py_ssize_t i;
        2035                 :          0 :         int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0;
        2036                 :          0 :         Py_ssize_t itemcount = Py_SIZE(items) / 4;
        2037                 :          0 :         const char *memstr = PyBytes_AS_STRING(items);
        2038                 :            :
        2039                 :          0 :         converted_items = PyList_New(itemcount);
        2040         [ #  # ]:          0 :         if (converted_items == NULL)
        2041                 :          0 :             return NULL;
        2042         [ #  # ]:          0 :         for (i = 0; i < itemcount; i++) {
        2043                 :          0 :             PyObject *pyfloat = PyFloat_FromDouble(
        2044                 :          0 :                 PyFloat_Unpack4(&memstr[i * 4], le));
        2045         [ #  # ]:          0 :             if (pyfloat == NULL) {
        2046                 :          0 :                 Py_DECREF(converted_items);
        2047                 :          0 :                 return NULL;
        2048                 :            :             }
        2049                 :          0 :             PyList_SET_ITEM(converted_items, i, pyfloat);
        2050                 :            :         }
        2051                 :          0 :         break;
        2052                 :            :     }
        2053                 :          0 :     case IEEE_754_DOUBLE_LE:
        2054                 :            :     case IEEE_754_DOUBLE_BE: {
        2055                 :            :         Py_ssize_t i;
        2056                 :          0 :         int le = (mformat_code == IEEE_754_DOUBLE_LE) ? 1 : 0;
        2057                 :          0 :         Py_ssize_t itemcount = Py_SIZE(items) / 8;
        2058                 :          0 :         const char *memstr = PyBytes_AS_STRING(items);
        2059                 :            :
        2060                 :          0 :         converted_items = PyList_New(itemcount);
        2061         [ #  # ]:          0 :         if (converted_items == NULL)
        2062                 :          0 :             return NULL;
        2063         [ #  # ]:          0 :         for (i = 0; i < itemcount; i++) {
        2064                 :          0 :             PyObject *pyfloat = PyFloat_FromDouble(
        2065                 :          0 :                 PyFloat_Unpack8(&memstr[i * 8], le));
        2066         [ #  # ]:          0 :             if (pyfloat == NULL) {
        2067                 :          0 :                 Py_DECREF(converted_items);
        2068                 :          0 :                 return NULL;
        2069                 :            :             }
        2070                 :          0 :             PyList_SET_ITEM(converted_items, i, pyfloat);
        2071                 :            :         }
        2072                 :          0 :         break;
        2073                 :            :     }
        2074                 :          0 :     case UTF16_LE:
        2075                 :            :     case UTF16_BE: {
        2076         [ #  # ]:          0 :         int byteorder = (mformat_code == UTF16_LE) ? -1 : 1;
        2077                 :          0 :         converted_items = PyUnicode_DecodeUTF16(
        2078                 :          0 :             PyBytes_AS_STRING(items), Py_SIZE(items),
        2079                 :            :             "strict", &byteorder);
        2080         [ #  # ]:          0 :         if (converted_items == NULL)
        2081                 :          0 :             return NULL;
        2082                 :          0 :         break;
        2083                 :            :     }
        2084                 :          0 :     case UTF32_LE:
        2085                 :            :     case UTF32_BE: {
        2086         [ #  # ]:          0 :         int byteorder = (mformat_code == UTF32_LE) ? -1 : 1;
        2087                 :          0 :         converted_items = PyUnicode_DecodeUTF32(
        2088                 :          0 :             PyBytes_AS_STRING(items), Py_SIZE(items),
        2089                 :            :             "strict", &byteorder);
        2090         [ #  # ]:          0 :         if (converted_items == NULL)
        2091                 :          0 :             return NULL;
        2092                 :          0 :         break;
        2093                 :            :     }
        2094                 :            :
        2095                 :          0 :     case UNSIGNED_INT8:
        2096                 :            :     case SIGNED_INT8:
        2097                 :            :     case UNSIGNED_INT16_LE:
        2098                 :            :     case UNSIGNED_INT16_BE:
        2099                 :            :     case SIGNED_INT16_LE:
        2100                 :            :     case SIGNED_INT16_BE:
        2101                 :            :     case UNSIGNED_INT32_LE:
        2102                 :            :     case UNSIGNED_INT32_BE:
        2103                 :            :     case SIGNED_INT32_LE:
        2104                 :            :     case SIGNED_INT32_BE:
        2105                 :            :     case UNSIGNED_INT64_LE:
        2106                 :            :     case UNSIGNED_INT64_BE:
        2107                 :            :     case SIGNED_INT64_LE:
        2108                 :            :     case SIGNED_INT64_BE: {
        2109                 :            :         Py_ssize_t i;
        2110                 :          0 :         const struct mformatdescr mf_descr =
        2111                 :            :             mformat_descriptors[mformat_code];
        2112                 :          0 :         Py_ssize_t itemcount = Py_SIZE(items) / mf_descr.size;
        2113                 :            :         const unsigned char *memstr =
        2114                 :          0 :             (unsigned char *)PyBytes_AS_STRING(items);
        2115                 :            :         const struct arraydescr *descr;
        2116                 :            :
        2117                 :            :         /* If possible, try to pack array's items using a data type
        2118                 :            :          * that fits better. This may result in an array with narrower
        2119                 :            :          * or wider elements.
        2120                 :            :          *
        2121                 :            :          * For example, if a 32-bit machine pickles an L-code array of
        2122                 :            :          * unsigned longs, then the array will be unpickled by 64-bit
        2123                 :            :          * machine as an I-code array of unsigned ints.
        2124                 :            :          *
        2125                 :            :          * XXX: Is it possible to write a unit test for this?
        2126                 :            :          */
        2127         [ #  # ]:          0 :         for (descr = descriptors; descr->typecode != '\0'; descr++) {
        2128         [ #  # ]:          0 :             if (descr->is_integer_type &&
        2129         [ #  # ]:          0 :                 (size_t)descr->itemsize == mf_descr.size &&
        2130         [ #  # ]:          0 :                 descr->is_signed == mf_descr.is_signed)
        2131                 :          0 :                 typecode = descr->typecode;
        2132                 :            :         }
        2133                 :            :
        2134                 :          0 :         converted_items = PyList_New(itemcount);
        2135         [ #  # ]:          0 :         if (converted_items == NULL)
        2136                 :          0 :             return NULL;
        2137         [ #  # ]:          0 :         for (i = 0; i < itemcount; i++) {
        2138                 :            :             PyObject *pylong;
        2139                 :            :
        2140                 :          0 :             pylong = _PyLong_FromByteArray(
        2141                 :          0 :                 &memstr[i * mf_descr.size],
        2142                 :            :                 mf_descr.size,
        2143                 :          0 :                 !mf_descr.is_big_endian,
        2144                 :            :                 mf_descr.is_signed);
        2145         [ #  # ]:          0 :             if (pylong == NULL) {
        2146                 :          0 :                 Py_DECREF(converted_items);
        2147                 :          0 :                 return NULL;
        2148                 :            :             }
        2149                 :          0 :             PyList_SET_ITEM(converted_items, i, pylong);
        2150                 :            :         }
        2151                 :          0 :         break;
        2152                 :            :     }
        2153                 :          0 :     case UNKNOWN_FORMAT:
        2154                 :            :         /* Impossible, but needed to shut up GCC about the unhandled
        2155                 :            :          * enumeration value.
        2156                 :            :          */
        2157                 :            :     default:
        2158                 :          0 :         PyErr_BadArgument();
        2159                 :          0 :         return NULL;
        2160                 :            :     }
        2161                 :            :
        2162                 :          0 :     result = make_array(arraytype, (char)typecode, converted_items);
        2163                 :          0 :     Py_DECREF(converted_items);
        2164                 :          0 :     return result;
        2165                 :            : }
        2166                 :            :
        2167                 :            : /*[clinic input]
        2168                 :            : array.array.__reduce_ex__
        2169                 :            :
        2170                 :            :     cls: defining_class
        2171                 :            :     value: object
        2172                 :            :     /
        2173                 :            :
        2174                 :            : Return state information for pickling.
        2175                 :            : [clinic start generated code]*/
        2176                 :            :
        2177                 :            : static PyObject *
        2178                 :          0 : array_array___reduce_ex___impl(arrayobject *self, PyTypeObject *cls,
        2179                 :            :                                PyObject *value)
        2180                 :            : /*[clinic end generated code: output=4958ee5d79452ad5 input=19968cf0f91d3eea]*/
        2181                 :            : {
        2182                 :            :     PyObject *dict;
        2183                 :            :     PyObject *result;
        2184                 :            :     PyObject *array_str;
        2185                 :          0 :     int typecode = self->ob_descr->typecode;
        2186                 :            :     int mformat_code;
        2187                 :            :     long protocol;
        2188                 :            :
        2189                 :          0 :     array_state *state = get_array_state_by_class(cls);
        2190                 :            :     assert(state != NULL);
        2191                 :            :
        2192         [ #  # ]:          0 :     if (state->array_reconstructor == NULL) {
        2193                 :          0 :         state->array_reconstructor = _PyImport_GetModuleAttrString(
        2194                 :            :                 "array", "_array_reconstructor");
        2195         [ #  # ]:          0 :         if (state->array_reconstructor == NULL) {
        2196                 :          0 :             return NULL;
        2197                 :            :         }
        2198                 :            :     }
        2199                 :            :
        2200         [ #  # ]:          0 :     if (!PyLong_Check(value)) {
        2201                 :          0 :         PyErr_SetString(PyExc_TypeError,
        2202                 :            :                         "__reduce_ex__ argument should be an integer");
        2203                 :          0 :         return NULL;
        2204                 :            :     }
        2205                 :          0 :     protocol = PyLong_AsLong(value);
        2206   [ #  #  #  # ]:          0 :     if (protocol == -1 && PyErr_Occurred())
        2207                 :          0 :         return NULL;
        2208                 :            :
        2209         [ #  # ]:          0 :     if (_PyObject_LookupAttr((PyObject *)self, state->str___dict__, &dict) < 0) {
        2210                 :          0 :         return NULL;
        2211                 :            :     }
        2212         [ #  # ]:          0 :     if (dict == NULL) {
        2213                 :          0 :         dict = Py_NewRef(Py_None);
        2214                 :            :     }
        2215                 :            :
        2216                 :          0 :     mformat_code = typecode_to_mformat_code(typecode);
        2217   [ #  #  #  # ]:          0 :     if (mformat_code == UNKNOWN_FORMAT || protocol < 3) {
        2218                 :            :         /* Convert the array to a list if we got something weird
        2219                 :            :          * (e.g., non-IEEE floats), or we are pickling the array using
        2220                 :            :          * a Python 2.x compatible protocol.
        2221                 :            :          *
        2222                 :            :          * It is necessary to use a list representation for Python 2.x
        2223                 :            :          * compatible pickle protocol, since Python 2's str objects
        2224                 :            :          * are unpickled as unicode by Python 3. Thus it is impossible
        2225                 :            :          * to make arrays unpicklable by Python 3 by using their memory
        2226                 :            :          * representation, unless we resort to ugly hacks such as
        2227                 :            :          * coercing unicode objects to bytes in array_reconstructor.
        2228                 :            :          */
        2229                 :            :         PyObject *list;
        2230                 :          0 :         list = array_array_tolist_impl(self);
        2231         [ #  # ]:          0 :         if (list == NULL) {
        2232                 :          0 :             Py_DECREF(dict);
        2233                 :          0 :             return NULL;
        2234                 :            :         }
        2235                 :          0 :         result = Py_BuildValue(
        2236                 :            :             "O(CO)O", Py_TYPE(self), typecode, list, dict);
        2237                 :          0 :         Py_DECREF(list);
        2238                 :          0 :         Py_DECREF(dict);
        2239                 :          0 :         return result;
        2240                 :            :     }
        2241                 :            :
        2242                 :          0 :     array_str = array_array_tobytes_impl(self);
        2243         [ #  # ]:          0 :     if (array_str == NULL) {
        2244                 :          0 :         Py_DECREF(dict);
        2245                 :          0 :         return NULL;
        2246                 :            :     }
        2247                 :            :
        2248                 :            :     assert(state->array_reconstructor != NULL);
        2249                 :          0 :     result = Py_BuildValue(
        2250                 :            :         "O(OCiN)O", state->array_reconstructor, Py_TYPE(self), typecode,
        2251                 :            :         mformat_code, array_str, dict);
        2252                 :          0 :     Py_DECREF(dict);
        2253                 :          0 :     return result;
        2254                 :            : }
        2255                 :            :
        2256                 :            : static PyObject *
        2257                 :          0 : array_get_typecode(arrayobject *a, void *closure)
        2258                 :            : {
        2259                 :          0 :     char typecode = a->ob_descr->typecode;
        2260                 :          0 :     return PyUnicode_FromOrdinal(typecode);
        2261                 :            : }
        2262                 :            :
        2263                 :            : static PyObject *
        2264                 :          0 : array_get_itemsize(arrayobject *a, void *closure)
        2265                 :            : {
        2266                 :          0 :     return PyLong_FromLong((long)a->ob_descr->itemsize);
        2267                 :            : }
        2268                 :            :
        2269                 :            : static PyGetSetDef array_getsets [] = {
        2270                 :            :     {"typecode", (getter) array_get_typecode, NULL,
        2271                 :            :      "the typecode character used to create the array"},
        2272                 :            :     {"itemsize", (getter) array_get_itemsize, NULL,
        2273                 :            :      "the size, in bytes, of one array item"},
        2274                 :            :     {NULL}
        2275                 :            : };
        2276                 :            :
        2277                 :            : static PyMethodDef array_methods[] = {
        2278                 :            :     ARRAY_ARRAY_APPEND_METHODDEF
        2279                 :            :     ARRAY_ARRAY_BUFFER_INFO_METHODDEF
        2280                 :            :     ARRAY_ARRAY_BYTESWAP_METHODDEF
        2281                 :            :     ARRAY_ARRAY___COPY___METHODDEF
        2282                 :            :     ARRAY_ARRAY_COUNT_METHODDEF
        2283                 :            :     ARRAY_ARRAY___DEEPCOPY___METHODDEF
        2284                 :            :     ARRAY_ARRAY_EXTEND_METHODDEF
        2285                 :            :     ARRAY_ARRAY_FROMFILE_METHODDEF
        2286                 :            :     ARRAY_ARRAY_FROMLIST_METHODDEF
        2287                 :            :     ARRAY_ARRAY_FROMBYTES_METHODDEF
        2288                 :            :     ARRAY_ARRAY_FROMUNICODE_METHODDEF
        2289                 :            :     ARRAY_ARRAY_INDEX_METHODDEF
        2290                 :            :     ARRAY_ARRAY_INSERT_METHODDEF
        2291                 :            :     ARRAY_ARRAY_POP_METHODDEF
        2292                 :            :     ARRAY_ARRAY___REDUCE_EX___METHODDEF
        2293                 :            :     ARRAY_ARRAY_REMOVE_METHODDEF
        2294                 :            :     ARRAY_ARRAY_REVERSE_METHODDEF
        2295                 :            :     ARRAY_ARRAY_TOFILE_METHODDEF
        2296                 :            :     ARRAY_ARRAY_TOLIST_METHODDEF
        2297                 :            :     ARRAY_ARRAY_TOBYTES_METHODDEF
        2298                 :            :     ARRAY_ARRAY_TOUNICODE_METHODDEF
        2299                 :            :     ARRAY_ARRAY___SIZEOF___METHODDEF
        2300                 :            :     {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
        2301                 :            :     {NULL, NULL}  /* sentinel */
        2302                 :            : };
        2303                 :            :
        2304                 :            : static PyObject *
        2305                 :          0 : array_repr(arrayobject *a)
        2306                 :            : {
        2307                 :            :     char typecode;
        2308                 :          0 :     PyObject *s, *v = NULL;
        2309                 :            :     Py_ssize_t len;
        2310                 :            :
        2311                 :          0 :     len = Py_SIZE(a);
        2312                 :          0 :     typecode = a->ob_descr->typecode;
        2313         [ #  # ]:          0 :     if (len == 0) {
        2314                 :          0 :         return PyUnicode_FromFormat("%s('%c')",
        2315                 :            :                                     _PyType_Name(Py_TYPE(a)), (int)typecode);
        2316                 :            :     }
        2317         [ #  # ]:          0 :     if (typecode == 'u') {
        2318                 :          0 :         v = array_array_tounicode_impl(a);
        2319                 :            :     } else {
        2320                 :          0 :         v = array_array_tolist_impl(a);
        2321                 :            :     }
        2322         [ #  # ]:          0 :     if (v == NULL)
        2323                 :          0 :         return NULL;
        2324                 :            :
        2325                 :          0 :     s = PyUnicode_FromFormat("%s('%c', %R)",
        2326                 :            :                              _PyType_Name(Py_TYPE(a)), (int)typecode, v);
        2327                 :          0 :     Py_DECREF(v);
        2328                 :          0 :     return s;
        2329                 :            : }
        2330                 :            :
        2331                 :            : static PyObject*
        2332                 :          0 : array_subscr(arrayobject* self, PyObject* item)
        2333                 :            : {
        2334                 :          0 :     array_state *state = find_array_state_by_type(Py_TYPE(self));
        2335                 :            :
        2336         [ #  # ]:          0 :     if (PyIndex_Check(item)) {
        2337                 :          0 :         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
        2338   [ #  #  #  # ]:          0 :         if (i==-1 && PyErr_Occurred()) {
        2339                 :          0 :             return NULL;
        2340                 :            :         }
        2341         [ #  # ]:          0 :         if (i < 0)
        2342                 :          0 :             i += Py_SIZE(self);
        2343                 :          0 :         return array_item(self, i);
        2344                 :            :     }
        2345         [ #  # ]:          0 :     else if (PySlice_Check(item)) {
        2346                 :            :         Py_ssize_t start, stop, step, slicelength, i;
        2347                 :            :         size_t cur;
        2348                 :            :         PyObject* result;
        2349                 :            :         arrayobject* ar;
        2350                 :          0 :         int itemsize = self->ob_descr->itemsize;
        2351                 :            :
        2352         [ #  # ]:          0 :         if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
        2353                 :          0 :             return NULL;
        2354                 :            :         }
        2355                 :          0 :         slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop,
        2356                 :            :                                             step);
        2357                 :            :
        2358         [ #  # ]:          0 :         if (slicelength <= 0) {
        2359                 :          0 :             return newarrayobject(state->ArrayType, 0, self->ob_descr);
        2360                 :            :         }
        2361         [ #  # ]:          0 :         else if (step == 1) {
        2362                 :          0 :             PyObject *result = newarrayobject(state->ArrayType,
        2363                 :            :                                     slicelength, self->ob_descr);
        2364         [ #  # ]:          0 :             if (result == NULL)
        2365                 :          0 :                 return NULL;
        2366                 :          0 :             memcpy(((arrayobject *)result)->ob_item,
        2367                 :          0 :                    self->ob_item + start * itemsize,
        2368                 :          0 :                    slicelength * itemsize);
        2369                 :          0 :             return result;
        2370                 :            :         }
        2371                 :            :         else {
        2372                 :          0 :             result = newarrayobject(state->ArrayType, slicelength, self->ob_descr);
        2373         [ #  # ]:          0 :             if (!result) return NULL;
        2374                 :            :
        2375                 :          0 :             ar = (arrayobject*)result;
        2376                 :            :
        2377         [ #  # ]:          0 :             for (cur = start, i = 0; i < slicelength;
        2378                 :          0 :                  cur += step, i++) {
        2379                 :          0 :                 memcpy(ar->ob_item + i*itemsize,
        2380                 :          0 :                        self->ob_item + cur*itemsize,
        2381                 :            :                        itemsize);
        2382                 :            :             }
        2383                 :            :
        2384                 :          0 :             return result;
        2385                 :            :         }
        2386                 :            :     }
        2387                 :            :     else {
        2388                 :          0 :         PyErr_SetString(PyExc_TypeError,
        2389                 :            :                         "array indices must be integers");
        2390                 :          0 :         return NULL;
        2391                 :            :     }
        2392                 :            : }
        2393                 :            :
        2394                 :            : static int
        2395                 :          0 : array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
        2396                 :            : {
        2397                 :            :     Py_ssize_t start, stop, step, slicelength, needed;
        2398                 :          0 :     array_state* state = find_array_state_by_type(Py_TYPE(self));
        2399                 :            :     arrayobject* other;
        2400                 :            :     int itemsize;
        2401                 :            :
        2402         [ #  # ]:          0 :     if (PyIndex_Check(item)) {
        2403                 :          0 :         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
        2404                 :            :
        2405   [ #  #  #  # ]:          0 :         if (i == -1 && PyErr_Occurred())
        2406                 :          0 :             return -1;
        2407         [ #  # ]:          0 :         if (i < 0)
        2408                 :          0 :             i += Py_SIZE(self);
        2409   [ #  #  #  # ]:          0 :         if (i < 0 || i >= Py_SIZE(self)) {
        2410                 :          0 :             PyErr_SetString(PyExc_IndexError,
        2411                 :            :                 "array assignment index out of range");
        2412                 :          0 :             return -1;
        2413                 :            :         }
        2414         [ #  # ]:          0 :         if (value == NULL) {
        2415                 :            :             /* Fall through to slice assignment */
        2416                 :          0 :             start = i;
        2417                 :          0 :             stop = i + 1;
        2418                 :          0 :             step = 1;
        2419                 :          0 :             slicelength = 1;
        2420                 :            :         }
        2421                 :            :         else
        2422                 :          0 :             return (*self->ob_descr->setitem)(self, i, value);
        2423                 :            :     }
        2424         [ #  # ]:          0 :     else if (PySlice_Check(item)) {
        2425         [ #  # ]:          0 :         if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
        2426                 :          0 :             return -1;
        2427                 :            :         }
        2428                 :          0 :         slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop,
        2429                 :            :                                             step);
        2430                 :            :     }
        2431                 :            :     else {
        2432                 :          0 :         PyErr_SetString(PyExc_TypeError,
        2433                 :            :                         "array indices must be integers");
        2434                 :          0 :         return -1;
        2435                 :            :     }
        2436         [ #  # ]:          0 :     if (value == NULL) {
        2437                 :          0 :         other = NULL;
        2438                 :          0 :         needed = 0;
        2439                 :            :     }
        2440         [ #  # ]:          0 :     else if (array_Check(value, state)) {
        2441                 :          0 :         other = (arrayobject *)value;
        2442                 :          0 :         needed = Py_SIZE(other);
        2443         [ #  # ]:          0 :         if (self == other) {
        2444                 :            :             /* Special case "self[i:j] = self" -- copy self first */
        2445                 :            :             int ret;
        2446                 :          0 :             value = array_slice(other, 0, needed);
        2447         [ #  # ]:          0 :             if (value == NULL)
        2448                 :          0 :                 return -1;
        2449                 :          0 :             ret = array_ass_subscr(self, item, value);
        2450                 :          0 :             Py_DECREF(value);
        2451                 :          0 :             return ret;
        2452                 :            :         }
        2453         [ #  # ]:          0 :         if (other->ob_descr != self->ob_descr) {
        2454                 :          0 :             PyErr_BadArgument();
        2455                 :          0 :             return -1;
        2456                 :            :         }
        2457                 :            :     }
        2458                 :            :     else {
        2459                 :          0 :         PyErr_Format(PyExc_TypeError,
        2460                 :            :          "can only assign array (not \"%.200s\") to array slice",
        2461                 :          0 :                          Py_TYPE(value)->tp_name);
        2462                 :          0 :         return -1;
        2463                 :            :     }
        2464                 :          0 :     itemsize = self->ob_descr->itemsize;
        2465                 :            :     /* for 'a[2:1] = ...', the insertion point is 'start', not 'stop' */
        2466   [ #  #  #  # ]:          0 :     if ((step > 0 && stop < start) ||
        2467   [ #  #  #  # ]:          0 :         (step < 0 && stop > start))
        2468                 :          0 :         stop = start;
        2469                 :            :
        2470                 :            :     /* Issue #4509: If the array has exported buffers and the slice
        2471                 :            :        assignment would change the size of the array, fail early to make
        2472                 :            :        sure we don't modify it. */
        2473   [ #  #  #  #  :          0 :     if ((needed == 0 || slicelength != needed) && self->ob_exports > 0) {
                       #  # ]
        2474                 :          0 :         PyErr_SetString(PyExc_BufferError,
        2475                 :            :             "cannot resize an array that is exporting buffers");
        2476                 :          0 :         return -1;
        2477                 :            :     }
        2478                 :            :
        2479         [ #  # ]:          0 :     if (step == 1) {
        2480         [ #  # ]:          0 :         if (slicelength > needed) {
        2481                 :          0 :             memmove(self->ob_item + (start + needed) * itemsize,
        2482                 :          0 :                 self->ob_item + stop * itemsize,
        2483                 :          0 :                 (Py_SIZE(self) - stop) * itemsize);
        2484         [ #  # ]:          0 :             if (array_resize(self, Py_SIZE(self) +
        2485                 :            :                 needed - slicelength) < 0)
        2486                 :          0 :                 return -1;
        2487                 :            :         }
        2488         [ #  # ]:          0 :         else if (slicelength < needed) {
        2489         [ #  # ]:          0 :             if (array_resize(self, Py_SIZE(self) +
        2490                 :            :                 needed - slicelength) < 0)
        2491                 :          0 :                 return -1;
        2492                 :          0 :             memmove(self->ob_item + (start + needed) * itemsize,
        2493                 :          0 :                 self->ob_item + stop * itemsize,
        2494                 :          0 :                 (Py_SIZE(self) - start - needed) * itemsize);
        2495                 :            :         }
        2496         [ #  # ]:          0 :         if (needed > 0)
        2497                 :          0 :             memcpy(self->ob_item + start * itemsize,
        2498                 :          0 :                    other->ob_item, needed * itemsize);
        2499                 :          0 :         return 0;
        2500                 :            :     }
        2501         [ #  # ]:          0 :     else if (needed == 0) {
        2502                 :            :         /* Delete slice */
        2503                 :            :         size_t cur;
        2504                 :            :         Py_ssize_t i;
        2505                 :            :
        2506         [ #  # ]:          0 :         if (step < 0) {
        2507                 :          0 :             stop = start + 1;
        2508                 :          0 :             start = stop + step * (slicelength - 1) - 1;
        2509                 :          0 :             step = -step;
        2510                 :            :         }
        2511         [ #  # ]:          0 :         for (cur = start, i = 0; i < slicelength;
        2512                 :          0 :              cur += step, i++) {
        2513                 :          0 :             Py_ssize_t lim = step - 1;
        2514                 :            :
        2515         [ #  # ]:          0 :             if (cur + step >= (size_t)Py_SIZE(self))
        2516                 :          0 :                 lim = Py_SIZE(self) - cur - 1;
        2517                 :          0 :             memmove(self->ob_item + (cur - i) * itemsize,
        2518                 :          0 :                 self->ob_item + (cur + 1) * itemsize,
        2519                 :          0 :                 lim * itemsize);
        2520                 :            :         }
        2521                 :          0 :         cur = start + (size_t)slicelength * step;
        2522         [ #  # ]:          0 :         if (cur < (size_t)Py_SIZE(self)) {
        2523                 :          0 :             memmove(self->ob_item + (cur-slicelength) * itemsize,
        2524                 :          0 :                 self->ob_item + cur * itemsize,
        2525                 :          0 :                 (Py_SIZE(self) - cur) * itemsize);
        2526                 :            :         }
        2527         [ #  # ]:          0 :         if (array_resize(self, Py_SIZE(self) - slicelength) < 0)
        2528                 :          0 :             return -1;
        2529                 :          0 :         return 0;
        2530                 :            :     }
        2531                 :            :     else {
        2532                 :            :         size_t cur;
        2533                 :            :         Py_ssize_t i;
        2534                 :            :
        2535         [ #  # ]:          0 :         if (needed != slicelength) {
        2536                 :          0 :             PyErr_Format(PyExc_ValueError,
        2537                 :            :                 "attempt to assign array of size %zd "
        2538                 :            :                 "to extended slice of size %zd",
        2539                 :            :                 needed, slicelength);
        2540                 :          0 :             return -1;
        2541                 :            :         }
        2542         [ #  # ]:          0 :         for (cur = start, i = 0; i < slicelength;
        2543                 :          0 :              cur += step, i++) {
        2544                 :          0 :             memcpy(self->ob_item + cur * itemsize,
        2545                 :          0 :                    other->ob_item + i * itemsize,
        2546                 :            :                    itemsize);
        2547                 :            :         }
        2548                 :          0 :         return 0;
        2549                 :            :     }
        2550                 :            : }
        2551                 :            :
        2552                 :            : static const void *emptybuf = "";
        2553                 :            :
        2554                 :            :
        2555                 :            : static int
        2556                 :          0 : array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags)
        2557                 :            : {
        2558         [ #  # ]:          0 :     if (view == NULL) {
        2559                 :          0 :         PyErr_SetString(PyExc_BufferError,
        2560                 :            :             "array_buffer_getbuf: view==NULL argument is obsolete");
        2561                 :          0 :         return -1;
        2562                 :            :     }
        2563                 :            :
        2564                 :          0 :     view->buf = (void *)self->ob_item;
        2565                 :          0 :     view->obj = Py_NewRef(self);
        2566         [ #  # ]:          0 :     if (view->buf == NULL)
        2567                 :          0 :         view->buf = (void *)emptybuf;
        2568                 :          0 :     view->len = Py_SIZE(self) * self->ob_descr->itemsize;
        2569                 :          0 :     view->readonly = 0;
        2570                 :          0 :     view->ndim = 1;
        2571                 :          0 :     view->itemsize = self->ob_descr->itemsize;
        2572                 :          0 :     view->suboffsets = NULL;
        2573                 :          0 :     view->shape = NULL;
        2574         [ #  # ]:          0 :     if ((flags & PyBUF_ND)==PyBUF_ND) {
        2575                 :          0 :         view->shape = &((PyVarObject*)self)->ob_size;
        2576                 :            :     }
        2577                 :          0 :     view->strides = NULL;
        2578         [ #  # ]:          0 :     if ((flags & PyBUF_STRIDES)==PyBUF_STRIDES)
        2579                 :          0 :         view->strides = &(view->itemsize);
        2580                 :          0 :     view->format = NULL;
        2581                 :          0 :     view->internal = NULL;
        2582         [ #  # ]:          0 :     if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
        2583                 :          0 :         view->format = (char *)self->ob_descr->formats;
        2584                 :            : #ifdef Py_UNICODE_WIDE
        2585         [ #  # ]:          0 :         if (self->ob_descr->typecode == 'u') {
        2586                 :          0 :             view->format = "w";
        2587                 :            :         }
        2588                 :            : #endif
        2589                 :            :     }
        2590                 :            :
        2591                 :          0 :     self->ob_exports++;
        2592                 :          0 :     return 0;
        2593                 :            : }
        2594                 :            :
        2595                 :            : static void
        2596                 :          0 : array_buffer_relbuf(arrayobject *self, Py_buffer *view)
        2597                 :            : {
        2598                 :          0 :     self->ob_exports--;
        2599                 :          0 : }
        2600                 :            :
        2601                 :            : static PyObject *
        2602                 :          0 : array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        2603                 :            : {
        2604                 :          0 :     array_state *state = find_array_state_by_type(type);
        2605                 :            :     int c;
        2606                 :          0 :     PyObject *initial = NULL, *it = NULL;
        2607                 :            :     const struct arraydescr *descr;
        2608                 :            :
        2609         [ #  # ]:          0 :     if ((type == state->ArrayType ||
        2610   [ #  #  #  # ]:          0 :          type->tp_init == state->ArrayType->tp_init) &&
        2611         [ #  # ]:          0 :         !_PyArg_NoKeywords("array.array", kwds))
        2612                 :          0 :         return NULL;
        2613                 :            :
        2614         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial))
        2615                 :          0 :         return NULL;
        2616                 :            :
        2617         [ #  # ]:          0 :     if (PySys_Audit("array.__new__", "CO",
        2618         [ #  # ]:          0 :                     c, initial ? initial : Py_None) < 0) {
        2619                 :          0 :         return NULL;
        2620                 :            :     }
        2621                 :            :
        2622   [ #  #  #  # ]:          0 :     if (initial && c != 'u') {
        2623         [ #  # ]:          0 :         if (PyUnicode_Check(initial)) {
        2624                 :          0 :             PyErr_Format(PyExc_TypeError, "cannot use a str to initialize "
        2625                 :            :                          "an array with typecode '%c'", c);
        2626                 :          0 :             return NULL;
        2627                 :            :         }
        2628         [ #  # ]:          0 :         else if (array_Check(initial, state) &&
        2629         [ #  # ]:          0 :                  ((arrayobject*)initial)->ob_descr->typecode == 'u') {
        2630                 :          0 :             PyErr_Format(PyExc_TypeError, "cannot use a unicode array to "
        2631                 :            :                          "initialize an array with typecode '%c'", c);
        2632                 :          0 :             return NULL;
        2633                 :            :         }
        2634                 :            :     }
        2635                 :            :
        2636   [ #  #  #  #  :          0 :     if (!(initial == NULL || PyList_Check(initial)
                       #  # ]
        2637         [ #  # ]:          0 :           || PyByteArray_Check(initial)
        2638         [ #  # ]:          0 :           || PyBytes_Check(initial)
        2639         [ #  # ]:          0 :           || PyTuple_Check(initial)
        2640   [ #  #  #  # ]:          0 :           || ((c=='u') && PyUnicode_Check(initial))
        2641                 :          0 :           || (array_Check(initial, state)
        2642         [ #  # ]:          0 :               && c == ((arrayobject*)initial)->ob_descr->typecode))) {
        2643                 :          0 :         it = PyObject_GetIter(initial);
        2644         [ #  # ]:          0 :         if (it == NULL)
        2645                 :          0 :             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                 :          0 :         initial = NULL;
        2652                 :            :     }
        2653         [ #  # ]:          0 :     for (descr = descriptors; descr->typecode != '\0'; descr++) {
        2654         [ #  # ]:          0 :         if (descr->typecode == c) {
        2655                 :            :             PyObject *a;
        2656                 :            :             Py_ssize_t len;
        2657                 :            :
        2658         [ #  # ]:          0 :             if (initial == NULL)
        2659                 :          0 :                 len = 0;
        2660         [ #  # ]:          0 :             else if (PyList_Check(initial))
        2661                 :          0 :                 len = PyList_GET_SIZE(initial);
        2662   [ #  #  #  # ]:          0 :             else if (PyTuple_Check(initial) || array_Check(initial, state))
        2663                 :          0 :                 len = Py_SIZE(initial);
        2664                 :            :             else
        2665                 :          0 :                 len = 0;
        2666                 :            :
        2667                 :          0 :             a = newarrayobject(type, len, descr);
        2668         [ #  # ]:          0 :             if (a == NULL)
        2669                 :          0 :                 return NULL;
        2670                 :            :
        2671   [ #  #  #  # ]:          0 :             if (len > 0 && !array_Check(initial, state)) {
        2672                 :            :                 Py_ssize_t i;
        2673         [ #  # ]:          0 :                 for (i = 0; i < len; i++) {
        2674                 :            :                     PyObject *v =
        2675                 :          0 :                         PySequence_GetItem(initial, i);
        2676         [ #  # ]:          0 :                     if (v == NULL) {
        2677                 :          0 :                         Py_DECREF(a);
        2678                 :          0 :                         return NULL;
        2679                 :            :                     }
        2680         [ #  # ]:          0 :                     if (setarrayitem(a, i, v) != 0) {
        2681                 :          0 :                         Py_DECREF(v);
        2682                 :          0 :                         Py_DECREF(a);
        2683                 :          0 :                         return NULL;
        2684                 :            :                     }
        2685                 :          0 :                     Py_DECREF(v);
        2686                 :            :                 }
        2687                 :            :             }
        2688   [ #  #  #  #  :          0 :             else if (initial != NULL && (PyByteArray_Check(initial) ||
                       #  # ]
        2689                 :          0 :                                PyBytes_Check(initial))) {
        2690                 :            :                 PyObject *v;
        2691                 :          0 :                 v = array_array_frombytes((arrayobject *)a,
        2692                 :            :                                           initial);
        2693         [ #  # ]:          0 :                 if (v == NULL) {
        2694                 :          0 :                     Py_DECREF(a);
        2695                 :          0 :                     return NULL;
        2696                 :            :                 }
        2697                 :          0 :                 Py_DECREF(v);
        2698                 :            :             }
        2699   [ #  #  #  # ]:          0 :             else if (initial != NULL && PyUnicode_Check(initial))  {
        2700                 :            :                 Py_ssize_t n;
        2701                 :          0 :                 wchar_t *ustr = PyUnicode_AsWideCharString(initial, &n);
        2702         [ #  # ]:          0 :                 if (ustr == NULL) {
        2703                 :          0 :                     Py_DECREF(a);
        2704                 :          0 :                     return NULL;
        2705                 :            :                 }
        2706                 :            :
        2707         [ #  # ]:          0 :                 if (n > 0) {
        2708                 :          0 :                     arrayobject *self = (arrayobject *)a;
        2709                 :            :                     // self->ob_item may be NULL but it is safe.
        2710                 :          0 :                     PyMem_Free(self->ob_item);
        2711                 :          0 :                     self->ob_item = (char *)ustr;
        2712                 :          0 :                     Py_SET_SIZE(self, n);
        2713                 :          0 :                     self->allocated = n;
        2714                 :            :                 }
        2715                 :            :             }
        2716   [ #  #  #  #  :          0 :             else if (initial != NULL && array_Check(initial, state) && len > 0) {
                       #  # ]
        2717                 :          0 :                 arrayobject *self = (arrayobject *)a;
        2718                 :          0 :                 arrayobject *other = (arrayobject *)initial;
        2719                 :          0 :                 memcpy(self->ob_item, other->ob_item, len * other->ob_descr->itemsize);
        2720                 :            :             }
        2721         [ #  # ]:          0 :             if (it != NULL) {
        2722         [ #  # ]:          0 :                 if (array_iter_extend((arrayobject *)a, it) == -1) {
        2723                 :          0 :                     Py_DECREF(it);
        2724                 :          0 :                     Py_DECREF(a);
        2725                 :          0 :                     return NULL;
        2726                 :            :                 }
        2727                 :          0 :                 Py_DECREF(it);
        2728                 :            :             }
        2729                 :          0 :             return a;
        2730                 :            :         }
        2731                 :            :     }
        2732                 :          0 :     PyErr_SetString(PyExc_ValueError,
        2733                 :            :         "bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)");
        2734                 :          0 :     return NULL;
        2735                 :            : }
        2736                 :            :
        2737                 :            :
        2738                 :            : PyDoc_STRVAR(module_doc,
        2739                 :            : "This module defines an object type which can efficiently represent\n\
        2740                 :            : an array of basic values: characters, integers, floating point\n\
        2741                 :            : numbers.  Arrays are sequence types and behave very much like lists,\n\
        2742                 :            : except that the type of objects stored in them is constrained.\n");
        2743                 :            :
        2744                 :            : PyDoc_STRVAR(arraytype_doc,
        2745                 :            : "array(typecode [, initializer]) -> array\n\
        2746                 :            : \n\
        2747                 :            : Return a new array whose items are restricted by typecode, and\n\
        2748                 :            : initialized from the optional initializer value, which must be a list,\n\
        2749                 :            : string or iterable over elements of the appropriate type.\n\
        2750                 :            : \n\
        2751                 :            : Arrays represent basic values and behave very much like lists, except\n\
        2752                 :            : the type of objects stored in them is constrained. The type is specified\n\
        2753                 :            : at object creation time by using a type code, which is a single character.\n\
        2754                 :            : The following type codes are defined:\n\
        2755                 :            : \n\
        2756                 :            :     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\
        2770                 :            : \n\
        2771                 :            : NOTE: The 'u' typecode corresponds to Python's unicode character. On\n\
        2772                 :            : narrow builds this is 2-bytes on wide builds this is 4-bytes.\n\
        2773                 :            : \n\
        2774                 :            : NOTE: The 'q' and 'Q' type codes are only available if the platform\n\
        2775                 :            : C compiler used to build Python supports 'long long', or, on Windows,\n\
        2776                 :            : '__int64'.\n\
        2777                 :            : \n\
        2778                 :            : Methods:\n\
        2779                 :            : \n\
        2780                 :            : append() -- append a new item to the end of the array\n\
        2781                 :            : buffer_info() -- return information giving the current memory info\n\
        2782                 :            : byteswap() -- byteswap all the items of the array\n\
        2783                 :            : count() -- return number of occurrences of an object\n\
        2784                 :            : extend() -- extend array by appending multiple elements from an iterable\n\
        2785                 :            : fromfile() -- read items from a file object\n\
        2786                 :            : fromlist() -- append items from the list\n\
        2787                 :            : frombytes() -- append items from the string\n\
        2788                 :            : index() -- return index of first occurrence of an object\n\
        2789                 :            : insert() -- insert a new item into the array at a provided position\n\
        2790                 :            : pop() -- remove and return item (default last)\n\
        2791                 :            : remove() -- remove first occurrence of an object\n\
        2792                 :            : reverse() -- reverse the order of the items in the array\n\
        2793                 :            : tofile() -- write all items to a file object\n\
        2794                 :            : tolist() -- return the array converted to an ordinary list\n\
        2795                 :            : tobytes() -- return the array converted to a string\n\
        2796                 :            : \n\
        2797                 :            : Attributes:\n\
        2798                 :            : \n\
        2799                 :            : typecode -- the typecode character used to create the array\n\
        2800                 :            : itemsize -- the length in bytes of one array item\n\
        2801                 :            : ");
        2802                 :            :
        2803                 :            : static PyObject *array_iter(arrayobject *ao);
        2804                 :            :
        2805                 :            : static struct PyMemberDef array_members[] = {
        2806                 :            :     {"__weaklistoffset__", T_PYSSIZET, offsetof(arrayobject, weakreflist), READONLY},
        2807                 :            :     {NULL},
        2808                 :            : };
        2809                 :            :
        2810                 :            : static 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_traverse, array_tp_traverse},
        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                 :            :
        2846                 :            : static PyType_Spec array_spec = {
        2847                 :            :     .name = "array.array",
        2848                 :            :     .basicsize = sizeof(arrayobject),
        2849                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
        2850                 :            :               Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC |
        2851                 :            :               Py_TPFLAGS_SEQUENCE),
        2852                 :            :     .slots = array_slots,
        2853                 :            : };
        2854                 :            :
        2855                 :            : /*********************** Array Iterator **************************/
        2856                 :            :
        2857                 :            : /*[clinic input]
        2858                 :            : class array.arrayiterator "arrayiterobject *" "find_array_state_by_type(type)->ArrayIterType"
        2859                 :            : [clinic start generated code]*/
        2860                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=fb46d5ef98dd95ff]*/
        2861                 :            :
        2862                 :            : static PyObject *
        2863                 :          0 : array_iter(arrayobject *ao)
        2864                 :            : {
        2865                 :          0 :     array_state *state = find_array_state_by_type(Py_TYPE(ao));
        2866                 :            :     arrayiterobject *it;
        2867                 :            :
        2868         [ #  # ]:          0 :     if (!array_Check(ao, state)) {
        2869                 :          0 :         PyErr_BadInternalCall();
        2870                 :          0 :         return NULL;
        2871                 :            :     }
        2872                 :            :
        2873                 :          0 :     it = PyObject_GC_New(arrayiterobject, state->ArrayIterType);
        2874         [ #  # ]:          0 :     if (it == NULL)
        2875                 :          0 :         return NULL;
        2876                 :            :
        2877                 :          0 :     it->ao = (arrayobject*)Py_NewRef(ao);
        2878                 :          0 :     it->index = 0;
        2879                 :          0 :     it->getitem = ao->ob_descr->getitem;
        2880                 :          0 :     PyObject_GC_Track(it);
        2881                 :          0 :     return (PyObject *)it;
        2882                 :            : }
        2883                 :            :
        2884                 :            : static PyObject *
        2885                 :          0 : arrayiter_next(arrayiterobject *it)
        2886                 :            : {
        2887                 :            :     arrayobject *ao;
        2888                 :            :
        2889                 :            :     assert(it != NULL);
        2890                 :            : #ifndef NDEBUG
        2891                 :            :     array_state *state = find_array_state_by_type(Py_TYPE(it));
        2892                 :            :     assert(PyObject_TypeCheck(it, state->ArrayIterType));
        2893                 :            : #endif
        2894                 :          0 :     ao = it->ao;
        2895         [ #  # ]:          0 :     if (ao == NULL) {
        2896                 :          0 :         return NULL;
        2897                 :            :     }
        2898                 :            : #ifndef NDEBUG
        2899                 :            :     assert(array_Check(ao, state));
        2900                 :            : #endif
        2901         [ #  # ]:          0 :     if (it->index < Py_SIZE(ao)) {
        2902                 :          0 :         return (*it->getitem)(ao, it->index++);
        2903                 :            :     }
        2904                 :          0 :     it->ao = NULL;
        2905                 :          0 :     Py_DECREF(ao);
        2906                 :          0 :     return NULL;
        2907                 :            : }
        2908                 :            :
        2909                 :            : static void
        2910                 :          0 : arrayiter_dealloc(arrayiterobject *it)
        2911                 :            : {
        2912                 :          0 :     PyTypeObject *tp = Py_TYPE(it);
        2913                 :            :
        2914                 :          0 :     PyObject_GC_UnTrack(it);
        2915                 :          0 :     Py_XDECREF(it->ao);
        2916                 :          0 :     PyObject_GC_Del(it);
        2917                 :          0 :     Py_DECREF(tp);
        2918                 :          0 : }
        2919                 :            :
        2920                 :            : static int
        2921                 :          0 : arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
        2922                 :            : {
        2923   [ #  #  #  # ]:          0 :     Py_VISIT(Py_TYPE(it));
        2924   [ #  #  #  # ]:          0 :     Py_VISIT(it->ao);
        2925                 :          0 :     return 0;
        2926                 :            : }
        2927                 :            :
        2928                 :            : /*[clinic input]
        2929                 :            : array.arrayiterator.__reduce__
        2930                 :            :
        2931                 :            :     cls: defining_class
        2932                 :            :     /
        2933                 :            :
        2934                 :            : Return state information for pickling.
        2935                 :            : [clinic start generated code]*/
        2936                 :            :
        2937                 :            : static PyObject *
        2938                 :          0 : array_arrayiterator___reduce___impl(arrayiterobject *self, PyTypeObject *cls)
        2939                 :            : /*[clinic end generated code: output=4b032417a2c8f5e6 input=ac64e65a87ad452e]*/
        2940                 :            : {
        2941                 :            :
        2942                 :          0 :     array_state *state = get_array_state_by_class(cls);
        2943                 :            :     assert(state != NULL);
        2944                 :          0 :     PyObject *func = _PyEval_GetBuiltin(state->str_iter);
        2945         [ #  # ]:          0 :     if (self->ao == NULL) {
        2946                 :          0 :         return Py_BuildValue("N(())", func);
        2947                 :            :     }
        2948                 :          0 :     return Py_BuildValue("N(O)n", func, self->ao, self->index);
        2949                 :            : }
        2950                 :            :
        2951                 :            : /*[clinic input]
        2952                 :            : array.arrayiterator.__setstate__
        2953                 :            :
        2954                 :            :     state: object
        2955                 :            :     /
        2956                 :            :
        2957                 :            : Set state information for unpickling.
        2958                 :            : [clinic start generated code]*/
        2959                 :            :
        2960                 :            : static PyObject *
        2961                 :          0 : array_arrayiterator___setstate__(arrayiterobject *self, PyObject *state)
        2962                 :            : /*[clinic end generated code: output=397da9904e443cbe input=f47d5ceda19e787b]*/
        2963                 :            : {
        2964                 :          0 :     Py_ssize_t index = PyLong_AsSsize_t(state);
        2965   [ #  #  #  # ]:          0 :     if (index == -1 && PyErr_Occurred())
        2966                 :          0 :         return NULL;
        2967         [ #  # ]:          0 :     if (index < 0)
        2968                 :          0 :         index = 0;
        2969         [ #  # ]:          0 :     else if (index > Py_SIZE(self->ao))
        2970                 :          0 :         index = Py_SIZE(self->ao); /* iterator exhausted */
        2971                 :          0 :     self->index = index;
        2972                 :          0 :     Py_RETURN_NONE;
        2973                 :            : }
        2974                 :            :
        2975                 :            : static PyMethodDef arrayiter_methods[] = {
        2976                 :            :     ARRAY_ARRAYITERATOR___REDUCE___METHODDEF
        2977                 :            :     ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF
        2978                 :            :     {NULL, NULL} /* sentinel */
        2979                 :            : };
        2980                 :            :
        2981                 :            : static PyType_Slot arrayiter_slots[] = {
        2982                 :            :     {Py_tp_dealloc, arrayiter_dealloc},
        2983                 :            :     {Py_tp_getattro, PyObject_GenericGetAttr},
        2984                 :            :     {Py_tp_traverse, arrayiter_traverse},
        2985                 :            :     {Py_tp_iter, PyObject_SelfIter},
        2986                 :            :     {Py_tp_iternext, arrayiter_next},
        2987                 :            :     {Py_tp_methods, arrayiter_methods},
        2988                 :            :     {0, NULL},
        2989                 :            : };
        2990                 :            :
        2991                 :            : static PyType_Spec arrayiter_spec = {
        2992                 :            :     .name = "array.arrayiterator",
        2993                 :            :     .basicsize = sizeof(arrayiterobject),
        2994                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        2995                 :            :               Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE),
        2996                 :            :     .slots = arrayiter_slots,
        2997                 :            : };
        2998                 :            :
        2999                 :            :
        3000                 :            : /*********************** Install Module **************************/
        3001                 :            :
        3002                 :            : static int
        3003                 :         16 : array_traverse(PyObject *module, visitproc visit, void *arg)
        3004                 :            : {
        3005                 :         16 :     array_state *state = get_array_state(module);
        3006   [ +  -  -  + ]:         16 :     Py_VISIT(state->ArrayType);
        3007   [ +  -  -  + ]:         16 :     Py_VISIT(state->ArrayIterType);
        3008   [ -  +  -  - ]:         16 :     Py_VISIT(state->array_reconstructor);
        3009                 :         16 :     return 0;
        3010                 :            : }
        3011                 :            :
        3012                 :            : static int
        3013                 :          4 : array_clear(PyObject *module)
        3014                 :            : {
        3015                 :          4 :     array_state *state = get_array_state(module);
        3016         [ +  + ]:          4 :     Py_CLEAR(state->ArrayType);
        3017         [ +  + ]:          4 :     Py_CLEAR(state->ArrayIterType);
        3018         [ -  + ]:          4 :     Py_CLEAR(state->array_reconstructor);
        3019         [ +  + ]:          4 :     Py_CLEAR(state->str_read);
        3020         [ +  + ]:          4 :     Py_CLEAR(state->str_write);
        3021         [ +  + ]:          4 :     Py_CLEAR(state->str___dict__);
        3022         [ +  + ]:          4 :     Py_CLEAR(state->str_iter);
        3023                 :          4 :     return 0;
        3024                 :            : }
        3025                 :            :
        3026                 :            : static void
        3027                 :          2 : array_free(void *module)
        3028                 :            : {
        3029                 :          2 :     array_clear((PyObject *)module);
        3030                 :          2 : }
        3031                 :            :
        3032                 :            : /* No functions in array module. */
        3033                 :            : static PyMethodDef a_methods[] = {
        3034                 :            :     ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF
        3035                 :            :     {NULL, NULL, 0, NULL}        /* Sentinel */
        3036                 :            : };
        3037                 :            :
        3038                 :            : #define CREATE_TYPE(module, type, spec)                                  \
        3039                 :            : do {                                                                     \
        3040                 :            :     type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \
        3041                 :            :     if (type == NULL) {                                                  \
        3042                 :            :         return -1;                                                       \
        3043                 :            :     }                                                                    \
        3044                 :            : } while (0)
        3045                 :            :
        3046                 :            : #define ADD_INTERNED(state, string)                      \
        3047                 :            : do {                                                     \
        3048                 :            :     PyObject *tmp = PyUnicode_InternFromString(#string); \
        3049                 :            :     if (tmp == NULL) {                                   \
        3050                 :            :         return -1;                                       \
        3051                 :            :     }                                                    \
        3052                 :            :     state->str_ ## string = tmp;                         \
        3053                 :            : } while (0)
        3054                 :            :
        3055                 :            : static int
        3056                 :          2 : array_modexec(PyObject *m)
        3057                 :            : {
        3058                 :          2 :     array_state *state = get_array_state(m);
        3059                 :            :     char buffer[Py_ARRAY_LENGTH(descriptors)], *p;
        3060                 :            :     PyObject *typecodes;
        3061                 :            :     const struct arraydescr *descr;
        3062                 :            :
        3063                 :          2 :     state->array_reconstructor = NULL;
        3064                 :            :     /* Add interned strings */
        3065         [ -  + ]:          2 :     ADD_INTERNED(state, read);
        3066         [ -  + ]:          2 :     ADD_INTERNED(state, write);
        3067         [ -  + ]:          2 :     ADD_INTERNED(state, __dict__);
        3068         [ -  + ]:          2 :     ADD_INTERNED(state, iter);
        3069                 :            :
        3070         [ -  + ]:          2 :     CREATE_TYPE(m, state->ArrayType, &array_spec);
        3071         [ -  + ]:          2 :     CREATE_TYPE(m, state->ArrayIterType, &arrayiter_spec);
        3072                 :          2 :     Py_SET_TYPE(state->ArrayIterType, &PyType_Type);
        3073                 :            :
        3074         [ -  + ]:          2 :     if (PyModule_AddObject(m, "ArrayType",
        3075                 :          2 :                            Py_NewRef((PyObject *)state->ArrayType)) < 0) {
        3076                 :          0 :         Py_DECREF((PyObject *)state->ArrayType);
        3077                 :          0 :         return -1;
        3078                 :            :     }
        3079                 :            :
        3080                 :          2 :     PyObject *mutablesequence = _PyImport_GetModuleAttrString(
        3081                 :            :             "collections.abc", "MutableSequence");
        3082         [ -  + ]:          2 :     if (!mutablesequence) {
        3083                 :          0 :         Py_DECREF((PyObject *)state->ArrayType);
        3084                 :          0 :         return -1;
        3085                 :            :     }
        3086                 :          2 :     PyObject *res = PyObject_CallMethod(mutablesequence, "register", "O",
        3087                 :          2 :                                         (PyObject *)state->ArrayType);
        3088                 :          2 :     Py_DECREF(mutablesequence);
        3089         [ -  + ]:          2 :     if (!res) {
        3090                 :          0 :         Py_DECREF((PyObject *)state->ArrayType);
        3091                 :          0 :         return -1;
        3092                 :            :     }
        3093                 :          2 :     Py_DECREF(res);
        3094                 :            :
        3095         [ -  + ]:          2 :     if (PyModule_AddType(m, state->ArrayType) < 0) {
        3096                 :          0 :         return -1;
        3097                 :            :     }
        3098                 :            :
        3099                 :          2 :     p = buffer;
        3100         [ +  + ]:         28 :     for (descr = descriptors; descr->typecode != '\0'; descr++) {
        3101                 :         26 :         *p++ = (char)descr->typecode;
        3102                 :            :     }
        3103                 :          2 :     typecodes = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
        3104         [ -  + ]:          2 :     if (PyModule_AddObject(m, "typecodes", typecodes) < 0) {
        3105                 :          0 :         Py_XDECREF(typecodes);
        3106                 :          0 :         return -1;
        3107                 :            :     }
        3108                 :            :
        3109                 :          2 :     return 0;
        3110                 :            : }
        3111                 :            :
        3112                 :            : static PyModuleDef_Slot arrayslots[] = {
        3113                 :            :     {Py_mod_exec, array_modexec},
        3114                 :            :     {0, NULL}
        3115                 :            : };
        3116                 :            :
        3117                 :            :
        3118                 :            : static struct PyModuleDef arraymodule = {
        3119                 :            :     .m_base = PyModuleDef_HEAD_INIT,
        3120                 :            :     .m_name = "array",
        3121                 :            :     .m_size = sizeof(array_state),
        3122                 :            :     .m_doc = module_doc,
        3123                 :            :     .m_methods = a_methods,
        3124                 :            :     .m_slots = arrayslots,
        3125                 :            :     .m_traverse = array_traverse,
        3126                 :            :     .m_clear = array_clear,
        3127                 :            :     .m_free = array_free,
        3128                 :            : };
        3129                 :            :
        3130                 :            :
        3131                 :            : PyMODINIT_FUNC
        3132                 :          2 : PyInit_array(void)
        3133                 :            : {
        3134                 :          2 :     return PyModuleDef_Init(&arraymodule);
        3135                 :            : }

Generated by: LCOV version 1.14