]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-46541: Remove usage of _Py_IDENTIFIER from array module (GH-31376)
authorDong-hee Na <donghee.na@python.org>
Thu, 17 Feb 2022 04:02:17 +0000 (13:02 +0900)
committerGitHub <noreply@github.com>
Thu, 17 Feb 2022 04:02:17 +0000 (13:02 +0900)
Modules/arraymodule.c
Modules/clinic/arraymodule.c.h

index e516f54ab61e632d006e96a3b18d9de2e57c56ec..2d6da1aaac85a951336b84a628c9970e43233bb0 100644 (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);
index c46cc738de91b7ed47aef9f918f8cecf79bdb973..583ff28bf3287e6b374db9f45b1fb6ec78b9b48c 100644 (file)
@@ -285,35 +285,26 @@ PyDoc_STRVAR(array_array_fromfile__doc__,
 "Read n objects from the file object f and append them to the end of the array.");
 
 #define ARRAY_ARRAY_FROMFILE_METHODDEF    \
-    {"fromfile", (PyCFunction)(void(*)(void))array_array_fromfile, METH_FASTCALL, array_array_fromfile__doc__},
+    {"fromfile", (PyCFunction)(void(*)(void))array_array_fromfile, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, array_array_fromfile__doc__},
 
 static PyObject *
-array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n);
+array_array_fromfile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f,
+                          Py_ssize_t n);
 
 static PyObject *
-array_array_fromfile(arrayobject *self, PyObject *const *args, Py_ssize_t nargs)
+array_array_fromfile(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {"On:fromfile", _keywords, 0};
     PyObject *f;
     Py_ssize_t n;
 
-    if (!_PyArg_CheckPositional("fromfile", nargs, 2, 2)) {
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+        &f, &n)) {
         goto exit;
     }
-    f = args[0];
-    {
-        Py_ssize_t ival = -1;
-        PyObject *iobj = _PyNumber_Index(args[1]);
-        if (iobj != NULL) {
-            ival = PyLong_AsSsize_t(iobj);
-            Py_DECREF(iobj);
-        }
-        if (ival == -1 && PyErr_Occurred()) {
-            goto exit;
-        }
-        n = ival;
-    }
-    return_value = array_array_fromfile_impl(self, f, n);
+    return_value = array_array_fromfile_impl(self, cls, f, n);
 
 exit:
     return return_value;
@@ -326,7 +317,28 @@ PyDoc_STRVAR(array_array_tofile__doc__,
 "Write all items (as machine values) to the file object f.");
 
 #define ARRAY_ARRAY_TOFILE_METHODDEF    \
-    {"tofile", (PyCFunction)array_array_tofile, METH_O, array_array_tofile__doc__},
+    {"tofile", (PyCFunction)(void(*)(void))array_array_tofile, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, array_array_tofile__doc__},
+
+static PyObject *
+array_array_tofile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f);
+
+static PyObject *
+array_array_tofile(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {"O:tofile", _keywords, 0};
+    PyObject *f;
+
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+        &f)) {
+        goto exit;
+    }
+    return_value = array_array_tofile_impl(self, cls, f);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(array_array_fromlist__doc__,
 "fromlist($self, list, /)\n"
@@ -544,7 +556,29 @@ PyDoc_STRVAR(array_array___reduce_ex____doc__,
 "Return state information for pickling.");
 
 #define ARRAY_ARRAY___REDUCE_EX___METHODDEF    \
-    {"__reduce_ex__", (PyCFunction)array_array___reduce_ex__, METH_O, array_array___reduce_ex____doc__},
+    {"__reduce_ex__", (PyCFunction)(void(*)(void))array_array___reduce_ex__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, array_array___reduce_ex____doc__},
+
+static PyObject *
+array_array___reduce_ex___impl(arrayobject *self, PyTypeObject *cls,
+                               PyObject *value);
+
+static PyObject *
+array_array___reduce_ex__(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {"O:__reduce_ex__", _keywords, 0};
+    PyObject *value;
+
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+        &value)) {
+        goto exit;
+    }
+    return_value = array_array___reduce_ex___impl(self, cls, value);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(array_arrayiterator___reduce____doc__,
 "__reduce__($self, /)\n"
@@ -553,15 +587,26 @@ PyDoc_STRVAR(array_arrayiterator___reduce____doc__,
 "Return state information for pickling.");
 
 #define ARRAY_ARRAYITERATOR___REDUCE___METHODDEF    \
-    {"__reduce__", (PyCFunction)array_arrayiterator___reduce__, METH_NOARGS, array_arrayiterator___reduce____doc__},
+    {"__reduce__", (PyCFunction)(void(*)(void))array_arrayiterator___reduce__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, array_arrayiterator___reduce____doc__},
 
 static PyObject *
-array_arrayiterator___reduce___impl(arrayiterobject *self);
+array_arrayiterator___reduce___impl(arrayiterobject *self, PyTypeObject *cls);
 
 static PyObject *
-array_arrayiterator___reduce__(arrayiterobject *self, PyObject *Py_UNUSED(ignored))
+array_arrayiterator___reduce__(arrayiterobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return array_arrayiterator___reduce___impl(self);
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = { NULL};
+    static _PyArg_Parser _parser = {":__reduce__", _keywords, 0};
+
+    if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser
+        )) {
+        goto exit;
+    }
+    return_value = array_arrayiterator___reduce___impl(self, cls);
+
+exit:
+    return return_value;
 }
 
 PyDoc_STRVAR(array_arrayiterator___setstate____doc__,
@@ -572,4 +617,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__,
 
 #define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF    \
     {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__},
-/*[clinic end generated code: output=f130a994f98f1227 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=1db6decd8492bf91 input=a9049054013a1b77]*/