bpo-46541: Remove usage of _Py_IDENTIFIER from array module (GH-31376)

This commit is contained in:
Dong-hee Na 2022-02-17 13:02:17 +09:00 committed by GitHub
parent 6e7b813195
commit 8cb5f707a8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 139 additions and 45 deletions

View file

@ -6,7 +6,6 @@
#ifndef Py_BUILD_CORE_BUILTIN
# define Py_BUILD_CORE_MODULE 1
#endif
#define NEEDS_PY_IDENTIFIER
#define PY_SSIZE_T_CLEAN
#include "Python.h"
@ -58,6 +57,12 @@ typedef struct {
typedef struct {
PyTypeObject *ArrayType;
PyTypeObject *ArrayIterType;
PyObject *str_read;
PyObject *str_write;
PyObject *str__array_reconstructor;
PyObject *str___dict__;
PyObject *str_iter;
} array_state;
static array_state *
@ -1464,6 +1469,7 @@ array_array_reverse_impl(arrayobject *self)
/*[clinic input]
array.array.fromfile
cls: defining_class
f: object
n: Py_ssize_t
/
@ -1472,13 +1478,13 @@ Read n objects from the file object f and append them to the end of the array.
[clinic start generated code]*/
static PyObject *
array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n)
/*[clinic end generated code: output=ec9f600e10f53510 input=e188afe8e58adf40]*/
array_array_fromfile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f,
Py_ssize_t n)
/*[clinic end generated code: output=83a667080b345ebc input=3822e907c1c11f1a]*/
{
PyObject *b, *res;
Py_ssize_t itemsize = self->ob_descr->itemsize;
Py_ssize_t nbytes;
_Py_IDENTIFIER(read);
int not_enough_bytes;
if (n < 0) {
@ -1489,9 +1495,14 @@ array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n)
PyErr_NoMemory();
return NULL;
}
array_state *state = get_array_state_by_class(cls);
assert(state != NULL);
nbytes = n * itemsize;
b = _PyObject_CallMethodId(f, &PyId_read, "n", nbytes);
b = _PyObject_CallMethod(f, state->str_read, "n", nbytes);
if (b == NULL)
return NULL;
@ -1522,6 +1533,7 @@ array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n)
/*[clinic input]
array.array.tofile
cls: defining_class
f: object
/
@ -1529,8 +1541,8 @@ Write all items (as machine values) to the file object f.
[clinic start generated code]*/
static PyObject *
array_array_tofile(arrayobject *self, PyObject *f)
/*[clinic end generated code: output=3a2cfa8128df0777 input=b0669a484aab0831]*/
array_array_tofile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f)
/*[clinic end generated code: output=4560c628d9c18bc2 input=5a24da7a7b407b52]*/
{
Py_ssize_t nbytes = Py_SIZE(self) * self->ob_descr->itemsize;
/* Write 64K blocks at a time */
@ -1542,18 +1554,21 @@ array_array_tofile(arrayobject *self, PyObject *f)
if (Py_SIZE(self) == 0)
goto done;
array_state *state = get_array_state_by_class(cls);
assert(state != NULL);
for (i = 0; i < nblocks; i++) {
char* ptr = self->ob_item + i*BLOCKSIZE;
Py_ssize_t size = BLOCKSIZE;
PyObject *bytes, *res;
_Py_IDENTIFIER(write);
if (i*BLOCKSIZE + size > nbytes)
size = nbytes - i*BLOCKSIZE;
bytes = PyBytes_FromStringAndSize(ptr, size);
if (bytes == NULL)
return NULL;
res = _PyObject_CallMethodIdOneArg(f, &PyId_write, bytes);
res = PyObject_CallMethodOneArg(f, state->str_write, bytes);
Py_DECREF(bytes);
if (res == NULL)
return NULL;
@ -2176,6 +2191,7 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype,
/*[clinic input]
array.array.__reduce_ex__
cls: defining_class
value: object
/
@ -2183,8 +2199,9 @@ Return state information for pickling.
[clinic start generated code]*/
static PyObject *
array_array___reduce_ex__(arrayobject *self, PyObject *value)
/*[clinic end generated code: output=051e0a6175d0eddb input=c36c3f85de7df6cd]*/
array_array___reduce_ex___impl(arrayobject *self, PyTypeObject *cls,
PyObject *value)
/*[clinic end generated code: output=4958ee5d79452ad5 input=19968cf0f91d3eea]*/
{
PyObject *dict;
PyObject *result;
@ -2193,16 +2210,17 @@ array_array___reduce_ex__(arrayobject *self, PyObject *value)
int mformat_code;
static PyObject *array_reconstructor = NULL;
long protocol;
_Py_IDENTIFIER(_array_reconstructor);
_Py_IDENTIFIER(__dict__);
array_state *state = get_array_state_by_class(cls);
assert(state != NULL);
if (array_reconstructor == NULL) {
PyObject *array_module = PyImport_ImportModule("array");
if (array_module == NULL)
return NULL;
array_reconstructor = _PyObject_GetAttrId(
array_reconstructor = PyObject_GetAttr(
array_module,
&PyId__array_reconstructor);
state->str__array_reconstructor);
Py_DECREF(array_module);
if (array_reconstructor == NULL)
return NULL;
@ -2217,7 +2235,7 @@ array_array___reduce_ex__(arrayobject *self, PyObject *value)
if (protocol == -1 && PyErr_Occurred())
return NULL;
if (_PyObject_LookupAttrId((PyObject *)self, &PyId___dict__, &dict) < 0) {
if (_PyObject_LookupAttr((PyObject *)self, state->str___dict__, &dict) < 0) {
return NULL;
}
if (dict == NULL) {
@ -2939,15 +2957,20 @@ arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
/*[clinic input]
array.arrayiterator.__reduce__
cls: defining_class
/
Return state information for pickling.
[clinic start generated code]*/
static PyObject *
array_arrayiterator___reduce___impl(arrayiterobject *self)
/*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/
array_arrayiterator___reduce___impl(arrayiterobject *self, PyTypeObject *cls)
/*[clinic end generated code: output=4b032417a2c8f5e6 input=ac64e65a87ad452e]*/
{
_Py_IDENTIFIER(iter);
PyObject *func = _PyEval_GetBuiltinId(&PyId_iter);
array_state *state = get_array_state_by_class(cls);
assert(state != NULL);
PyObject *func = _PyEval_GetBuiltin(state->str_iter);
if (self->ao == NULL) {
return Py_BuildValue("N(())", func);
}
@ -3011,6 +3034,11 @@ array_traverse(PyObject *module, visitproc visit, void *arg)
array_state *state = get_array_state(module);
Py_VISIT(state->ArrayType);
Py_VISIT(state->ArrayIterType);
Py_VISIT(state->str_read);
Py_VISIT(state->str_write);
Py_VISIT(state->str__array_reconstructor);
Py_VISIT(state->str___dict__);
Py_VISIT(state->str_iter);
return 0;
}
@ -3020,6 +3048,11 @@ array_clear(PyObject *module)
array_state *state = get_array_state(module);
Py_CLEAR(state->ArrayType);
Py_CLEAR(state->ArrayIterType);
Py_CLEAR(state->str_read);
Py_CLEAR(state->str_write);
Py_CLEAR(state->str__array_reconstructor);
Py_CLEAR(state->str___dict__);
Py_CLEAR(state->str_iter);
return 0;
}
@ -3043,6 +3076,15 @@ do { \
} \
} while (0)
#define ADD_INTERNED(state, string) \
do { \
PyObject *tmp = PyUnicode_InternFromString(#string); \
if (tmp == NULL) { \
return -1; \
} \
state->str_ ## string = tmp; \
} while (0)
static int
array_modexec(PyObject *m)
{
@ -3051,6 +3093,13 @@ array_modexec(PyObject *m)
PyObject *typecodes;
const struct arraydescr *descr;
/* Add interned strings */
ADD_INTERNED(state, read);
ADD_INTERNED(state, write);
ADD_INTERNED(state, _array_reconstructor);
ADD_INTERNED(state, __dict__);
ADD_INTERNED(state, iter);
CREATE_TYPE(m, state->ArrayType, &array_spec);
CREATE_TYPE(m, state->ArrayIterType, &arrayiter_spec);
Py_SET_TYPE(state->ArrayIterType, &PyType_Type);