LCOV - code coverage report
Current view: top level - Modules - arraymodule.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 1203 1346 89.4 %
Date: 2022-07-20 13:12:14 Functions: 104 104 100.0 %
Branches: 750 897 83.6 %

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

Generated by: LCOV version 1.14