From 863d9748857c41a9cac350e7ad77b7240ad30727 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 13:48:38 +0100 Subject: [PATCH 01/17] Add empty module state --- Modules/cjkcodecs/multibytecodec.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 9208b86b0c9055..ae04e9f99e136c 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -10,6 +10,9 @@ #include "multibytecodec.h" #include "clinic/multibytecodec.c.h" +typedef struct { +} _multibytecodec_state; + /*[clinic input] module _multibytecodec class _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "&MultibyteCodec_Type" @@ -2045,15 +2048,10 @@ static struct PyMethodDef __methods[] = { 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 = __methods, }; PyMODINIT_FUNC From c2c8b0477d7e067898bf7b8fa53b0d105e001f89 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 14:06:55 +0100 Subject: [PATCH 02/17] Convert encoder and decoder types to heap type --- Modules/cjkcodecs/multibytecodec.c | 184 ++++++++++++++--------------- 1 file changed, 86 insertions(+), 98 deletions(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index ae04e9f99e136c..0136f4dba2d29e 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -11,8 +11,22 @@ #include "clinic/multibytecodec.c.h" typedef struct { + PyTypeObject *encoder_type; + PyTypeObject *decoder_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; +#define clinic_get_state() \ + (_multibytecodec_get_state(_PyType_GetModuleByDef(type, &_multibytecodecmodule))) + /*[clinic input] module _multibytecodec class _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "&MultibyteCodec_Type" @@ -872,9 +886,9 @@ decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, /*[clinic input] - class _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "&MultibyteIncrementalEncoder_Type" + class _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "clinic_get_state()->encoder_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3be82909cd08924d]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=fce269303b813c06]*/ /*[clinic input] _multibytecodec.MultibyteIncrementalEncoder.encode @@ -1068,60 +1082,37 @@ 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 = "MultibyteIncrementalEncoder", + .basicsize = sizeof(MultibyteIncrementalEncoderObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + .slots = encoder_slots, }; /*[clinic input] - class _multibytecodec.MultibyteIncrementalDecoder "MultibyteIncrementalDecoderObject *" "&MultibyteIncrementalDecoder_Type" + class _multibytecodec.MultibyteIncrementalDecoder "MultibyteIncrementalDecoderObject *" "clinic_get_state()->decoder_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f6003faaf2cea692]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a237fd1042be76c8]*/ /*[clinic input] _multibytecodec.MultibyteIncrementalDecoder.decode @@ -1368,52 +1359,29 @@ 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}, +}; + +static PyType_Spec decoder_spec = { + .name = "MultibyteIncrementalDecoder", + .basicsize = sizeof(MultibyteIncrementalDecoderObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + .slots = decoder_slots, }; @@ -2054,33 +2022,53 @@ static struct PyModuleDef _multibytecodecmodule = { .m_methods = __methods, }; +#define CREATE_TYPE(module, type, spec) \ +do { \ + type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \ + if (!type) { \ + goto error; \ + } \ +} while (0) + +#define ADD_TYPE(module, type) \ +do { \ + if (PyModule_AddType(module, type) < 0) { \ + goto error; \ + } \ +} while (0) + PyMODINIT_FUNC PyInit__multibytecodec(void) { - PyObject *m; + PyObject *m = NULL; PyTypeObject *typelist[] = { - &MultibyteIncrementalEncoder_Type, - &MultibyteIncrementalDecoder_Type, &MultibyteStreamReader_Type, &MultibyteStreamWriter_Type }; if (PyType_Ready(&MultibyteCodec_Type) < 0) - return NULL; + goto error; m = PyModule_Create(&_multibytecodecmodule); if (m == NULL) - return NULL; + goto error; + + _multibytecodec_state *state = _multibytecodec_get_state(m); + CREATE_TYPE(m, state->encoder_type, &encoder_spec); + CREATE_TYPE(m, state->decoder_type, &decoder_spec); + + ADD_TYPE(m, state->encoder_type); + ADD_TYPE(m, state->decoder_type); for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { if (PyModule_AddType(m, typelist[i]) < 0) { - return NULL; + goto error; } } - if (PyErr_Occurred()) { - Py_DECREF(m); - m = NULL; - } return m; + +error: + Py_XDECREF(m); + return NULL; } From 2e7e452d536f66251c5668b49414758b001d6a16 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 14:16:39 +0100 Subject: [PATCH 03/17] Convert reader and writer types to heap type --- Modules/cjkcodecs/multibytecodec.c | 148 ++++++++++------------------- 1 file changed, 50 insertions(+), 98 deletions(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 0136f4dba2d29e..e13d4d0345c84e 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -13,6 +13,8 @@ typedef struct { PyTypeObject *encoder_type; PyTypeObject *decoder_type; + PyTypeObject *reader_type; + PyTypeObject *writer_type; } _multibytecodec_state; static _multibytecodec_state * @@ -1386,9 +1388,9 @@ static PyType_Spec decoder_spec = { /*[clinic input] - class _multibytecodec.MultibyteStreamReader "MultibyteStreamReaderObject *" "MultibyteStreamReader_Type" + class _multibytecodec.MultibyteStreamReader "MultibyteStreamReaderObject *" "clinic_get_state()->reader_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d323634b74976f09]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8d4b82105d531fce]*/ static PyObject * mbstreamreader_iread(MultibyteStreamReaderObject *self, @@ -1682,60 +1684,38 @@ 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}, +}; + +static PyType_Spec reader_spec = { + .name = "MultibyteStreamReader", + .basicsize = sizeof(MultibyteStreamReaderObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + .slots = reader_slots, }; /*[clinic input] - class _multibytecodec.MultibyteStreamWriter "MultibyteStreamWriterObject *" "&MultibyteStreamWriter_Type" + class _multibytecodec.MultibyteStreamWriter "MultibyteStreamWriterObject *" "clinic_get_state()->writer_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cde22780a215d6ac]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2f5c85659ad82e8c]*/ static int mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, @@ -1914,10 +1894,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[] = { @@ -1934,47 +1916,23 @@ 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 = "MultibyteStreamWriter", + .basicsize = sizeof(MultibyteStreamWriterObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + .slots = writer_slots, }; @@ -2041,10 +1999,6 @@ PyMODINIT_FUNC PyInit__multibytecodec(void) { PyObject *m = NULL; - PyTypeObject *typelist[] = { - &MultibyteStreamReader_Type, - &MultibyteStreamWriter_Type - }; if (PyType_Ready(&MultibyteCodec_Type) < 0) goto error; @@ -2056,15 +2010,13 @@ PyInit__multibytecodec(void) _multibytecodec_state *state = _multibytecodec_get_state(m); CREATE_TYPE(m, state->encoder_type, &encoder_spec); CREATE_TYPE(m, state->decoder_type, &decoder_spec); + CREATE_TYPE(m, state->reader_type, &reader_spec); + CREATE_TYPE(m, state->writer_type, &writer_spec); ADD_TYPE(m, state->encoder_type); ADD_TYPE(m, state->decoder_type); - - for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { - if (PyModule_AddType(m, typelist[i]) < 0) { - goto error; - } - } + ADD_TYPE(m, state->reader_type); + ADD_TYPE(m, state->writer_type); return m; From 5eb463f7c4a7d0b2e4cc351371ceccb8e349b939 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 14:24:48 +0100 Subject: [PATCH 04/17] Convert multibytecode type to heap type --- Modules/cjkcodecs/multibytecodec.c | 86 ++++++++++++++---------------- Modules/cjkcodecs/multibytecodec.h | 2 +- 2 files changed, 42 insertions(+), 46 deletions(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index e13d4d0345c84e..6c496c23ac9257 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -15,6 +15,7 @@ typedef struct { PyTypeObject *decoder_type; PyTypeObject *reader_type; PyTypeObject *writer_type; + PyTypeObject *multibytecodec_type; } _multibytecodec_state; static _multibytecodec_state * @@ -26,14 +27,20 @@ _multibytecodec_get_state(PyObject *module) } static struct PyModuleDef _multibytecodecmodule; -#define clinic_get_state() \ - (_multibytecodec_get_state(_PyType_GetModuleByDef(type, &_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" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6ad689546cbb5450]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=10de8b4f74379258]*/ typedef struct { PyObject *inobj; @@ -710,39 +717,23 @@ static struct PyMethodDef multibytecodec_methods[] = { static void multibytecodec_dealloc(MultibyteCodecObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_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}, + {0, NULL}, +}; + +static PyType_Spec multibytecodec_spec = { + .name = "MultibyteCodec", + .basicsize = sizeof(MultibyteCodecObject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = multibytecodec_slots, }; @@ -1043,7 +1034,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; } @@ -1320,7 +1313,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; } @@ -1640,7 +1635,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; } @@ -1850,7 +1847,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; } @@ -1959,7 +1958,8 @@ _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_New(MultibyteCodecObject, state->multibytecodec_type); if (self == NULL) return NULL; self->codec = codec; @@ -1998,16 +1998,12 @@ do { \ PyMODINIT_FUNC PyInit__multibytecodec(void) { - PyObject *m = NULL; - - if (PyType_Ready(&MultibyteCodec_Type) < 0) - goto error; - - m = PyModule_Create(&_multibytecodecmodule); + PyObject *m = PyModule_Create(&_multibytecodecmodule); if (m == NULL) goto error; _multibytecodec_state *state = _multibytecodec_get_state(m); + CREATE_TYPE(m, state->multibytecodec_type, &multibytecodec_spec); CREATE_TYPE(m, state->encoder_type, &encoder_spec); CREATE_TYPE(m, state->decoder_type, &decoder_spec); CREATE_TYPE(m, state->reader_type, &reader_spec); diff --git a/Modules/cjkcodecs/multibytecodec.h b/Modules/cjkcodecs/multibytecodec.h index 59468210b970c8..69404ba96aa1f0 100644 --- a/Modules/cjkcodecs/multibytecodec.h +++ b/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 \ From 85ed3378fee5824e18b41285c91adb4cd200ebdd Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 14:56:19 +0100 Subject: [PATCH 05/17] Support multi-phase init --- Modules/cjkcodecs/multibytecodec.c | 101 +++++++++++++++++++---------- 1 file changed, 68 insertions(+), 33 deletions(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 6c496c23ac9257..1412bda59fb74d 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -1967,56 +1967,91 @@ _multibytecodec___create_codec(PyObject *module, PyObject *arg) return (PyObject *)self; } -static struct PyMethodDef __methods[] = { - _MULTIBYTECODEC___CREATE_CODEC_METHODDEF - {NULL, NULL}, -}; +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 struct PyModuleDef _multibytecodecmodule = { - .m_base = PyModuleDef_HEAD_INIT, - .m_name = "_multibytecodec", - .m_size = sizeof(_multibytecodec_state), - .m_methods = __methods, -}; +static void +_multibytecodec_free(void *m) +{ + _multibytecodec_clear((PyObject *)m); +} #define CREATE_TYPE(module, type, spec) \ do { \ type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \ if (!type) { \ - goto error; \ + return -1; \ } \ } while (0) #define ADD_TYPE(module, type) \ do { \ if (PyModule_AddType(module, type) < 0) { \ - goto error; \ + 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; +} + +static struct PyMethodDef __methods[] = { + _MULTIBYTECODEC___CREATE_CODEC_METHODDEF + {NULL, NULL}, +}; + +static PyModuleDef_Slot _multibytecodec_slots[] = { + {Py_mod_exec, _multibytecodec_exec}, + {0, NULL} +}; + +static struct PyModuleDef _multibytecodecmodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_multibytecodec", + .m_size = sizeof(_multibytecodec_state), + .m_methods = __methods, + .m_slots = _multibytecodec_slots, + .m_traverse = _multibytecodec_traverse, + .m_clear = _multibytecodec_clear, + .m_free = _multibytecodec_free, +}; + PyMODINIT_FUNC PyInit__multibytecodec(void) { - PyObject *m = PyModule_Create(&_multibytecodecmodule); - if (m == NULL) - goto error; - - _multibytecodec_state *state = _multibytecodec_get_state(m); - CREATE_TYPE(m, state->multibytecodec_type, &multibytecodec_spec); - CREATE_TYPE(m, state->encoder_type, &encoder_spec); - CREATE_TYPE(m, state->decoder_type, &decoder_spec); - CREATE_TYPE(m, state->reader_type, &reader_spec); - CREATE_TYPE(m, state->writer_type, &writer_spec); - - ADD_TYPE(m, state->encoder_type); - ADD_TYPE(m, state->decoder_type); - ADD_TYPE(m, state->reader_type); - ADD_TYPE(m, state->writer_type); - - return m; - -error: - Py_XDECREF(m); - return NULL; + return PyModuleDef_Init(&_multibytecodecmodule); } From f30a0962d4b708834218e457193fa61bb3ab74bc Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 15:05:45 +0100 Subject: [PATCH 06/17] Add NEWS --- .../next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst diff --git a/Misc/NEWS.d/next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst b/Misc/NEWS.d/next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst new file mode 100644 index 00000000000000..f35af2666c1bb2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst @@ -0,0 +1,2 @@ +Convert :mod:`multibytecodec` to multi-phase init and module state. Patch by +Erlend E. Aasland. From 1c9e8ba45d4935f978c03b5fe61cf40f1593dddc Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 15:27:21 +0100 Subject: [PATCH 07/17] Fix type names --- Modules/cjkcodecs/multibytecodec.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 1412bda59fb74d..0c1d867ce0c627 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -730,7 +730,7 @@ static PyType_Slot multibytecodec_slots[] = { }; static PyType_Spec multibytecodec_spec = { - .name = "MultibyteCodec", + .name = "_multibytecodec.MultibyteCodec", .basicsize = sizeof(MultibyteCodecObject), .flags = Py_TPFLAGS_DEFAULT, .slots = multibytecodec_slots, @@ -1097,7 +1097,7 @@ static PyType_Slot encoder_slots[] = { }; static PyType_Spec encoder_spec = { - .name = "MultibyteIncrementalEncoder", + .name = "_multibytecodec.MultibyteIncrementalEncoder", .basicsize = sizeof(MultibyteIncrementalEncoderObject), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, .slots = encoder_slots, @@ -1375,7 +1375,7 @@ static PyType_Slot decoder_slots[] = { }; static PyType_Spec decoder_spec = { - .name = "MultibyteIncrementalDecoder", + .name = "_multibytecodec.MultibyteIncrementalDecoder", .basicsize = sizeof(MultibyteIncrementalDecoderObject), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, .slots = decoder_slots, @@ -1702,7 +1702,7 @@ static PyType_Slot reader_slots[] = { }; static PyType_Spec reader_spec = { - .name = "MultibyteStreamReader", + .name = "_multibytecodec.MultibyteStreamReader", .basicsize = sizeof(MultibyteStreamReaderObject), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, .slots = reader_slots, @@ -1928,7 +1928,7 @@ static PyType_Slot writer_slots[] = { }; static PyType_Spec writer_spec = { - .name = "MultibyteStreamWriter", + .name = "_multibytecodec.MultibyteStreamWriter", .basicsize = sizeof(MultibyteStreamWriterObject), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, .slots = writer_slots, From dc7371388b9b4714ccc07eadf835a7535f064bd4 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 20:17:52 +0100 Subject: [PATCH 08/17] Address review: Improve NEWS text --- .../next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst b/Misc/NEWS.d/next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst index f35af2666c1bb2..85c026bd82f19a 100644 --- a/Misc/NEWS.d/next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst +++ b/Misc/NEWS.d/next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst @@ -1,2 +1,2 @@ -Convert :mod:`multibytecodec` to multi-phase init and module state. Patch by -Erlend E. Aasland. +Convert :mod:`multibytecodec` to multi-phase initialization (:pep:`489`). +Patch by Erlend E. Aasland. From 1b5b9fdaac7a42034758b5ba632e71be106b9d2e Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 20:19:03 +0100 Subject: [PATCH 09/17] Address review: Improve naming --- Modules/cjkcodecs/multibytecodec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 0c1d867ce0c627..02fb564b7e25ec 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -1992,9 +1992,9 @@ _multibytecodec_clear(PyObject *mod) } static void -_multibytecodec_free(void *m) +_multibytecodec_free(void *mod) { - _multibytecodec_clear((PyObject *)m); + _multibytecodec_clear((PyObject *)mod); } #define CREATE_TYPE(module, type, spec) \ From 94c15cba11292bc3bb4440c5d15ef0bb2c9b6c6a Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 21:44:34 +0100 Subject: [PATCH 10/17] Address review: Add MODULE_NAME macro --- Modules/cjkcodecs/multibytecodec.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 02fb564b7e25ec..098465956c2136 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -10,6 +10,8 @@ #include "multibytecodec.h" #include "clinic/multibytecodec.c.h" +#define MODULE_NAME "_multibytecodec" + typedef struct { PyTypeObject *encoder_type; PyTypeObject *decoder_type; @@ -730,7 +732,7 @@ static PyType_Slot multibytecodec_slots[] = { }; static PyType_Spec multibytecodec_spec = { - .name = "_multibytecodec.MultibyteCodec", + .name = MODULE_NAME ".MultibyteCodec", .basicsize = sizeof(MultibyteCodecObject), .flags = Py_TPFLAGS_DEFAULT, .slots = multibytecodec_slots, @@ -1097,7 +1099,7 @@ static PyType_Slot encoder_slots[] = { }; static PyType_Spec encoder_spec = { - .name = "_multibytecodec.MultibyteIncrementalEncoder", + .name = MODULE_NAME ".MultibyteIncrementalEncoder", .basicsize = sizeof(MultibyteIncrementalEncoderObject), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, .slots = encoder_slots, @@ -1375,7 +1377,7 @@ static PyType_Slot decoder_slots[] = { }; static PyType_Spec decoder_spec = { - .name = "_multibytecodec.MultibyteIncrementalDecoder", + .name = MODULE_NAME ".MultibyteIncrementalDecoder", .basicsize = sizeof(MultibyteIncrementalDecoderObject), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, .slots = decoder_slots, @@ -1702,7 +1704,7 @@ static PyType_Slot reader_slots[] = { }; static PyType_Spec reader_spec = { - .name = "_multibytecodec.MultibyteStreamReader", + .name = MODULE_NAME ".MultibyteStreamReader", .basicsize = sizeof(MultibyteStreamReaderObject), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, .slots = reader_slots, @@ -1928,7 +1930,7 @@ static PyType_Slot writer_slots[] = { }; static PyType_Spec writer_spec = { - .name = "_multibytecodec.MultibyteStreamWriter", + .name = MODULE_NAME ".MultibyteStreamWriter", .basicsize = sizeof(MultibyteStreamWriterObject), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, .slots = writer_slots, From 15205cf32581d998a1f8504bfbc3b1af4dd75806 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 21:45:16 +0100 Subject: [PATCH 11/17] Address review: Fix macro indent --- Modules/cjkcodecs/multibytecodec.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 098465956c2136..8c3d8b77197997 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -1999,20 +1999,20 @@ _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) +#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) From 6bae5b1d92d6b1b0f753c86ccf0f85a3b0e3bbce Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Mon, 4 Jan 2021 21:40:59 +0100 Subject: [PATCH 12/17] Update Modules/cjkcodecs/multibytecodec.c Co-authored-by: Victor Stinner --- Modules/cjkcodecs/multibytecodec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 8c3d8b77197997..cc7fb89821d852 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -40,7 +40,7 @@ _multibyte_codec_find_state_by_type(PyTypeObject *type) /*[clinic input] module _multibytecodec -class _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "clinic_get_state->multibytecodec_type" +class _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "clinic_get_state()->multibytecodec_type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=10de8b4f74379258]*/ From b1f3f3b002eb31edaef59f2b9c7ee49b0f921dda Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 21:50:42 +0100 Subject: [PATCH 13/17] Address review: undef ADD_TYPE and CREATE_TYPE macros to better show their scope --- Modules/cjkcodecs/multibytecodec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index cc7fb89821d852..731cb6c85e6c6c 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -2031,6 +2031,9 @@ _multibytecodec_exec(PyObject *mod) return 0; } +#undef CREATE_TYPE +#undef ADD_TYPE + static struct PyMethodDef __methods[] = { _MULTIBYTECODEC___CREATE_CODEC_METHODDEF {NULL, NULL}, From e8b302113dcaef81ec083a9765304479c70b7399 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 21:52:10 +0100 Subject: [PATCH 14/17] Collect AC def's and scope clinic_get_state() --- Modules/cjkcodecs/multibytecodec.c | 31 +++++++----------------------- 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 731cb6c85e6c6c..51ec85d5ac2b78 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -36,13 +36,18 @@ _multibyte_codec_find_state_by_type(PyTypeObject *type) assert(module != NULL); return _multibytecodec_get_state(module); } -#define clinic_get_state() _multibyte_codec_find_state_by_type(type) +#define clinic_get_state() _multibyte_codec_find_state_by_type(type) /*[clinic input] module _multibytecodec 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=10de8b4f74379258]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=305a76dfdd24b99c]*/ +#undef clinic_get_state typedef struct { PyObject *inobj; @@ -880,11 +885,6 @@ decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, } -/*[clinic input] - class _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "clinic_get_state()->encoder_type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=fce269303b813c06]*/ - /*[clinic input] _multibytecodec.MultibyteIncrementalEncoder.encode @@ -1106,11 +1106,6 @@ static PyType_Spec encoder_spec = { }; -/*[clinic input] - class _multibytecodec.MultibyteIncrementalDecoder "MultibyteIncrementalDecoderObject *" "clinic_get_state()->decoder_type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a237fd1042be76c8]*/ - /*[clinic input] _multibytecodec.MultibyteIncrementalDecoder.decode @@ -1383,12 +1378,6 @@ static PyType_Spec decoder_spec = { .slots = decoder_slots, }; - -/*[clinic input] - class _multibytecodec.MultibyteStreamReader "MultibyteStreamReaderObject *" "clinic_get_state()->reader_type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8d4b82105d531fce]*/ - static PyObject * mbstreamreader_iread(MultibyteStreamReaderObject *self, const char *method, Py_ssize_t sizehint) @@ -1710,12 +1699,6 @@ static PyType_Spec reader_spec = { .slots = reader_slots, }; - -/*[clinic input] - class _multibytecodec.MultibyteStreamWriter "MultibyteStreamWriterObject *" "clinic_get_state()->writer_type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2f5c85659ad82e8c]*/ - static int mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, PyObject *unistr) From 883f766f0aa9c4e66f076ac655d4748c48719ad3 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 21:57:27 +0100 Subject: [PATCH 15/17] Address review: Improve NEWS again --- .../next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst b/Misc/NEWS.d/next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst index 85c026bd82f19a..7ba9a53ddf9009 100644 --- a/Misc/NEWS.d/next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst +++ b/Misc/NEWS.d/next/Library/2021-01-04-15-05-40.bpo-1635741.EOCfZY.rst @@ -1,2 +1,2 @@ -Convert :mod:`multibytecodec` to multi-phase initialization (:pep:`489`). -Patch by Erlend E. Aasland. +Convert the _multibytecodec extension module (CJK codecs) to multi-phase +initialization (:pep:`489`). Patch by Erlend E. Aasland. From 18c18296b01ff04a5ab87ffbe0e4f157a6a5204b Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Mon, 4 Jan 2021 22:08:09 +0100 Subject: [PATCH 16/17] Rename __methods to _multibytecodec_methods for consistency Co-authored-by: Victor Stinner --- Modules/cjkcodecs/multibytecodec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 51ec85d5ac2b78..5466e0dc20161a 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -2031,7 +2031,7 @@ static struct PyModuleDef _multibytecodecmodule = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "_multibytecodec", .m_size = sizeof(_multibytecodec_state), - .m_methods = __methods, + .m_methods = _multibytecodec_methods, .m_slots = _multibytecodec_slots, .m_traverse = _multibytecodec_traverse, .m_clear = _multibytecodec_clear, From bf3da940b1407e3f209782bd449016f691c58188 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 4 Jan 2021 22:09:16 +0100 Subject: [PATCH 17/17] Fix rename --- Modules/cjkcodecs/multibytecodec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 5466e0dc20161a..4f34b8a82fb94d 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -2017,7 +2017,7 @@ _multibytecodec_exec(PyObject *mod) #undef CREATE_TYPE #undef ADD_TYPE -static struct PyMethodDef __methods[] = { +static struct PyMethodDef _multibytecodec_methods[] = { _MULTIBYTECODEC___CREATE_CODEC_METHODDEF {NULL, NULL}, };