LCOV - code coverage report
Current view: top level - Modules - arraymodule.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 1224 1378 88.8 %
Date: 2022-07-07 18:19:46 Functions: 104 104 100.0 %

          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     1100450 : get_array_state(PyObject *module)
      69             : {
      70     1100450 :     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       44939 : array_resize(arrayobject *self, Py_ssize_t newsize)
     128             : {
     129             :     char *items;
     130             :     size_t _new_size;
     131             : 
     132       44939 :     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       84713 :     if (self->allocated >= newsize &&
     144       39854 :         Py_SIZE(self) < newsize + 16 &&
     145       39841 :         self->ob_item != NULL) {
     146       39840 :         Py_SET_SIZE(self, newsize);
     147       39840 :         return 0;
     148             :     }
     149             : 
     150        5019 :     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        5005 :     _new_size = (newsize >> 4) + (Py_SIZE(self) < 8 ? 3 : 7) + newsize;
     171        5005 :     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        5005 :     if (_new_size <= ((~(size_t)0) / self->ob_descr->itemsize))
     175        5005 :         PyMem_RESIZE(items, char, (_new_size * self->ob_descr->itemsize));
     176             :     else
     177           0 :         items = NULL;
     178        5005 :     if (items == NULL) {
     179           0 :         PyErr_NoMemory();
     180           0 :         return -1;
     181             :     }
     182        5005 :     self->ob_item = items;
     183        5005 :     Py_SET_SIZE(self, newsize);
     184        5005 :     self->allocated = _new_size;
     185        5005 :     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       41216 : b_getitem(arrayobject *ap, Py_ssize_t i)
     202             : {
     203       41216 :     long x = ((signed char *)ap->ob_item)[i];
     204       41216 :     return PyLong_FromLong(x);
     205             : }
     206             : 
     207             : static int
     208       21453 : 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       21453 :     if (!PyArg_Parse(v, "h;array item must be integer", &x))
     215           5 :         return -1;
     216       21448 :     else if (x < -128) {
     217           4 :         PyErr_SetString(PyExc_OverflowError,
     218             :             "signed char is less than minimum");
     219           4 :         return -1;
     220             :     }
     221       21444 :     else if (x > 127) {
     222           4 :         PyErr_SetString(PyExc_OverflowError,
     223             :             "signed char is greater than maximum");
     224           4 :         return -1;
     225             :     }
     226       21440 :     if (i >= 0)
     227       21173 :         ((char *)ap->ob_item)[i] = (char)x;
     228       21440 :     return 0;
     229             : }
     230             : 
     231             : static PyObject *
     232       19262 : BB_getitem(arrayobject *ap, Py_ssize_t i)
     233             : {
     234       19262 :     long x = ((unsigned char *)ap->ob_item)[i];
     235       19262 :     return PyLong_FromLong(x);
     236             : }
     237             : 
     238             : static int
     239       70263 : 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       70263 :     if (!PyArg_Parse(v, "b;array item must be integer", &x))
     244          13 :         return -1;
     245       70250 :     if (i >= 0)
     246       53457 :         ((char *)ap->ob_item)[i] = x;
     247       70250 :     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        9994 :     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       15164 : h_getitem(arrayobject *ap, Py_ssize_t i)
     284             : {
     285       15164 :     return PyLong_FromLong((long) ((short *)ap->ob_item)[i]);
     286             : }
     287             : 
     288             : 
     289             : static int
     290       20965 : 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       20965 :     if (!PyArg_Parse(v, "h;array item must be integer", &x))
     295          13 :         return -1;
     296       20952 :     if (i >= 0)
     297       20813 :                  ((short *)ap->ob_item)[i] = x;
     298       20952 :     return 0;
     299             : }
     300             : 
     301             : static PyObject *
     302       17962 : HH_getitem(arrayobject *ap, Py_ssize_t i)
     303             : {
     304       17962 :     return PyLong_FromLong((long) ((unsigned short *)ap->ob_item)[i]);
     305             : }
     306             : 
     307             : static int
     308       24972 : 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       24972 :     if (!PyArg_Parse(v, "i;array item must be integer", &x))
     314           5 :         return -1;
     315       24967 :     else if (x < 0) {
     316           4 :         PyErr_SetString(PyExc_OverflowError,
     317             :             "unsigned short is less than minimum");
     318           4 :         return -1;
     319             :     }
     320       24963 :     else if (x > USHRT_MAX) {
     321           4 :         PyErr_SetString(PyExc_OverflowError,
     322             :             "unsigned short is greater than maximum");
     323           4 :         return -1;
     324             :     }
     325       24959 :     if (i >= 0)
     326       24806 :         ((short *)ap->ob_item)[i] = (short)x;
     327       24959 :     return 0;
     328             : }
     329             : 
     330             : static PyObject *
     331       95718 : i_getitem(arrayobject *ap, Py_ssize_t i)
     332             : {
     333       95718 :     return PyLong_FromLong((long) ((int *)ap->ob_item)[i]);
     334             : }
     335             : 
     336             : static int
     337       26325 : 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       26325 :     if (!PyArg_Parse(v, "i;array item must be integer", &x))
     342          13 :         return -1;
     343       26312 :     if (i >= 0)
     344       26066 :                  ((int *)ap->ob_item)[i] = x;
     345       26312 :     return 0;
     346             : }
     347             : 
     348             : static PyObject *
     349       17908 : II_getitem(arrayobject *ap, Py_ssize_t i)
     350             : {
     351       35816 :     return PyLong_FromUnsignedLong(
     352       17908 :         (unsigned long) ((unsigned int *)ap->ob_item)[i]);
     353             : }
     354             : 
     355             : static int
     356       24916 : II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     357             : {
     358             :     unsigned long x;
     359       24916 :     int do_decref = 0; /* if nb_int was called */
     360             : 
     361       24916 :     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       24911 :     x = PyLong_AsUnsignedLong(v);
     369       24911 :     if (x == (unsigned long)-1 && PyErr_Occurred()) {
     370           4 :         if (do_decref) {
     371           2 :             Py_DECREF(v);
     372             :         }
     373           4 :         return -1;
     374             :     }
     375       24907 :     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       24903 :     if (i >= 0)
     384       24750 :         ((unsigned int *)ap->ob_item)[i] = (unsigned int)x;
     385             : 
     386       24903 :     if (do_decref) {
     387           4 :         Py_DECREF(v);
     388             :     }
     389       24903 :     return 0;
     390             : }
     391             : 
     392             : static PyObject *
     393       15137 : l_getitem(arrayobject *ap, Py_ssize_t i)
     394             : {
     395       15137 :     return PyLong_FromLong(((long *)ap->ob_item)[i]);
     396             : }
     397             : 
     398             : static int
     399       20942 : l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     400             : {
     401             :     long x;
     402       20942 :     if (!PyArg_Parse(v, "l;array item must be integer", &x))
     403          13 :         return -1;
     404       20929 :     if (i >= 0)
     405       20790 :                  ((long *)ap->ob_item)[i] = x;
     406       20929 :     return 0;
     407             : }
     408             : 
     409             : static PyObject *
     410       17995 : LL_getitem(arrayobject *ap, Py_ssize_t i)
     411             : {
     412       17995 :     return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]);
     413             : }
     414             : 
     415             : static int
     416       24973 : LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     417             : {
     418             :     unsigned long x;
     419       24973 :     int do_decref = 0; /* if nb_int was called */
     420             : 
     421       24973 :     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       24968 :     x = PyLong_AsUnsignedLong(v);
     429       24968 :     if (x == (unsigned long)-1 && PyErr_Occurred()) {
     430           8 :         if (do_decref) {
     431           4 :             Py_DECREF(v);
     432             :         }
     433           8 :         return -1;
     434             :     }
     435       24960 :     if (i >= 0)
     436       24807 :         ((unsigned long *)ap->ob_item)[i] = x;
     437             : 
     438       24960 :     if (do_decref) {
     439           4 :         Py_DECREF(v);
     440             :     }
     441       24960 :     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       40329 : f_getitem(arrayobject *ap, Py_ssize_t i)
     499             : {
     500       40329 :     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       40292 : d_getitem(arrayobject *ap, Py_ssize_t i)
     516             : {
     517       40292 :     return PyFloat_FromDouble(((double *)ap->ob_item)[i]);
     518             : }
     519             : 
     520             : static int
     521       86519 : d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     522             : {
     523             :     double x;
     524       86519 :     if (!PyArg_Parse(v, "d;array item must be float", &x))
     525           3 :         return -1;
     526       86516 :     if (i >= 0)
     527       86378 :                  ((double *)ap->ob_item)[i] = x;
     528       86516 :     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       15099 : DEFINE_COMPAREITEMS(b, signed char)
     543       17537 : DEFINE_COMPAREITEMS(BB, unsigned char)
     544       11962 : DEFINE_COMPAREITEMS(u, wchar_t)
     545       15070 : DEFINE_COMPAREITEMS(h, short)
     546       17557 : DEFINE_COMPAREITEMS(HH, unsigned short)
     547       15232 : DEFINE_COMPAREITEMS(i, int)
     548       17519 : DEFINE_COMPAREITEMS(II, unsigned int)
     549       15057 : DEFINE_COMPAREITEMS(l, long)
     550       17575 : 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       90731 : newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr)
     586             : {
     587             :     arrayobject *op;
     588             :     size_t nbytes;
     589             : 
     590       90731 :     if (size < 0) {
     591           0 :         PyErr_BadInternalCall();
     592           0 :         return NULL;
     593             :     }
     594             : 
     595             :     /* Check for overflow */
     596       90731 :     if (size > PY_SSIZE_T_MAX / descr->itemsize) {
     597           0 :         return PyErr_NoMemory();
     598             :     }
     599       90731 :     nbytes = size * descr->itemsize;
     600       90731 :     op = (arrayobject *) type->tp_alloc(type, 0);
     601       90731 :     if (op == NULL) {
     602           0 :         return NULL;
     603             :     }
     604       90731 :     op->ob_descr = descr;
     605       90731 :     op->allocated = size;
     606       90731 :     op->weakreflist = NULL;
     607       90731 :     Py_SET_SIZE(op, size);
     608       90731 :     if (size <= 0) {
     609       22213 :         op->ob_item = NULL;
     610             :     }
     611             :     else {
     612       68518 :         op->ob_item = PyMem_NEW(char, nbytes);
     613       68518 :         if (op->ob_item == NULL) {
     614           0 :             Py_DECREF(op);
     615           0 :             return PyErr_NoMemory();
     616             :         }
     617             :     }
     618       90731 :     op->ob_exports = 0;
     619       90731 :     return (PyObject *) op;
     620             : }
     621             : 
     622             : static PyObject *
     623      213914 : getarrayitem(PyObject *op, Py_ssize_t i)
     624             : {
     625             : #ifndef NDEBUG
     626      213914 :     array_state *state = find_array_state_by_type(Py_TYPE(op));
     627      213914 :     assert(array_Check(op, state));
     628             : #endif
     629             :     arrayobject *ap;
     630      213914 :     ap = (arrayobject *)op;
     631      213914 :     assert(i>=0 && i<Py_SIZE(ap));
     632      213914 :     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          94 : array_tp_traverse(arrayobject *op, visitproc visit, void *arg)
     669             : {
     670          94 :     Py_VISIT(Py_TYPE(op));
     671          94 :     return 0;
     672             : }
     673             : 
     674             : static void
     675       90730 : array_dealloc(arrayobject *op)
     676             : {
     677       90730 :     PyTypeObject *tp = Py_TYPE(op);
     678       90730 :     PyObject_GC_UnTrack(op);
     679             : 
     680       90730 :     if (op->weakreflist != NULL)
     681          13 :         PyObject_ClearWeakRefs((PyObject *) op);
     682       90730 :     if (op->ob_item != NULL)
     683       71531 :         PyMem_Free(op->ob_item);
     684       90730 :     tp->tp_free(op);
     685       90730 :     Py_DECREF(tp);
     686       90730 : }
     687             : 
     688             : static PyObject *
     689       47276 : array_richcompare(PyObject *v, PyObject *w, int op)
     690             : {
     691       47276 :     array_state *state = find_array_state_by_type(Py_TYPE(v));
     692             :     arrayobject *va, *wa;
     693       47276 :     PyObject *vi = NULL;
     694       47276 :     PyObject *wi = NULL;
     695             :     Py_ssize_t i, k;
     696             :     PyObject *res;
     697             : 
     698       47276 :     if (!array_Check(v, state) || !array_Check(w, state))
     699       10462 :         Py_RETURN_NOTIMPLEMENTED;
     700             : 
     701       36814 :     va = (arrayobject *)v;
     702       36814 :     wa = (arrayobject *)w;
     703             : 
     704       36814 :     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       36762 :     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       30904 :         Py_ssize_t common_length = Py_MIN(Py_SIZE(va), Py_SIZE(wa));
     718       30904 :         int result = va->ob_descr->compareitems(va->ob_item, wa->ob_item,
     719             :                                                 common_length);
     720       30904 :         if (result == 0)
     721       27990 :             goto compare_sizes;
     722             : 
     723             :         int cmp;
     724        2914 :         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        2804 :         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        2914 :         PyObject *res = cmp ? Py_True : Py_False;
     734        2914 :         Py_INCREF(res);
     735        2914 :         return res;
     736             :     }
     737             : 
     738             : 
     739             :     /* Search for the first index where items are different */
     740        5858 :     k = 1;
     741       30426 :     for (i = 0; i < Py_SIZE(va) && i < Py_SIZE(wa); i++) {
     742       25307 :         vi = getarrayitem(v, i);
     743       25307 :         wi = getarrayitem(w, i);
     744       25307 :         if (vi == NULL || wi == NULL) {
     745           0 :             Py_XDECREF(vi);
     746           0 :             Py_XDECREF(wi);
     747           0 :             return NULL;
     748             :         }
     749       25307 :         k = PyObject_RichCompareBool(vi, wi, Py_EQ);
     750       25307 :         if (k == 0)
     751         739 :             break; /* Keeping vi and wi alive! */
     752       24568 :         Py_DECREF(vi);
     753       24568 :         Py_DECREF(wi);
     754       24568 :         if (k < 0)
     755           0 :             return NULL;
     756             :     }
     757             : 
     758        5858 :     if (k) {
     759             :         /* No more items to compare -- compare sizes */
     760        5119 :         compare_sizes: ;
     761       33109 :         Py_ssize_t vs = Py_SIZE(va);
     762       33109 :         Py_ssize_t ws = Py_SIZE(wa);
     763             :         int cmp;
     764       33109 :         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       32992 :         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       33109 :         if (cmp)
     776       33044 :             res = Py_True;
     777             :         else
     778          65 :             res = Py_False;
     779       33109 :         Py_INCREF(res);
     780       33109 :         return res;
     781             :     }
     782             : 
     783             :     /* We have an item that differs.  First, shortcuts for EQ/NE */
     784         739 :     if (op == Py_EQ) {
     785           6 :         Py_INCREF(Py_False);
     786           6 :         res = Py_False;
     787             :     }
     788         733 :     else if (op == Py_NE) {
     789         709 :         Py_INCREF(Py_True);
     790         709 :         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         739 :     Py_DECREF(vi);
     797         739 :     Py_DECREF(wi);
     798         739 :     return res;
     799             : }
     800             : 
     801             : static Py_ssize_t
     802       71929 : array_length(arrayobject *a)
     803             : {
     804       71929 :     return Py_SIZE(a);
     805             : }
     806             : 
     807             : static PyObject *
     808      126744 : array_item(arrayobject *a, Py_ssize_t i)
     809             : {
     810      126744 :     if (i < 0 || i >= Py_SIZE(a)) {
     811          27 :         PyErr_SetString(PyExc_IndexError, "array index out of range");
     812          27 :         return NULL;
     813             :     }
     814      126717 :     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           0 :         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           1 :         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      349447 : array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v)
     971             : {
     972      349447 :     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      349447 :     if (v == NULL)
     978           0 :         return array_del_slice(a, i, i+1);
     979      349447 :     return (*a->ob_descr->setitem)(a, i, v);
     980             : }
     981             : 
     982             : static int
     983      349447 : setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v)
     984             : {
     985             : #ifndef NDEBUG
     986      349447 :     array_state *state = find_array_state_by_type(Py_TYPE(a));
     987      349447 :     assert(array_Check(a, state));
     988             : #endif
     989      349447 :     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           0 :         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           0 :             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           1 :             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          15 :     assert((size_t)itemsize <= sizeof(tmp));
    1436             : 
    1437          15 :     if (Py_SIZE(self) > 1) {
    1438        5196 :         for (p = self->ob_item,
    1439          15 :              q = self->ob_item + (Py_SIZE(self) - 1)*itemsize;
    1440             :              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           0 :         PyErr_NoMemory();
    1481           0 :         return NULL;
    1482             :     }
    1483             : 
    1484             : 
    1485          89 :     array_state *state = get_array_state_by_class(cls);
    1486          89 :     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          13 :     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        2188 : array_array_tolist_impl(arrayobject *self)
    1618             : /*[clinic end generated code: output=00b60cc9eab8ef89 input=a8d7784a94f86b53]*/
    1619             : {
    1620        2188 :     PyObject *list = PyList_New(Py_SIZE(self));
    1621             :     Py_ssize_t i;
    1622             : 
    1623        2188 :     if (list == NULL)
    1624           0 :         return NULL;
    1625       14869 :     for (i = 0; i < Py_SIZE(self); i++) {
    1626       12681 :         PyObject *v = getarrayitem((PyObject *)self, i);
    1627       12681 :         if (v == NULL)
    1628           0 :             goto error;
    1629       12681 :         PyList_SET_ITEM(list, i, v);
    1630             :     }
    1631        2188 :     return list;
    1632             : 
    1633           0 : error:
    1634           0 :     Py_DECREF(list);
    1635           0 :     return NULL;
    1636             : }
    1637             : 
    1638             : static PyObject *
    1639        1301 : frombytes(arrayobject *self, Py_buffer *buffer)
    1640             : {
    1641        1301 :     int itemsize = self->ob_descr->itemsize;
    1642             :     Py_ssize_t n;
    1643        1301 :     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        1301 :     n = buffer->len;
    1649        1301 :     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        1289 :     n = n / itemsize;
    1656        1289 :     if (n > 0) {
    1657        1196 :         Py_ssize_t old_size = Py_SIZE(self);
    1658        1196 :         if ((n > PY_SSIZE_T_MAX - old_size) ||
    1659        1196 :             ((old_size + n) > PY_SSIZE_T_MAX / itemsize)) {
    1660           0 :                 PyBuffer_Release(buffer);
    1661           0 :                 return PyErr_NoMemory();
    1662             :         }
    1663        1196 :         if (array_resize(self, old_size + n) == -1) {
    1664          13 :             PyBuffer_Release(buffer);
    1665          13 :             return NULL;
    1666             :         }
    1667        1183 :         memcpy(self->ob_item + old_size * itemsize,
    1668        1183 :             buffer->buf, n * itemsize);
    1669             :     }
    1670        1276 :     PyBuffer_Release(buffer);
    1671        1276 :     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        1301 : array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer)
    1685             : /*[clinic end generated code: output=d9842c8f7510a516 input=378db226dfac949e]*/
    1686             : {
    1687        1301 :     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        2194 : array_array_tobytes_impl(arrayobject *self)
    1698             : /*[clinic end generated code: output=87318e4edcdc2bb6 input=90ee495f96de34f5]*/
    1699             : {
    1700        2194 :     if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
    1701        2194 :         return PyBytes_FromStringAndSize(self->ob_item,
    1702        2194 :                             Py_SIZE(self) * self->ob_descr->itemsize);
    1703             :     } else {
    1704           0 :         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           5 :     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         116 :             if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
    1851         116 :                 return IEEE_754_FLOAT_BE;
    1852         116 :             if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
    1853         116 :                 return IEEE_754_FLOAT_LE;
    1854             :         }
    1855           0 :         return UNKNOWN_FORMAT;
    1856             : 
    1857         117 :     case 'd':
    1858             :         if (sizeof(double) == 8) {
    1859         117 :             const double x = 9006104071832581.0;
    1860         117 :             if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
    1861         117 :                 return IEEE_754_DOUBLE_BE;
    1862         117 :             if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
    1863         117 :                 return IEEE_754_DOUBLE_LE;
    1864             :         }
    1865           0 :         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         513 :     assert(arraytype != NULL);
    1937         513 :     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             :                 mf_descr.size,
    2150          91 :                 !mf_descr.is_big_endian,
    2151             :                 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        1014 :     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        1110 : array_get_itemsize(arrayobject *a, void *closure)
    2271             : {
    2272        1110 :     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       51218 : array_subscr(arrayobject* self, PyObject* item)
    2338             : {
    2339       51218 :     array_state *state = find_array_state_by_type(Py_TYPE(self));
    2340             : 
    2341       51218 :     if (PyIndex_Check(item)) {
    2342       32097 :         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
    2343       32097 :         if (i==-1 && PyErr_Occurred()) {
    2344           0 :             return NULL;
    2345             :         }
    2346       32097 :         if (i < 0)
    2347         187 :             i += Py_SIZE(self);
    2348       32097 :         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        4334 :             PyObject *result = newarrayobject(state->ArrayType,
    2368             :                                     slicelength, self->ob_descr);
    2369        4334 :             if (result == NULL)
    2370           0 :                 return NULL;
    2371        4334 :             memcpy(((arrayobject *)result)->ob_item,
    2372        4334 :                    self->ob_item + start * itemsize,
    2373        4334 :                    slicelength * itemsize);
    2374        4334 :             return result;
    2375             :         }
    2376             :         else {
    2377        5840 :             result = newarrayobject(state->ArrayType, slicelength, self->ob_descr);
    2378        5840 :             if (!result) return NULL;
    2379             : 
    2380        5840 :             ar = (arrayobject*)result;
    2381             : 
    2382       17105 :             for (cur = start, i = 0; i < slicelength;
    2383       11265 :                  cur += step, i++) {
    2384       11265 :                 memcpy(ar->ob_item + i*itemsize,
    2385       11265 :                        self->ob_item + cur*itemsize,
    2386             :                        itemsize);
    2387             :             }
    2388             : 
    2389        5840 :             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       42954 : array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
    2401             : {
    2402             :     Py_ssize_t start, stop, step, slicelength, needed;
    2403       42954 :     array_state* state = find_array_state_by_type(Py_TYPE(self));
    2404             :     arrayobject* other;
    2405             :     int itemsize;
    2406             : 
    2407       42954 :     if (PyIndex_Check(item)) {
    2408        9958 :         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
    2409             : 
    2410        9958 :         if (i == -1 && PyErr_Occurred())
    2411           0 :             return -1;
    2412        9958 :         if (i < 0)
    2413          93 :             i += Py_SIZE(self);
    2414        9958 :         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        9906 :         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        9841 :             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        7434 :         if (slicelength > needed) {
    2486        1684 :             memmove(self->ob_item + (start + needed) * itemsize,
    2487        1684 :                 self->ob_item + stop * itemsize,
    2488        1684 :                 (Py_SIZE(self) - stop) * itemsize);
    2489        1684 :             if (array_resize(self, Py_SIZE(self) +
    2490             :                 needed - slicelength) < 0)
    2491           0 :                 return -1;
    2492             :         }
    2493        5750 :         else if (slicelength < needed) {
    2494         335 :             if (array_resize(self, Py_SIZE(self) +
    2495             :                 needed - slicelength) < 0)
    2496           0 :                 return -1;
    2497         335 :             memmove(self->ob_item + (start + needed) * itemsize,
    2498         335 :                 self->ob_item + stop * itemsize,
    2499         335 :                 (Py_SIZE(self) - start - needed) * itemsize);
    2500             :         }
    2501        7434 :         if (needed > 0)
    2502        2477 :             memcpy(self->ob_item + start * itemsize,
    2503        2477 :                    other->ob_item, needed * itemsize);
    2504        7434 :         return 0;
    2505             :     }
    2506       25354 :     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        5610 :         if (needed != slicelength) {
    2541          61 :             PyErr_Format(PyExc_ValueError,
    2542             :                 "attempt to assign array of size %zd "
    2543             :                 "to extended slice of size %zd",
    2544             :                 needed, slicelength);
    2545          61 :             return -1;
    2546             :         }
    2547       13784 :         for (cur = start, i = 0; i < slicelength;
    2548        8235 :              cur += step, i++) {
    2549        8235 :             memcpy(self->ob_item + cur * itemsize,
    2550        8235 :                    other->ob_item + i * itemsize,
    2551             :                    itemsize);
    2552             :         }
    2553        5549 :         return 0;
    2554             :     }
    2555             : }
    2556             : 
    2557             : static const void *emptybuf = "";
    2558             : 
    2559             : 
    2560             : static int
    2561       14402 : array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags)
    2562             : {
    2563       14402 :     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       14389 :     view->buf = (void *)self->ob_item;
    2570       14389 :     view->obj = (PyObject*)self;
    2571       14389 :     Py_INCREF(self);
    2572       14389 :     if (view->buf == NULL)
    2573          45 :         view->buf = (void *)emptybuf;
    2574       14389 :     view->len = Py_SIZE(self) * self->ob_descr->itemsize;
    2575       14389 :     view->readonly = 0;
    2576       14389 :     view->ndim = 1;
    2577       14389 :     view->itemsize = self->ob_descr->itemsize;
    2578       14389 :     view->suboffsets = NULL;
    2579       14389 :     view->shape = NULL;
    2580       14389 :     if ((flags & PyBUF_ND)==PyBUF_ND) {
    2581       13218 :         view->shape = &((PyVarObject*)self)->ob_size;
    2582             :     }
    2583       14389 :     view->strides = NULL;
    2584       14389 :     if ((flags & PyBUF_STRIDES)==PyBUF_STRIDES)
    2585       13214 :         view->strides = &(view->itemsize);
    2586       14389 :     view->format = NULL;
    2587       14389 :     view->internal = NULL;
    2588       14389 :     if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
    2589       13214 :         view->format = (char *)self->ob_descr->formats;
    2590             : #ifdef Py_UNICODE_WIDE
    2591       13214 :         if (self->ob_descr->typecode == 'u') {
    2592           4 :             view->format = "w";
    2593             :         }
    2594             : #endif
    2595             :     }
    2596             : 
    2597       14389 :     self->ob_exports++;
    2598       14389 :     return 0;
    2599             : }
    2600             : 
    2601             : static void
    2602       14388 : array_buffer_relbuf(arrayobject *self, Py_buffer *view)
    2603             : {
    2604       14388 :     self->ob_exports--;
    2605       14388 : }
    2606             : 
    2607             : static PyObject *
    2608       71311 : array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    2609             : {
    2610       71311 :     array_state *state = find_array_state_by_type(type);
    2611             :     int c;
    2612       71311 :     PyObject *initial = NULL, *it = NULL;
    2613             :     const struct arraydescr *descr;
    2614             : 
    2615       71311 :     if ((type == state->ArrayType ||
    2616       71311 :          type->tp_init == state->ArrayType->tp_init) &&
    2617          97 :         !_PyArg_NoKeywords("array.array", kwds))
    2618           1 :         return NULL;
    2619             : 
    2620       71310 :     if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial))
    2621           2 :         return NULL;
    2622             : 
    2623       71308 :     if (PySys_Audit("array.__new__", "CO",
    2624       71308 :                     c, initial ? initial : Py_None) < 0) {
    2625           0 :         return NULL;
    2626             :     }
    2627             : 
    2628       71308 :     if (initial && c != 'u') {
    2629       65023 :         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       65010 :         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       71815 :     if (!(initial == NULL || PyList_Check(initial)
    2643        2502 :           || PyByteArray_Check(initial)
    2644        2489 :           || 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      493191 :     for (descr = descriptors; descr->typecode != '\0'; descr++) {
    2660      493190 :         if (descr->typecode == c) {
    2661             :             PyObject *a;
    2662             :             Py_ssize_t len;
    2663             : 
    2664       71243 :             if (initial == NULL)
    2665        1679 :                 len = 0;
    2666       69564 :             else if (PyList_Check(initial))
    2667       67579 :                 len = PyList_GET_SIZE(initial);
    2668        1985 :             else if (PyTuple_Check(initial) || array_Check(initial, state))
    2669          15 :                 len = Py_SIZE(initial);
    2670             :             else
    2671        1970 :                 len = 0;
    2672             : 
    2673       71243 :             a = newarrayobject(type, len, descr);
    2674       71243 :             if (a == NULL)
    2675           0 :                 return NULL;
    2676             : 
    2677      129194 :             if (len > 0 && !array_Check(initial, state)) {
    2678             :                 Py_ssize_t i;
    2679      407398 :                 for (i = 0; i < len; i++) {
    2680             :                     PyObject *v =
    2681      349447 :                         PySequence_GetItem(initial, i);
    2682      349447 :                     if (v == NULL) {
    2683           0 :                         Py_DECREF(a);
    2684           0 :                         return NULL;
    2685             :                     }
    2686      349447 :                     if (setarrayitem(a, i, v) != 0) {
    2687          40 :                         Py_DECREF(v);
    2688          40 :                         Py_DECREF(a);
    2689          40 :                         return NULL;
    2690             :                     }
    2691      349407 :                     Py_DECREF(v);
    2692             :                 }
    2693             :             }
    2694       24812 :             else if (initial != NULL && (PyByteArray_Check(initial) ||
    2695       12159 :                                PyBytes_Check(initial))) {
    2696             :                 PyObject *v;
    2697         600 :                 v = array_array_frombytes((arrayobject *)a,
    2698             :                                           initial);
    2699         600 :                 if (v == NULL) {
    2700           1 :                     Py_DECREF(a);
    2701           1 :                     return NULL;
    2702             :                 }
    2703         599 :                 Py_DECREF(v);
    2704             :             }
    2705       14022 :             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       11282 :             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       71202 :             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       71189 :             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       50102 : array_iter(arrayobject *ao)
    2870             : {
    2871       50102 :     array_state *state = find_array_state_by_type(Py_TYPE(ao));
    2872             :     arrayiterobject *it;
    2873             : 
    2874       50102 :     if (!array_Check(ao, state)) {
    2875           0 :         PyErr_BadInternalCall();
    2876           0 :         return NULL;
    2877             :     }
    2878             : 
    2879       50102 :     it = PyObject_GC_New(arrayiterobject, state->ArrayIterType);
    2880       50102 :     if (it == NULL)
    2881           0 :         return NULL;
    2882             : 
    2883       50102 :     Py_INCREF(ao);
    2884       50102 :     it->ao = ao;
    2885       50102 :     it->index = 0;
    2886       50102 :     it->getitem = ao->ob_descr->getitem;
    2887       50102 :     PyObject_GC_Track(it);
    2888       50102 :     return (PyObject *)it;
    2889             : }
    2890             : 
    2891             : static PyObject *
    2892      247290 : arrayiter_next(arrayiterobject *it)
    2893             : {
    2894             :     arrayobject *ao;
    2895             : 
    2896      247290 :     assert(it != NULL);
    2897             : #ifndef NDEBUG
    2898      247290 :     array_state *state = find_array_state_by_type(Py_TYPE(it));
    2899      247290 :     assert(PyObject_TypeCheck(it, state->ArrayIterType));
    2900             : #endif
    2901      247290 :     ao = it->ao;
    2902      247290 :     if (ao == NULL) {
    2903          26 :         return NULL;
    2904             :     }
    2905             : #ifndef NDEBUG
    2906      247264 :     assert(array_Check(ao, state));
    2907             : #endif
    2908      247264 :     if (it->index < Py_SIZE(ao)) {
    2909      197178 :         return (*it->getitem)(ao, it->index++);
    2910             :     }
    2911       50086 :     it->ao = NULL;
    2912       50086 :     Py_DECREF(ao);
    2913       50086 :     return NULL;
    2914             : }
    2915             : 
    2916             : static void
    2917       50102 : arrayiter_dealloc(arrayiterobject *it)
    2918             : {
    2919       50102 :     PyTypeObject *tp = Py_TYPE(it);
    2920             : 
    2921       50102 :     PyObject_GC_UnTrack(it);
    2922       50102 :     Py_XDECREF(it->ao);
    2923       50102 :     PyObject_GC_Del(it);
    2924       50102 :     Py_DECREF(tp);
    2925       50102 : }
    2926             : 
    2927             : static int
    2928       50258 : arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
    2929             : {
    2930       50258 :     Py_VISIT(Py_TYPE(it));
    2931       50258 :     Py_VISIT(it->ao);
    2932       50258 :     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         312 :     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       22112 : array_traverse(PyObject *module, visitproc visit, void *arg)
    3011             : {
    3012       22112 :     array_state *state = get_array_state(module);
    3013       22112 :     Py_VISIT(state->ArrayType);
    3014       22112 :     Py_VISIT(state->ArrayIterType);
    3015       22112 :     return 0;
    3016             : }
    3017             : 
    3018             : static int
    3019        1534 : array_clear(PyObject *module)
    3020             : {
    3021        1534 :     array_state *state = get_array_state(module);
    3022        1534 :     Py_CLEAR(state->ArrayType);
    3023        1534 :     Py_CLEAR(state->ArrayIterType);
    3024        1534 :     Py_CLEAR(state->str_read);
    3025        1534 :     Py_CLEAR(state->str_write);
    3026        1534 :     Py_CLEAR(state->str___dict__);
    3027        1534 :     Py_CLEAR(state->str_iter);
    3028        1534 :     return 0;
    3029             : }
    3030             : 
    3031             : static void
    3032         767 : array_free(void *module)
    3033             : {
    3034         767 :     array_clear((PyObject *)module);
    3035         767 : }
    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         808 : array_modexec(PyObject *m)
    3062             : {
    3063         808 :     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         808 :     ADD_INTERNED(state, read);
    3070         808 :     ADD_INTERNED(state, write);
    3071         808 :     ADD_INTERNED(state, __dict__);
    3072         808 :     ADD_INTERNED(state, iter);
    3073             : 
    3074         808 :     CREATE_TYPE(m, state->ArrayType, &array_spec);
    3075         808 :     CREATE_TYPE(m, state->ArrayIterType, &arrayiter_spec);
    3076         808 :     Py_SET_TYPE(state->ArrayIterType, &PyType_Type);
    3077             : 
    3078         808 :     Py_INCREF((PyObject *)state->ArrayType);
    3079         808 :     if (PyModule_AddObject(m, "ArrayType", (PyObject *)state->ArrayType) < 0) {
    3080           0 :         Py_DECREF((PyObject *)state->ArrayType);
    3081           0 :         return -1;
    3082             :     }
    3083             : 
    3084         808 :     PyObject *mutablesequence = _PyImport_GetModuleAttrString(
    3085             :             "collections.abc", "MutableSequence");
    3086         808 :     if (!mutablesequence) {
    3087           0 :         Py_DECREF((PyObject *)state->ArrayType);
    3088           0 :         return -1;
    3089             :     }
    3090         808 :     PyObject *res = PyObject_CallMethod(mutablesequence, "register", "O",
    3091         808 :                                         (PyObject *)state->ArrayType);
    3092         808 :     Py_DECREF(mutablesequence);
    3093         808 :     if (!res) {
    3094           0 :         Py_DECREF((PyObject *)state->ArrayType);
    3095           0 :         return -1;
    3096             :     }
    3097         808 :     Py_DECREF(res);
    3098             : 
    3099         808 :     if (PyModule_AddType(m, state->ArrayType) < 0) {
    3100           0 :         return -1;
    3101             :     }
    3102             : 
    3103         808 :     p = buffer;
    3104       11312 :     for (descr = descriptors; descr->typecode != '\0'; descr++) {
    3105       10504 :         *p++ = (char)descr->typecode;
    3106             :     }
    3107         808 :     typecodes = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
    3108         808 :     if (PyModule_AddObject(m, "typecodes", typecodes) < 0) {
    3109           0 :         Py_XDECREF(typecodes);
    3110           0 :         return -1;
    3111             :     }
    3112             : 
    3113         808 :     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         808 : PyInit_array(void)
    3137             : {
    3138         808 :     return PyModuleDef_Init(&arraymodule);
    3139             : }

Generated by: LCOV version 1.14