Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-46541: Remove usage of _Py_IDENTIFIER from array module #31376

Merged
merged 2 commits into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 69 additions & 20 deletions Modules/arraymodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 *
Expand Down Expand Up @@ -1464,6 +1469,7 @@ array_array_reverse_impl(arrayobject *self)
/*[clinic input]
array.array.fromfile

cls: defining_class
f: object
n: Py_ssize_t
/
Expand All @@ -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) {
Expand All @@ -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;

Expand Down Expand Up @@ -1522,15 +1533,16 @@ array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n)
/*[clinic input]
array.array.tofile

cls: defining_class
f: object
/

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 */
Expand All @@ -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;
Expand Down Expand Up @@ -2176,15 +2191,17 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype,
/*[clinic input]
array.array.__reduce_ex__

cls: defining_class
value: object
/

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;
Expand All @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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)
{
Expand All @@ -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);
Expand Down
95 changes: 70 additions & 25 deletions Modules/clinic/arraymodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.