From d4be68e361f4258cf0848fc70018dfe37a2acc24 Mon Sep 17 00:00:00 2001 From: shadchin Date: Mon, 18 Apr 2022 12:39:32 +0300 Subject: IGNIETFERRO-1816 Update Python 3 from 3.9.12 to 3.10.4 ref:9f96be6d02ee8044fdd6f124b799b270c20ce641 --- .../python3/src/Modules/cjkcodecs/cjkcodecs.h | 69 +-- .../Modules/cjkcodecs/clinic/multibytecodec.c.h | 12 +- .../python3/src/Modules/cjkcodecs/multibytecodec.c | 498 ++++++++++----------- .../python3/src/Modules/cjkcodecs/multibytecodec.h | 2 +- 4 files changed, 277 insertions(+), 304 deletions(-) (limited to 'contrib/tools/python3/src/Modules/cjkcodecs') diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/cjkcodecs.h b/contrib/tools/python3/src/Modules/cjkcodecs/cjkcodecs.h index e41755b197f..ba8fad26055 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/cjkcodecs.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/cjkcodecs.h @@ -245,15 +245,13 @@ static const struct dbcs_map *mapping_list; static PyObject * getmultibytecodec(void) { - static PyObject *cofunc = NULL; - - if (cofunc == NULL) { - PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec"); - if (mod == NULL) - return NULL; - cofunc = PyObject_GetAttrString(mod, "__create_codec"); - Py_DECREF(mod); + PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec"); + if (mod == NULL) { + return NULL; } + + PyObject *cofunc = PyObject_GetAttrString(mod, "__create_codec"); + Py_DECREF(mod); return cofunc; } @@ -293,14 +291,11 @@ getcodec(PyObject *self, PyObject *encoding) r = PyObject_CallOneArg(cofunc, codecobj); Py_DECREF(codecobj); + Py_DECREF(cofunc); return r; } -static struct PyMethodDef __methods[] = { - {"getcodec", (PyCFunction)getcodec, METH_O, ""}, - {NULL, NULL}, -}; static int register_maps(PyObject *module) @@ -309,12 +304,17 @@ register_maps(PyObject *module) for (h = mapping_list; h->charset[0] != '\0'; h++) { char mhname[256] = "__map_"; - int r; strcpy(mhname + sizeof("__map_") - 1, h->charset); - r = PyModule_AddObject(module, mhname, - PyCapsule_New((void *)h, PyMultibyteCodec_CAPSULE_NAME, NULL)); - if (r == -1) + + PyObject *capsule = PyCapsule_New((void *)h, + PyMultibyteCodec_CAPSULE_NAME, NULL); + if (capsule == NULL) { + return -1; + } + if (PyModule_AddObject(module, mhname, capsule) < 0) { + Py_DECREF(capsule); return -1; + } } return 0; } @@ -395,25 +395,36 @@ errorexit: } #endif +static int +_cjk_exec(PyObject *module) +{ + return register_maps(module); +} + + +static struct PyMethodDef _cjk_methods[] = { + {"getcodec", (PyCFunction)getcodec, METH_O, ""}, + {NULL, NULL}, +}; + +static PyModuleDef_Slot _cjk_slots[] = { + {Py_mod_exec, _cjk_exec}, + {0, NULL} +}; + #define I_AM_A_MODULE_FOR(loc) \ - static struct PyModuleDef __module = { \ + static struct PyModuleDef _cjk_module = { \ PyModuleDef_HEAD_INIT, \ - "_codecs_"#loc, \ - NULL, \ - 0, \ - __methods, \ - NULL, \ - NULL, \ - NULL, \ - NULL \ + .m_name = "_codecs_"#loc, \ + .m_size = 0, \ + .m_methods = _cjk_methods, \ + .m_slots = _cjk_slots, \ }; \ + \ PyMODINIT_FUNC \ PyInit__codecs_##loc(void) \ { \ - PyObject *m = PyModule_Create(&__module); \ - if (m != NULL) \ - (void)register_maps(m); \ - return m; \ + return PyModuleDef_Init(&_cjk_module); \ } #endif diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/clinic/multibytecodec.c.h b/contrib/tools/python3/src/Modules/cjkcodecs/clinic/multibytecodec.c.h index 5ddbbe221b9..563888370d0 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/clinic/multibytecodec.c.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -171,11 +171,6 @@ _multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderOb if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[1]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -288,11 +283,6 @@ _multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderOb if (!noptargs) { goto skip_optional_pos; } - if (PyFloat_Check(args[1])) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float" ); - goto exit; - } final = _PyLong_AsInt(args[1]); if (final == -1 && PyErr_Occurred()) { goto exit; @@ -525,4 +515,4 @@ PyDoc_STRVAR(_multibytecodec___create_codec__doc__, #define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \ {"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__}, -/*[clinic end generated code: output=5ce6fd4ca1f95620 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5c0f74129db07c87 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.c b/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.c index 86402768b6e..ba558d0dbf2 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.c +++ b/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.c @@ -10,11 +10,44 @@ #include "multibytecodec.h" #include "clinic/multibytecodec.c.h" +#define MODULE_NAME "_multibytecodec" + +typedef struct { + PyTypeObject *encoder_type; + PyTypeObject *decoder_type; + PyTypeObject *reader_type; + PyTypeObject *writer_type; + PyTypeObject *multibytecodec_type; +} _multibytecodec_state; + +static _multibytecodec_state * +_multibytecodec_get_state(PyObject *module) +{ + _multibytecodec_state *state = PyModule_GetState(module); + assert(state != NULL); + return state; +} + +static struct PyModuleDef _multibytecodecmodule; +static _multibytecodec_state * +_multibyte_codec_find_state_by_type(PyTypeObject *type) +{ + PyObject *module = _PyType_GetModuleByDef(type, &_multibytecodecmodule); + assert(module != NULL); + return _multibytecodec_get_state(module); +} + +#define clinic_get_state() _multibyte_codec_find_state_by_type(type) /*[clinic input] module _multibytecodec -class _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "&MultibyteCodec_Type" +class _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "clinic_get_state()->multibytecodec_type" +class _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "clinic_get_state()->encoder_type" +class _multibytecodec.MultibyteIncrementalDecoder "MultibyteIncrementalDecoderObject *" "clinic_get_state()->decoder_type" +class _multibytecodec.MultibyteStreamReader "MultibyteStreamReaderObject *" "clinic_get_state()->reader_type" +class _multibytecodec.MultibyteStreamWriter "MultibyteStreamWriterObject *" "clinic_get_state()->writer_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6ad689546cbb5450]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=305a76dfdd24b99c]*/ +#undef clinic_get_state typedef struct { PyObject *inobj; @@ -688,42 +721,36 @@ static struct PyMethodDef multibytecodec_methods[] = { {NULL, NULL}, }; +static int +multibytecodec_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + static void multibytecodec_dealloc(MultibyteCodecObject *self) { - PyObject_Del(self); + PyObject_GC_UnTrack(self); + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free(self); + Py_DECREF(tp); } -static PyTypeObject MultibyteCodec_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteCodec", /* tp_name */ - sizeof(MultibyteCodecObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)multibytecodec_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, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - multibytecodec_methods, /* tp_methods */ +static PyType_Slot multibytecodec_slots[] = { + {Py_tp_dealloc, multibytecodec_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_methods, multibytecodec_methods}, + {Py_tp_traverse, multibytecodec_traverse}, + {0, NULL}, +}; + +static PyType_Spec multibytecodec_spec = { + .name = MODULE_NAME ".MultibyteCodec", + .basicsize = sizeof(MultibyteCodecObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), + .slots = multibytecodec_slots, }; @@ -868,11 +895,6 @@ decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, } -/*[clinic input] - class _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "&MultibyteIncrementalEncoder_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3be82909cd08924d]*/ - /*[clinic input] _multibytecodec.MultibyteIncrementalEncoder.encode @@ -1024,7 +1046,9 @@ mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) codec = PyObject_GetAttrString((PyObject *)type, "codec"); if (codec == NULL) goto errorexit; - if (!MultibyteCodec_Check(codec)) { + + _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); + if (!MultibyteCodec_Check(state, codec)) { PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); goto errorexit; } @@ -1065,60 +1089,33 @@ mbiencoder_traverse(MultibyteIncrementalEncoderObject *self, static void mbiencoder_dealloc(MultibyteIncrementalEncoderObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); ERROR_DECREF(self->errors); Py_CLEAR(self->pending); - Py_TYPE(self)->tp_free(self); + tp->tp_free(self); + Py_DECREF(tp); } -static PyTypeObject MultibyteIncrementalEncoder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteIncrementalEncoder", /* tp_name */ - sizeof(MultibyteIncrementalEncoderObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)mbiencoder_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 - | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)mbiencoder_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - mbiencoder_methods, /* tp_methods */ - 0, /* tp_members */ - codecctx_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - mbiencoder_init, /* tp_init */ - 0, /* tp_alloc */ - mbiencoder_new, /* tp_new */ +static PyType_Slot encoder_slots[] = { + {Py_tp_dealloc, mbiencoder_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, mbiencoder_traverse}, + {Py_tp_methods, mbiencoder_methods}, + {Py_tp_getset, codecctx_getsets}, + {Py_tp_init, mbiencoder_init}, + {Py_tp_new, mbiencoder_new}, + {0, NULL}, }; +static PyType_Spec encoder_spec = { + .name = MODULE_NAME ".MultibyteIncrementalEncoder", + .basicsize = sizeof(MultibyteIncrementalEncoderObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = encoder_slots, +}; -/*[clinic input] - class _multibytecodec.MultibyteIncrementalDecoder "MultibyteIncrementalDecoderObject *" "&MultibyteIncrementalDecoder_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f6003faaf2cea692]*/ /*[clinic input] _multibytecodec.MultibyteIncrementalDecoder.decode @@ -1191,13 +1188,13 @@ _multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDeco goto errorexit; if (wdata != data) - PyMem_Del(wdata); + PyMem_Free(wdata); Py_XDECREF(buf.excobj); return res; errorexit: if (wdata != NULL && wdata != data) - PyMem_Del(wdata); + PyMem_Free(wdata); Py_XDECREF(buf.excobj); _PyUnicodeWriter_Dealloc(&buf.writer); return NULL; @@ -1324,7 +1321,9 @@ mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) codec = PyObject_GetAttrString((PyObject *)type, "codec"); if (codec == NULL) goto errorexit; - if (!MultibyteCodec_Check(codec)) { + + _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); + if (!MultibyteCodec_Check(state, codec)) { PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); goto errorexit; } @@ -1365,59 +1364,31 @@ mbidecoder_traverse(MultibyteIncrementalDecoderObject *self, static void mbidecoder_dealloc(MultibyteIncrementalDecoderObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); ERROR_DECREF(self->errors); - Py_TYPE(self)->tp_free(self); + tp->tp_free(self); + Py_DECREF(tp); } -static PyTypeObject MultibyteIncrementalDecoder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteIncrementalDecoder", /* tp_name */ - sizeof(MultibyteIncrementalDecoderObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)mbidecoder_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 - | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)mbidecoder_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - mbidecoder_methods, /* tp_methods */ - 0, /* tp_members */ - codecctx_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - mbidecoder_init, /* tp_init */ - 0, /* tp_alloc */ - mbidecoder_new, /* tp_new */ +static PyType_Slot decoder_slots[] = { + {Py_tp_dealloc, mbidecoder_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, mbidecoder_traverse}, + {Py_tp_methods, mbidecoder_methods}, + {Py_tp_getset, codecctx_getsets}, + {Py_tp_init, mbidecoder_init}, + {Py_tp_new, mbidecoder_new}, + {0, NULL}, }; - -/*[clinic input] - class _multibytecodec.MultibyteStreamReader "MultibyteStreamReaderObject *" "MultibyteStreamReader_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d323634b74976f09]*/ +static PyType_Spec decoder_spec = { + .name = MODULE_NAME ".MultibyteIncrementalDecoder", + .basicsize = sizeof(MultibyteIncrementalDecoderObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = decoder_slots, +}; static PyObject * mbstreamreader_iread(MultibyteStreamReaderObject *self, @@ -1667,7 +1638,9 @@ mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) codec = PyObject_GetAttrString((PyObject *)type, "codec"); if (codec == NULL) goto errorexit; - if (!MultibyteCodec_Check(codec)) { + + _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); + if (!MultibyteCodec_Check(state, codec)) { PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); goto errorexit; } @@ -1711,60 +1684,33 @@ mbstreamreader_traverse(MultibyteStreamReaderObject *self, static void mbstreamreader_dealloc(MultibyteStreamReaderObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); ERROR_DECREF(self->errors); Py_XDECREF(self->stream); - Py_TYPE(self)->tp_free(self); + tp->tp_free(self); + Py_DECREF(tp); } -static PyTypeObject MultibyteStreamReader_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteStreamReader", /* tp_name */ - sizeof(MultibyteStreamReaderObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)mbstreamreader_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 - | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)mbstreamreader_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - mbstreamreader_methods, /* tp_methods */ - mbstreamreader_members, /* tp_members */ - codecctx_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - mbstreamreader_init, /* tp_init */ - 0, /* tp_alloc */ - mbstreamreader_new, /* tp_new */ +static PyType_Slot reader_slots[] = { + {Py_tp_dealloc, mbstreamreader_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, mbstreamreader_traverse}, + {Py_tp_methods, mbstreamreader_methods}, + {Py_tp_members, mbstreamreader_members}, + {Py_tp_getset, codecctx_getsets}, + {Py_tp_init, mbstreamreader_init}, + {Py_tp_new, mbstreamreader_new}, + {0, NULL}, }; - -/*[clinic input] - class _multibytecodec.MultibyteStreamWriter "MultibyteStreamWriterObject *" "&MultibyteStreamWriter_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cde22780a215d6ac]*/ +static PyType_Spec reader_spec = { + .name = MODULE_NAME ".MultibyteStreamReader", + .basicsize = sizeof(MultibyteStreamReaderObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = reader_slots, +}; static int mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, @@ -1899,7 +1845,9 @@ mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) codec = PyObject_GetAttrString((PyObject *)type, "codec"); if (codec == NULL) goto errorexit; - if (!MultibyteCodec_Check(codec)) { + + _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); + if (!MultibyteCodec_Check(state, codec)) { PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); goto errorexit; } @@ -1943,10 +1891,12 @@ mbstreamwriter_traverse(MultibyteStreamWriterObject *self, static void mbstreamwriter_dealloc(MultibyteStreamWriterObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); ERROR_DECREF(self->errors); Py_XDECREF(self->stream); - Py_TYPE(self)->tp_free(self); + tp->tp_free(self); + Py_DECREF(tp); } static struct PyMethodDef mbstreamwriter_methods[] = { @@ -1963,47 +1913,24 @@ static PyMemberDef mbstreamwriter_members[] = { {NULL,} }; -static PyTypeObject MultibyteStreamWriter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MultibyteStreamWriter", /* tp_name */ - sizeof(MultibyteStreamWriterObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)mbstreamwriter_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 - | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)mbstreamwriter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iterext */ - mbstreamwriter_methods, /* tp_methods */ - mbstreamwriter_members, /* tp_members */ - codecctx_getsets, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - mbstreamwriter_init, /* tp_init */ - 0, /* tp_alloc */ - mbstreamwriter_new, /* tp_new */ +static PyType_Slot writer_slots[] = { + {Py_tp_dealloc, mbstreamwriter_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, mbstreamwriter_traverse}, + {Py_tp_methods, mbstreamwriter_methods}, + {Py_tp_members, mbstreamwriter_members}, + {Py_tp_getset, codecctx_getsets}, + {Py_tp_init, mbstreamwriter_init}, + {Py_tp_new, mbstreamwriter_new}, + {0, NULL}, +}; + +static PyType_Spec writer_spec = { + .name = MODULE_NAME ".MultibyteStreamWriter", + .basicsize = sizeof(MultibyteStreamWriterObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = writer_slots, }; @@ -2030,59 +1957,104 @@ _multibytecodec___create_codec(PyObject *module, PyObject *arg) if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0) return NULL; - self = PyObject_New(MultibyteCodecObject, &MultibyteCodec_Type); + _multibytecodec_state *state = _multibytecodec_get_state(module); + self = PyObject_GC_New(MultibyteCodecObject, state->multibytecodec_type); if (self == NULL) return NULL; self->codec = codec; + PyObject_GC_Track(self); return (PyObject *)self; } -static struct PyMethodDef __methods[] = { +static int +_multibytecodec_traverse(PyObject *mod, visitproc visit, void *arg) +{ + _multibytecodec_state *state = _multibytecodec_get_state(mod); + Py_VISIT(state->multibytecodec_type); + Py_VISIT(state->encoder_type); + Py_VISIT(state->decoder_type); + Py_VISIT(state->reader_type); + Py_VISIT(state->writer_type); + return 0; +} + +static int +_multibytecodec_clear(PyObject *mod) +{ + _multibytecodec_state *state = _multibytecodec_get_state(mod); + Py_CLEAR(state->multibytecodec_type); + Py_CLEAR(state->encoder_type); + Py_CLEAR(state->decoder_type); + Py_CLEAR(state->reader_type); + Py_CLEAR(state->writer_type); + return 0; +} + +static void +_multibytecodec_free(void *mod) +{ + _multibytecodec_clear((PyObject *)mod); +} + +#define CREATE_TYPE(module, type, spec) \ + do { \ + type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \ + if (!type) { \ + return -1; \ + } \ + } while (0) + +#define ADD_TYPE(module, type) \ + do { \ + if (PyModule_AddType(module, type) < 0) { \ + return -1; \ + } \ + } while (0) + +static int +_multibytecodec_exec(PyObject *mod) +{ + _multibytecodec_state *state = _multibytecodec_get_state(mod); + CREATE_TYPE(mod, state->multibytecodec_type, &multibytecodec_spec); + CREATE_TYPE(mod, state->encoder_type, &encoder_spec); + CREATE_TYPE(mod, state->decoder_type, &decoder_spec); + CREATE_TYPE(mod, state->reader_type, &reader_spec); + CREATE_TYPE(mod, state->writer_type, &writer_spec); + + ADD_TYPE(mod, state->encoder_type); + ADD_TYPE(mod, state->decoder_type); + ADD_TYPE(mod, state->reader_type); + ADD_TYPE(mod, state->writer_type); + return 0; +} + +#undef CREATE_TYPE +#undef ADD_TYPE + +static struct PyMethodDef _multibytecodec_methods[] = { _MULTIBYTECODEC___CREATE_CODEC_METHODDEF {NULL, NULL}, }; +static PyModuleDef_Slot _multibytecodec_slots[] = { + {Py_mod_exec, _multibytecodec_exec}, + {0, NULL} +}; static struct PyModuleDef _multibytecodecmodule = { - PyModuleDef_HEAD_INIT, - "_multibytecodec", - NULL, - -1, - __methods, - NULL, - NULL, - NULL, - NULL + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_multibytecodec", + .m_size = sizeof(_multibytecodec_state), + .m_methods = _multibytecodec_methods, + .m_slots = _multibytecodec_slots, + .m_traverse = _multibytecodec_traverse, + .m_clear = _multibytecodec_clear, + .m_free = _multibytecodec_free, }; PyMODINIT_FUNC PyInit__multibytecodec(void) { - PyObject *m; - PyTypeObject *typelist[] = { - &MultibyteIncrementalEncoder_Type, - &MultibyteIncrementalDecoder_Type, - &MultibyteStreamReader_Type, - &MultibyteStreamWriter_Type - }; - - if (PyType_Ready(&MultibyteCodec_Type) < 0) - return NULL; - - m = PyModule_Create(&_multibytecodecmodule); - if (m == NULL) - return NULL; - - for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { - if (PyModule_AddType(m, typelist[i]) < 0) { - return NULL; - } - } - - if (PyErr_Occurred()) { - Py_DECREF(m); - m = NULL; - } - return m; + return PyModuleDef_Init(&_multibytecodecmodule); } diff --git a/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.h b/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.h index 59468210b97..69404ba96aa 100644 --- a/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.h +++ b/contrib/tools/python3/src/Modules/cjkcodecs/multibytecodec.h @@ -65,7 +65,7 @@ typedef struct { MultibyteCodec *codec; } MultibyteCodecObject; -#define MultibyteCodec_Check(op) Py_IS_TYPE((op), &MultibyteCodec_Type) +#define MultibyteCodec_Check(state, op) Py_IS_TYPE((op), state->multibytecodec_type) #define _MultibyteStatefulCodec_HEAD \ PyObject_HEAD \ -- cgit v1.3