diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-11-03-13-46-10.bpo-40077.NfAIdj.rst b/Misc/NEWS.d/next/Core and Builtins/2020-11-03-13-46-10.bpo-40077.NfAIdj.rst new file mode 100644 index 00000000000000..40c5511e321334 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-11-03-13-46-10.bpo-40077.NfAIdj.rst @@ -0,0 +1 @@ +Convert :mod:`array` to use heap types, and establish module state for these. diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 6583e666119590..12bd51705579bd 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -5,6 +5,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "structmember.h" // PyMemberDef #include // offsetof() #ifdef STDC_HEADERS @@ -21,6 +22,7 @@ module array /*[clinic end generated code: output=da39a3ee5e6b4b0d input=7d1b8d7f5958fd83]*/ struct arrayobject; /* Forward */ +static struct PyModuleDef arraymodule; /* All possible arraydescr values are defined in the vector "descriptors" * below. That's defined later because the appropriate get and set @@ -46,8 +48,6 @@ typedef struct arrayobject { Py_ssize_t ob_exports; /* Number of exported buffers */ } arrayobject; -static PyTypeObject Arraytype; - typedef struct { PyObject_HEAD Py_ssize_t index; @@ -55,9 +55,21 @@ typedef struct { PyObject* (*getitem)(struct arrayobject *, Py_ssize_t); } arrayiterobject; -static PyTypeObject PyArrayIter_Type; +typedef struct { + PyTypeObject *ArrayType; + PyTypeObject *ArrayIterType; +} array_state; -#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type) +static array_state * +get_array_state(PyObject *module) +{ + return (array_state *)PyModule_GetState(module); +} + +#define find_array_state_by_type(tp) \ + (get_array_state(_PyType_GetModuleByDef(tp, &arraymodule))) +#define get_array_state_by_class(cls) \ + (get_array_state(PyType_GetModule(cls))) enum machine_format_code { UNKNOWN_FORMAT = -1, @@ -105,8 +117,7 @@ enum machine_format_code { */ #include "clinic/arraymodule.c.h" -#define array_Check(op) PyObject_TypeCheck(op, &Arraytype) -#define array_CheckExact(op) Py_IS_TYPE(op, &Arraytype) +#define array_Check(op, state) PyObject_TypeCheck(op, state->ArrayType) static int array_resize(arrayobject *self, Py_ssize_t newsize) @@ -562,9 +573,9 @@ static const struct arraydescr descriptors[] = { Implementations of array object methods. ****************************************************************************/ /*[clinic input] -class array.array "arrayobject *" "&Arraytype" +class array.array "arrayobject *" "ArrayType" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ad43d37e942a8854]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a5c29edf59f176a3]*/ static PyObject * newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr) @@ -607,8 +618,11 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des static PyObject * getarrayitem(PyObject *op, Py_ssize_t i) { +#ifndef NDEBUG + array_state *state = find_array_state_by_type(Py_TYPE(op)); + assert(array_Check(op, state)); +#endif arrayobject *ap; - assert(array_Check(op)); ap = (arrayobject *)op; assert(i>=0 && iob_descr->getitem)(ap, i); @@ -649,23 +663,27 @@ ins1(arrayobject *self, Py_ssize_t where, PyObject *v) static void array_dealloc(arrayobject *op) { + PyTypeObject *tp = Py_TYPE(op); + if (op->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) op); if (op->ob_item != NULL) PyMem_Free(op->ob_item); - Py_TYPE(op)->tp_free((PyObject *)op); + tp->tp_free(op); + Py_DECREF(tp); } static PyObject * array_richcompare(PyObject *v, PyObject *w, int op) { + array_state *state = find_array_state_by_type(Py_TYPE(v)); arrayobject *va, *wa; PyObject *vi = NULL; PyObject *wi = NULL; Py_ssize_t i, k; PyObject *res; - if (!array_Check(v) || !array_Check(w)) + if (!array_Check(v, state) || !array_Check(w, state)) Py_RETURN_NOTIMPLEMENTED; va = (arrayobject *)v; @@ -787,7 +805,9 @@ array_item(arrayobject *a, Py_ssize_t i) static PyObject * array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh) { + array_state *state = find_array_state_by_type(Py_TYPE(a)); arrayobject *np; + if (ilow < 0) ilow = 0; else if (ilow > Py_SIZE(a)) @@ -798,7 +818,7 @@ array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh) ihigh = ilow; else if (ihigh > Py_SIZE(a)) ihigh = Py_SIZE(a); - np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_descr); + np = (arrayobject *) newarrayobject(state->ArrayType, ihigh - ilow, a->ob_descr); if (np == NULL) return NULL; if (ihigh > ilow) { @@ -841,9 +861,10 @@ array_array___deepcopy__(arrayobject *self, PyObject *unused) static PyObject * array_concat(arrayobject *a, PyObject *bb) { + array_state *state = find_array_state_by_type(Py_TYPE(a)); Py_ssize_t size; arrayobject *np; - if (!array_Check(bb)) { + if (!array_Check(bb, state)) { PyErr_Format(PyExc_TypeError, "can only append array (not \"%.200s\") to array", Py_TYPE(bb)->tp_name); @@ -858,7 +879,7 @@ array_concat(arrayobject *a, PyObject *bb) return PyErr_NoMemory(); } size = Py_SIZE(a) + Py_SIZE(b); - np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr); + np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr); if (np == NULL) { return NULL; } @@ -876,6 +897,7 @@ array_concat(arrayobject *a, PyObject *bb) static PyObject * array_repeat(arrayobject *a, Py_ssize_t n) { + array_state *state = find_array_state_by_type(Py_TYPE(a)); Py_ssize_t size; arrayobject *np; Py_ssize_t oldbytes, newbytes; @@ -885,7 +907,7 @@ array_repeat(arrayobject *a, Py_ssize_t n) return PyErr_NoMemory(); } size = Py_SIZE(a) * n; - np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr); + np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr); if (np == NULL) return NULL; if (size == 0) @@ -958,7 +980,10 @@ array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v) static int setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v) { - assert(array_Check(a)); +#ifndef NDEBUG + array_state *state = find_array_state_by_type(Py_TYPE(a)); + assert(array_Check(a, state)); +#endif return array_ass_item((arrayobject *)a, i, v); } @@ -986,11 +1011,11 @@ array_iter_extend(arrayobject *self, PyObject *bb) } static int -array_do_extend(arrayobject *self, PyObject *bb) +array_do_extend(array_state *state, arrayobject *self, PyObject *bb) { Py_ssize_t size, oldsize, bbsize; - if (!array_Check(bb)) + if (!array_Check(bb, state)) return array_iter_extend(self, bb); #define b ((arrayobject *)bb) if (self->ob_descr != b->ob_descr) { @@ -1021,13 +1046,15 @@ array_do_extend(arrayobject *self, PyObject *bb) static PyObject * array_inplace_concat(arrayobject *self, PyObject *bb) { - if (!array_Check(bb)) { + array_state *state = find_array_state_by_type(Py_TYPE(self)); + + if (!array_Check(bb, state)) { PyErr_Format(PyExc_TypeError, "can only extend array with array (not \"%.200s\")", Py_TYPE(bb)->tp_name); return NULL; } - if (array_do_extend(self, bb) == -1) + if (array_do_extend(state, self, bb) == -1) return NULL; Py_INCREF(self); return (PyObject *)self; @@ -1232,6 +1259,7 @@ array_array_pop_impl(arrayobject *self, Py_ssize_t i) /*[clinic input] array.array.extend + cls: defining_class bb: object / @@ -1239,10 +1267,12 @@ Append items to the end of the array. [clinic start generated code]*/ static PyObject * -array_array_extend(arrayobject *self, PyObject *bb) -/*[clinic end generated code: output=bbddbc8e8bef871d input=43be86aba5c31e44]*/ +array_array_extend_impl(arrayobject *self, PyTypeObject *cls, PyObject *bb) +/*[clinic end generated code: output=e65eb7588f0bc266 input=8eb6817ec4d2cb62]*/ { - if (array_do_extend(self, bb) == -1) + array_state *state = get_array_state_by_class(cls); + + if (array_do_extend(state, self, bb) == -1) return NULL; Py_RETURN_NONE; } @@ -1928,6 +1958,7 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, PyObject *items) /*[clinic end generated code: output=e05263141ba28365 input=2464dc8f4c7736b5]*/ { + array_state *state = get_array_state(module); PyObject *converted_items; PyObject *result; const struct arraydescr *descr; @@ -1938,10 +1969,10 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, Py_TYPE(arraytype)->tp_name); return NULL; } - if (!PyType_IsSubtype(arraytype, &Arraytype)) { + if (!PyType_IsSubtype(arraytype, state->ArrayType)) { PyErr_Format(PyExc_TypeError, "%.200s is not a subtype of %.200s", - arraytype->tp_name, Arraytype.tp_name); + arraytype->tp_name, state->ArrayType->tp_name); return NULL; } for (descr = descriptors; descr->typecode != '\0'; descr++) { @@ -2287,6 +2318,8 @@ array_repr(arrayobject *a) static PyObject* array_subscr(arrayobject* self, PyObject* item) { + array_state *state = find_array_state_by_type(Py_TYPE(self)); + if (PyIndex_Check(item)) { Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i==-1 && PyErr_Occurred()) { @@ -2310,10 +2343,10 @@ array_subscr(arrayobject* self, PyObject* item) step); if (slicelength <= 0) { - return newarrayobject(&Arraytype, 0, self->ob_descr); + return newarrayobject(state->ArrayType, 0, self->ob_descr); } else if (step == 1) { - PyObject *result = newarrayobject(&Arraytype, + PyObject *result = newarrayobject(state->ArrayType, slicelength, self->ob_descr); if (result == NULL) return NULL; @@ -2323,7 +2356,7 @@ array_subscr(arrayobject* self, PyObject* item) return result; } else { - result = newarrayobject(&Arraytype, slicelength, self->ob_descr); + result = newarrayobject(state->ArrayType, slicelength, self->ob_descr); if (!result) return NULL; ar = (arrayobject*)result; @@ -2349,6 +2382,7 @@ static int array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value) { Py_ssize_t start, stop, step, slicelength, needed; + array_state* state = find_array_state_by_type(Py_TYPE(self)); arrayobject* other; int itemsize; @@ -2390,7 +2424,7 @@ array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value) other = NULL; needed = 0; } - else if (array_Check(value)) { + else if (array_Check(value, state)) { other = (arrayobject *)value; needed = Py_SIZE(other); if (self == other) { @@ -2502,12 +2536,6 @@ array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value) } } -static PyMappingMethods array_as_mapping = { - (lenfunc)array_length, - (binaryfunc)array_subscr, - (objobjargproc)array_ass_subscr -}; - static const void *emptybuf = ""; @@ -2558,32 +2586,15 @@ array_buffer_relbuf(arrayobject *self, Py_buffer *view) self->ob_exports--; } -static PySequenceMethods array_as_sequence = { - (lenfunc)array_length, /*sq_length*/ - (binaryfunc)array_concat, /*sq_concat*/ - (ssizeargfunc)array_repeat, /*sq_repeat*/ - (ssizeargfunc)array_item, /*sq_item*/ - 0, /*sq_slice*/ - (ssizeobjargproc)array_ass_item, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ - (objobjproc)array_contains, /*sq_contains*/ - (binaryfunc)array_inplace_concat, /*sq_inplace_concat*/ - (ssizeargfunc)array_inplace_repeat /*sq_inplace_repeat*/ -}; - -static PyBufferProcs array_as_buffer = { - (getbufferproc)array_buffer_getbuf, - (releasebufferproc)array_buffer_relbuf -}; - static PyObject * array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { + array_state *state = find_array_state_by_type(type); int c; PyObject *initial = NULL, *it = NULL; const struct arraydescr *descr; - if (type == &Arraytype && !_PyArg_NoKeywords("array.array", kwds)) + if (type == state->ArrayType && !_PyArg_NoKeywords("array.array", kwds)) return NULL; if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial)) @@ -2600,7 +2611,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) "an array with typecode '%c'", c); return NULL; } - else if (array_Check(initial) && + else if (array_Check(initial, state) && ((arrayobject*)initial)->ob_descr->typecode == 'u') { PyErr_Format(PyExc_TypeError, "cannot use a unicode array to " "initialize an array with typecode '%c'", c); @@ -2613,7 +2624,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) || PyBytes_Check(initial) || PyTuple_Check(initial) || ((c=='u') && PyUnicode_Check(initial)) - || (array_Check(initial) + || (array_Check(initial, state) && c == ((arrayobject*)initial)->ob_descr->typecode))) { it = PyObject_GetIter(initial); if (it == NULL) @@ -2634,7 +2645,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) len = 0; else if (PyList_Check(initial)) len = PyList_GET_SIZE(initial); - else if (PyTuple_Check(initial) || array_Check(initial)) + else if (PyTuple_Check(initial) || array_Check(initial, state)) len = Py_SIZE(initial); else len = 0; @@ -2643,7 +2654,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (a == NULL) return NULL; - if (len > 0 && !array_Check(initial)) { + if (len > 0 && !array_Check(initial, state)) { Py_ssize_t i; for (i = 0; i < len; i++) { PyObject *v = @@ -2688,7 +2699,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->allocated = n; } } - else if (initial != NULL && array_Check(initial) && len > 0) { + else if (initial != NULL && array_Check(initial, state) && len > 0) { arrayobject *self = (arrayobject *)a; arrayobject *other = (arrayobject *)initial; memcpy(self->ob_item, other->ob_item, len * other->ob_descr->itemsize); @@ -2777,67 +2788,73 @@ itemsize -- the length in bytes of one array item\n\ static PyObject *array_iter(arrayobject *ao); -static PyTypeObject Arraytype = { - PyVarObject_HEAD_INIT(NULL, 0) - "array.array", - sizeof(arrayobject), - 0, - (destructor)array_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)array_repr, /* tp_repr */ - 0, /* tp_as_number*/ - &array_as_sequence, /* tp_as_sequence*/ - &array_as_mapping, /* tp_as_mapping*/ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - &array_as_buffer, /* tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - arraytype_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - array_richcompare, /* tp_richcompare */ - offsetof(arrayobject, weakreflist), /* tp_weaklistoffset */ - (getiterfunc)array_iter, /* tp_iter */ - 0, /* tp_iternext */ - array_methods, /* tp_methods */ - 0, /* tp_members */ - array_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - array_new, /* tp_new */ - PyObject_Del, /* tp_free */ +static struct PyMemberDef array_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(arrayobject, weakreflist), READONLY}, + {NULL}, }; +static PyType_Slot array_slots[] = { + {Py_tp_dealloc, array_dealloc}, + {Py_tp_repr, array_repr}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)arraytype_doc}, + {Py_tp_richcompare, array_richcompare}, + {Py_tp_iter, array_iter}, + {Py_tp_methods, array_methods}, + {Py_tp_members, array_members}, + {Py_tp_getset, array_getsets}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, array_new}, + {Py_tp_free, PyObject_Del}, + + /* as sequence */ + {Py_sq_length, array_length}, + {Py_sq_concat, array_concat}, + {Py_sq_repeat, array_repeat}, + {Py_sq_item, array_item}, + {Py_sq_ass_item, array_ass_item}, + {Py_sq_contains, array_contains}, + {Py_sq_inplace_concat, array_inplace_concat}, + {Py_sq_inplace_repeat, array_inplace_repeat}, + + /* as mapping */ + {Py_mp_length, array_length}, + {Py_mp_subscript, array_subscr}, + {Py_mp_ass_subscript, array_ass_subscr}, + + /* as buffer */ + {Py_bf_getbuffer, array_buffer_getbuf}, + {Py_bf_releasebuffer, array_buffer_relbuf}, + + {0, NULL}, +}; + +static PyType_Spec array_spec = { + .name = "array.array", + .basicsize = sizeof(arrayobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .slots = array_slots, +}; /*********************** Array Iterator **************************/ /*[clinic input] -class array.arrayiterator "arrayiterobject *" "&PyArrayIter_Type" +class array.arrayiterator "arrayiterobject *" "find_array_state_by_type(type)->ArrayIterType" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5aefd2d74d8c8e30]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=fb46d5ef98dd95ff]*/ static PyObject * array_iter(arrayobject *ao) { + array_state *state = find_array_state_by_type(Py_TYPE(ao)); arrayiterobject *it; - if (!array_Check(ao)) { + if (!array_Check(ao, state)) { PyErr_BadInternalCall(); return NULL; } - it = PyObject_GC_New(arrayiterobject, &PyArrayIter_Type); + it = PyObject_GC_New(arrayiterobject, state->ArrayIterType); if (it == NULL) return NULL; @@ -2855,12 +2872,17 @@ arrayiter_next(arrayiterobject *it) arrayobject *ao; assert(it != NULL); - assert(PyArrayIter_Check(it)); +#ifndef NDEBUG + array_state *state = find_array_state_by_type(Py_TYPE(it)); + assert(PyObject_TypeCheck(it, state->ArrayIterType)); +#endif ao = it->ao; if (ao == NULL) { return NULL; } - assert(array_Check(ao)); +#ifndef NDEBUG + assert(array_Check(ao, state)); +#endif if (it->index < Py_SIZE(ao)) { return (*it->getitem)(ao, it->index++); } @@ -2872,9 +2894,12 @@ arrayiter_next(arrayiterobject *it) static void arrayiter_dealloc(arrayiterobject *it) { + PyTypeObject *tp = Py_TYPE(it); + PyObject_GC_UnTrack(it); Py_XDECREF(it->ao); PyObject_GC_Del(it); + Py_DECREF(tp); } static int @@ -2932,36 +2957,21 @@ static PyMethodDef arrayiter_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject PyArrayIter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "arrayiterator", /* tp_name */ - sizeof(arrayiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)arrayiter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ - 0, /* tp_doc */ - (traverseproc)arrayiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)arrayiter_next, /* tp_iternext */ - arrayiter_methods, /* tp_methods */ +static PyType_Slot arrayiter_slots[] = { + {Py_tp_dealloc, arrayiter_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, arrayiter_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, arrayiter_next}, + {Py_tp_methods, arrayiter_methods}, + {0, NULL}, +}; + +static PyType_Spec arrayiter_spec = { + .name = "array.arrayiterator", + .basicsize = sizeof(arrayiterobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .slots = arrayiter_slots, }; @@ -2973,45 +2983,53 @@ static PyMethodDef a_methods[] = { {NULL, NULL, 0, NULL} /* Sentinel */ }; +#define CREATE_TYPE(module, type, spec) \ +do { \ + type = (PyTypeObject *)PyType_FromModuleAndSpec(m, spec, NULL); \ + if (type == NULL) { \ + return -1; \ + } \ +} while (0) + static int array_modexec(PyObject *m) { + array_state *state = get_array_state(m); char buffer[Py_ARRAY_LENGTH(descriptors)], *p; PyObject *typecodes; const struct arraydescr *descr; - if (PyType_Ready(&Arraytype) < 0) - return -1; - Py_SET_TYPE(&PyArrayIter_Type, &PyType_Type); + CREATE_TYPE(m, state->ArrayType, &array_spec); + CREATE_TYPE(m, state->ArrayIterType, &arrayiter_spec); + Py_SET_TYPE(state->ArrayIterType, &PyType_Type); - Py_INCREF((PyObject *)&Arraytype); - if (PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype) < 0) { - Py_DECREF((PyObject *)&Arraytype); + Py_INCREF((PyObject *)state->ArrayType); + if (PyModule_AddObject(m, "ArrayType", (PyObject *)state->ArrayType) < 0) { + Py_DECREF((PyObject *)state->ArrayType); return -1; } PyObject *abc_mod = PyImport_ImportModule("collections.abc"); if (!abc_mod) { - Py_DECREF((PyObject *)&Arraytype); + Py_DECREF((PyObject *)state->ArrayType); return -1; } PyObject *mutablesequence = PyObject_GetAttrString(abc_mod, "MutableSequence"); Py_DECREF(abc_mod); if (!mutablesequence) { - Py_DECREF((PyObject *)&Arraytype); + Py_DECREF((PyObject *)state->ArrayType); return -1; } - PyObject *res = PyObject_CallMethod(mutablesequence, "register", "O", (PyObject *)&Arraytype); + PyObject *res = PyObject_CallMethod(mutablesequence, "register", "O", + (PyObject *)state->ArrayType); Py_DECREF(mutablesequence); if (!res) { - Py_DECREF((PyObject *)&Arraytype); + Py_DECREF((PyObject *)state->ArrayType); return -1; } Py_DECREF(res); - Py_INCREF((PyObject *)&Arraytype); - if (PyModule_AddObject(m, "array", (PyObject *)&Arraytype) < 0) { - Py_DECREF((PyObject *)&Arraytype); + if (PyModule_AddType(m, state->ArrayType) < 0) { return -1; } @@ -3035,15 +3053,12 @@ static PyModuleDef_Slot arrayslots[] = { static struct PyModuleDef arraymodule = { - PyModuleDef_HEAD_INIT, - "array", - module_doc, - 0, - a_methods, - arrayslots, - NULL, - NULL, - NULL + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "array", + .m_size = sizeof(array_state), + .m_doc = module_doc, + .m_methods = a_methods, + .m_slots = arrayslots, }; diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h index 300cd1397101e8..d0b70c46ff5707 100644 --- a/Modules/clinic/arraymodule.c.h +++ b/Modules/clinic/arraymodule.c.h @@ -108,7 +108,28 @@ PyDoc_STRVAR(array_array_extend__doc__, "Append items to the end of the array."); #define ARRAY_ARRAY_EXTEND_METHODDEF \ - {"extend", (PyCFunction)array_array_extend, METH_O, array_array_extend__doc__}, + {"extend", (PyCFunction)(void(*)(void))array_array_extend, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, array_array_extend__doc__}, + +static PyObject * +array_array_extend_impl(arrayobject *self, PyTypeObject *cls, PyObject *bb); + +static PyObject * +array_array_extend(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:extend", _keywords, 0}; + PyObject *bb; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &bb)) { + goto exit; + } + return_value = array_array_extend_impl(self, cls, bb); + +exit: + return return_value; +} PyDoc_STRVAR(array_array_insert__doc__, "insert($self, i, v, /)\n" @@ -514,4 +535,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=91c1cded65a1285f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a7f71a18b994c88f input=a9049054013a1b77]*/ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy