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