1111#include "Python.h"
1212#include "pycore_floatobject.h" // _PyFloat_Unpack4()
1313#include "pycore_moduleobject.h" // _PyModule_GetState()
14- #include "pycore_runtime.h" // _Py_ID()
1514#include "structmember.h" // PyMemberDef
1615#include <stddef.h> // offsetof()
1716#include <stddef.h>
@@ -58,6 +57,12 @@ typedef struct {
5857typedef struct {
5958 PyTypeObject * ArrayType ;
6059 PyTypeObject * ArrayIterType ;
60+
61+ PyObject * str_read ;
62+ PyObject * str_write ;
63+ PyObject * str__array_reconstructor ;
64+ PyObject * str___dict__ ;
65+ PyObject * str_iter ;
6166} array_state ;
6267
6368static array_state *
@@ -1464,6 +1469,7 @@ array_array_reverse_impl(arrayobject *self)
14641469/*[clinic input]
14651470array.array.fromfile
14661471
1472+ cls: defining_class
14671473 f: object
14681474 n: Py_ssize_t
14691475 /
@@ -1472,8 +1478,9 @@ Read n objects from the file object f and append them to the end of the array.
14721478[clinic start generated code]*/
14731479
14741480static PyObject *
1475- array_array_fromfile_impl (arrayobject * self , PyObject * f , Py_ssize_t n )
1476- /*[clinic end generated code: output=ec9f600e10f53510 input=e188afe8e58adf40]*/
1481+ array_array_fromfile_impl (arrayobject * self , PyTypeObject * cls , PyObject * f ,
1482+ Py_ssize_t n )
1483+ /*[clinic end generated code: output=83a667080b345ebc input=3822e907c1c11f1a]*/
14771484{
14781485 PyObject * b , * res ;
14791486 Py_ssize_t itemsize = self -> ob_descr -> itemsize ;
@@ -1488,9 +1495,14 @@ array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n)
14881495 PyErr_NoMemory ();
14891496 return NULL ;
14901497 }
1498+
1499+
1500+ array_state * state = get_array_state_by_class (cls );
1501+ assert (state != NULL );
1502+
14911503 nbytes = n * itemsize ;
14921504
1493- b = _PyObject_CallMethod (f , & _Py_ID ( read ) , "n" , nbytes );
1505+ b = _PyObject_CallMethod (f , state -> str_read , "n" , nbytes );
14941506 if (b == NULL )
14951507 return NULL ;
14961508
@@ -1521,15 +1533,16 @@ array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n)
15211533/*[clinic input]
15221534array.array.tofile
15231535
1536+ cls: defining_class
15241537 f: object
15251538 /
15261539
15271540Write all items (as machine values) to the file object f.
15281541[clinic start generated code]*/
15291542
15301543static PyObject *
1531- array_array_tofile (arrayobject * self , PyObject * f )
1532- /*[clinic end generated code: output=3a2cfa8128df0777 input=b0669a484aab0831 ]*/
1544+ array_array_tofile_impl (arrayobject * self , PyTypeObject * cls , PyObject * f )
1545+ /*[clinic end generated code: output=4560c628d9c18bc2 input=5a24da7a7b407b52 ]*/
15331546{
15341547 Py_ssize_t nbytes = Py_SIZE (self ) * self -> ob_descr -> itemsize ;
15351548 /* Write 64K blocks at a time */
@@ -1541,6 +1554,10 @@ array_array_tofile(arrayobject *self, PyObject *f)
15411554 if (Py_SIZE (self ) == 0 )
15421555 goto done ;
15431556
1557+
1558+ array_state * state = get_array_state_by_class (cls );
1559+ assert (state != NULL );
1560+
15441561 for (i = 0 ; i < nblocks ; i ++ ) {
15451562 char * ptr = self -> ob_item + i * BLOCKSIZE ;
15461563 Py_ssize_t size = BLOCKSIZE ;
@@ -1551,7 +1568,7 @@ array_array_tofile(arrayobject *self, PyObject *f)
15511568 bytes = PyBytes_FromStringAndSize (ptr , size );
15521569 if (bytes == NULL )
15531570 return NULL ;
1554- res = PyObject_CallMethodOneArg (f , & _Py_ID ( write ) , bytes );
1571+ res = PyObject_CallMethodOneArg (f , state -> str_write , bytes );
15551572 Py_DECREF (bytes );
15561573 if (res == NULL )
15571574 return NULL ;
@@ -2174,15 +2191,17 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype,
21742191/*[clinic input]
21752192array.array.__reduce_ex__
21762193
2194+ cls: defining_class
21772195 value: object
21782196 /
21792197
21802198Return state information for pickling.
21812199[clinic start generated code]*/
21822200
21832201static PyObject *
2184- array_array___reduce_ex__ (arrayobject * self , PyObject * value )
2185- /*[clinic end generated code: output=051e0a6175d0eddb input=c36c3f85de7df6cd]*/
2202+ array_array___reduce_ex___impl (arrayobject * self , PyTypeObject * cls ,
2203+ PyObject * value )
2204+ /*[clinic end generated code: output=4958ee5d79452ad5 input=19968cf0f91d3eea]*/
21862205{
21872206 PyObject * dict ;
21882207 PyObject * result ;
@@ -2192,13 +2211,16 @@ array_array___reduce_ex__(arrayobject *self, PyObject *value)
21922211 static PyObject * array_reconstructor = NULL ;
21932212 long protocol ;
21942213
2214+ array_state * state = get_array_state_by_class (cls );
2215+ assert (state != NULL );
2216+
21952217 if (array_reconstructor == NULL ) {
21962218 PyObject * array_module = PyImport_ImportModule ("array" );
21972219 if (array_module == NULL )
21982220 return NULL ;
21992221 array_reconstructor = PyObject_GetAttr (
22002222 array_module ,
2201- & _Py_ID ( _array_reconstructor ) );
2223+ state -> str__array_reconstructor );
22022224 Py_DECREF (array_module );
22032225 if (array_reconstructor == NULL )
22042226 return NULL ;
@@ -2213,7 +2235,7 @@ array_array___reduce_ex__(arrayobject *self, PyObject *value)
22132235 if (protocol == -1 && PyErr_Occurred ())
22142236 return NULL ;
22152237
2216- if (_PyObject_LookupAttr ((PyObject * )self , & _Py_ID ( __dict__ ) , & dict ) < 0 ) {
2238+ if (_PyObject_LookupAttr ((PyObject * )self , state -> str___dict__ , & dict ) < 0 ) {
22172239 return NULL ;
22182240 }
22192241 if (dict == NULL ) {
@@ -2935,14 +2957,20 @@ arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
29352957/*[clinic input]
29362958array.arrayiterator.__reduce__
29372959
2960+ cls: defining_class
2961+ /
2962+
29382963Return state information for pickling.
29392964[clinic start generated code]*/
29402965
29412966static PyObject *
2942- array_arrayiterator___reduce___impl (arrayiterobject * self )
2943- /*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a ]*/
2967+ array_arrayiterator___reduce___impl (arrayiterobject * self , PyTypeObject * cls )
2968+ /*[clinic end generated code: output=4b032417a2c8f5e6 input=ac64e65a87ad452e ]*/
29442969{
2945- PyObject * func = _PyEval_GetBuiltin (& _Py_ID (iter ));
2970+
2971+ array_state * state = get_array_state_by_class (cls );
2972+ assert (state != NULL );
2973+ PyObject * func = _PyEval_GetBuiltin (state -> str_iter );
29462974 if (self -> ao == NULL ) {
29472975 return Py_BuildValue ("N(())" , func );
29482976 }
@@ -3006,6 +3034,11 @@ array_traverse(PyObject *module, visitproc visit, void *arg)
30063034 array_state * state = get_array_state (module );
30073035 Py_VISIT (state -> ArrayType );
30083036 Py_VISIT (state -> ArrayIterType );
3037+ Py_VISIT (state -> str_read );
3038+ Py_VISIT (state -> str_write );
3039+ Py_VISIT (state -> str__array_reconstructor );
3040+ Py_VISIT (state -> str___dict__ );
3041+ Py_VISIT (state -> str_iter );
30093042 return 0 ;
30103043}
30113044
@@ -3015,6 +3048,11 @@ array_clear(PyObject *module)
30153048 array_state * state = get_array_state (module );
30163049 Py_CLEAR (state -> ArrayType );
30173050 Py_CLEAR (state -> ArrayIterType );
3051+ Py_CLEAR (state -> str_read );
3052+ Py_CLEAR (state -> str_write );
3053+ Py_CLEAR (state -> str__array_reconstructor );
3054+ Py_CLEAR (state -> str___dict__ );
3055+ Py_CLEAR (state -> str_iter );
30183056 return 0 ;
30193057}
30203058
@@ -3038,6 +3076,15 @@ do { \
30383076 } \
30393077} while (0)
30403078
3079+ #define ADD_INTERNED (state , string ) \
3080+ do { \
3081+ PyObject *tmp = PyUnicode_InternFromString(#string); \
3082+ if (tmp == NULL) { \
3083+ return -1; \
3084+ } \
3085+ state->str_ ## string = tmp; \
3086+ } while (0)
3087+
30413088static int
30423089array_modexec (PyObject * m )
30433090{
@@ -3046,6 +3093,13 @@ array_modexec(PyObject *m)
30463093 PyObject * typecodes ;
30473094 const struct arraydescr * descr ;
30483095
3096+ /* Add interned strings */
3097+ ADD_INTERNED (state , read );
3098+ ADD_INTERNED (state , write );
3099+ ADD_INTERNED (state , _array_reconstructor );
3100+ ADD_INTERNED (state , __dict__ );
3101+ ADD_INTERNED (state , iter );
3102+
30493103 CREATE_TYPE (m , state -> ArrayType , & array_spec );
30503104 CREATE_TYPE (m , state -> ArrayIterType , & arrayiter_spec );
30513105 Py_SET_TYPE (state -> ArrayIterType , & PyType_Type );
0 commit comments