From 369b187ac397073bbc89d2e3c8ccc8eac0b08977 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 27 Mar 2020 00:31:33 +0900 Subject: [PATCH 1/6] bpo-40077: Convert _jsonmodule to use PyType_FromSpec. --- .../2020-03-27-01-11-08.bpo-40077.wT002V.rst | 1 + Modules/_json.c | 302 ++++++++---------- 2 files changed, 143 insertions(+), 160 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-03-27-01-11-08.bpo-40077.wT002V.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-03-27-01-11-08.bpo-40077.wT002V.rst b/Misc/NEWS.d/next/Core and Builtins/2020-03-27-01-11-08.bpo-40077.wT002V.rst new file mode 100644 index 00000000000000..ab0654a5ca3ccd --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-03-27-01-11-08.bpo-40077.wT002V.rst @@ -0,0 +1 @@ +Convert json module to use :c:func:`PyType_FromSpec`. diff --git a/Modules/_json.c b/Modules/_json.c index d9346a783e40b4..1dcf07cffcc939 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -12,13 +12,19 @@ #include "structmember.h" #include "pycore_accu.h" -#define PyScanner_Check(op) PyObject_TypeCheck(op, &PyScannerType) -#define PyScanner_CheckExact(op) Py_IS_TYPE(op, &PyScannerType) -#define PyEncoder_Check(op) PyObject_TypeCheck(op, &PyEncoderType) -#define PyEncoder_CheckExact(op) Py_IS_TYPE(op, &PyEncoderType) +typedef struct { + PyObject *PyScannerType; + PyObject *PyEncoderType; +} _jsonmodulestate; + +static inline _jsonmodulestate* +get_json_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (_jsonmodulestate *)state; +} -static PyTypeObject PyScannerType; -static PyTypeObject PyEncoderType; typedef struct _PyScannerObject { PyObject_HEAD @@ -81,15 +87,15 @@ _build_rval_index_tuple(PyObject *rval, Py_ssize_t idx); static PyObject * scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static void -scanner_dealloc(PyObject *self); +scanner_dealloc(PyScannerObject *self); static int -scanner_clear(PyObject *self); +scanner_clear(PyScannerObject *self); static PyObject * encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static void -encoder_dealloc(PyObject *self); +encoder_dealloc(PyEncoderObject *self); static int -encoder_clear(PyObject *self); +encoder_clear(PyEncoderObject *self); static int encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, PyObject *seq, Py_ssize_t indent_level); static int @@ -628,40 +634,37 @@ py_encode_basestring(PyObject* Py_UNUSED(self), PyObject *pystr) } static void -scanner_dealloc(PyObject *self) +scanner_dealloc(PyScannerObject *self) { + PyTypeObject *tp = Py_TYPE(self); /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(self); scanner_clear(self); - Py_TYPE(self)->tp_free(self); + freefunc free_func = PyType_GetSlot(tp, Py_tp_free); + free_func(self); + Py_DECREF(tp); } static int -scanner_traverse(PyObject *self, visitproc visit, void *arg) +scanner_traverse(PyScannerObject *self, visitproc visit, void *arg) { - PyScannerObject *s; - assert(PyScanner_Check(self)); - s = (PyScannerObject *)self; - Py_VISIT(s->object_hook); - Py_VISIT(s->object_pairs_hook); - Py_VISIT(s->parse_float); - Py_VISIT(s->parse_int); - Py_VISIT(s->parse_constant); + Py_VISIT(self->object_hook); + Py_VISIT(self->object_pairs_hook); + Py_VISIT(self->parse_float); + Py_VISIT(self->parse_int); + Py_VISIT(self->parse_constant); return 0; } static int -scanner_clear(PyObject *self) +scanner_clear(PyScannerObject *self) { - PyScannerObject *s; - assert(PyScanner_Check(self)); - s = (PyScannerObject *)self; - Py_CLEAR(s->object_hook); - Py_CLEAR(s->object_pairs_hook); - Py_CLEAR(s->parse_float); - Py_CLEAR(s->parse_int); - Py_CLEAR(s->parse_constant); - Py_CLEAR(s->memo); + Py_CLEAR(self->object_hook); + Py_CLEAR(self->object_pairs_hook); + Py_CLEAR(self->parse_float); + Py_CLEAR(self->parse_int); + Py_CLEAR(self->parse_constant); + Py_CLEAR(self->memo); return 0; } @@ -1127,7 +1130,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ } static PyObject * -scanner_call(PyObject *self, PyObject *args, PyObject *kwds) +scanner_call(PyScannerObject *self, PyObject *args, PyObject *kwds) { /* Python callable interface to scan_once_{str,unicode} */ PyObject *pystr; @@ -1135,14 +1138,11 @@ scanner_call(PyObject *self, PyObject *args, PyObject *kwds) Py_ssize_t idx; Py_ssize_t next_idx = -1; static char *kwlist[] = {"string", "idx", NULL}; - PyScannerObject *s; - assert(PyScanner_Check(self)); - s = (PyScannerObject *)self; if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:scan_once", kwlist, &pystr, &idx)) return NULL; if (PyUnicode_Check(pystr)) { - rval = scan_once_unicode(s, pystr, idx, &next_idx); + rval = scan_once_unicode(self, pystr, idx, &next_idx); } else { PyErr_Format(PyExc_TypeError, @@ -1150,7 +1150,7 @@ scanner_call(PyObject *self, PyObject *args, PyObject *kwds) Py_TYPE(pystr)->tp_name); return NULL; } - PyDict_Clear(s->memo); + PyDict_Clear(self->memo); if (rval == NULL) return NULL; return _build_rval_index_tuple(rval, next_idx); @@ -1167,7 +1167,8 @@ scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx)) return NULL; - s = (PyScannerObject *)type->tp_alloc(type, 0); + allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc); + s = (PyScannerObject *)alloc_func(type, 0); if (s == NULL) { return NULL; } @@ -1209,47 +1210,24 @@ scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyDoc_STRVAR(scanner_doc, "JSON scanner object"); +static PyType_Slot PyScannerType_slots[] = { + {Py_tp_doc, (void *)scanner_doc}, + {Py_tp_dealloc, scanner_dealloc}, + {Py_tp_call, scanner_call}, + {Py_tp_traverse, scanner_traverse}, + {Py_tp_clear, scanner_clear}, + {Py_tp_members, scanner_members}, + {Py_tp_new, scanner_new}, + {0, 0} +}; + static -PyTypeObject PyScannerType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_json.Scanner", /* tp_name */ - sizeof(PyScannerObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - scanner_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 */ - scanner_call, /* tp_call */ - 0, /* tp_str */ - 0,/* PyObject_GenericGetAttr, */ /* tp_getattro */ - 0,/* PyObject_GenericSetAttr, */ /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - scanner_doc, /* tp_doc */ - scanner_traverse, /* tp_traverse */ - scanner_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - scanner_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0,/* PyType_GenericAlloc, */ /* tp_alloc */ - scanner_new, /* tp_new */ - 0,/* PyObject_GC_Del, */ /* tp_free */ +PyType_Spec PyScannerType_spec = { + "_json.Scanner", + sizeof(PyScannerObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + PyScannerType_slots, }; static PyObject * @@ -1275,7 +1253,8 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - s = (PyEncoderObject *)type->tp_alloc(type, 0); + allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc); + s = (PyEncoderObject *)alloc_func(type, 0); if (s == NULL) return NULL; @@ -1307,23 +1286,19 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } static PyObject * -encoder_call(PyObject *self, PyObject *args, PyObject *kwds) +encoder_call(PyEncoderObject *self, PyObject *args, PyObject *kwds) { /* Python callable interface to encode_listencode_obj */ static char *kwlist[] = {"obj", "_current_indent_level", NULL}; PyObject *obj; Py_ssize_t indent_level; - PyEncoderObject *s; _PyAccu acc; - - assert(PyEncoder_Check(self)); - s = (PyEncoderObject *)self; if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:_iterencode", kwlist, &obj, &indent_level)) return NULL; if (_PyAccu_Init(&acc)) return NULL; - if (encoder_listencode_obj(s, &acc, obj, indent_level)) { + if (encoder_listencode_obj(self, &acc, obj, indent_level)) { _PyAccu_Destroy(&acc); return NULL; } @@ -1760,88 +1735,61 @@ encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, } static void -encoder_dealloc(PyObject *self) +encoder_dealloc(PyEncoderObject *self) { + PyTypeObject *tp = Py_TYPE(self); /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(self); encoder_clear(self); - Py_TYPE(self)->tp_free(self); + freefunc free_func = PyType_GetSlot(tp, Py_tp_free); + free_func(self); + Py_DECREF(tp); } static int -encoder_traverse(PyObject *self, visitproc visit, void *arg) +encoder_traverse(PyEncoderObject *self, visitproc visit, void *arg) { - PyEncoderObject *s; - assert(PyEncoder_Check(self)); - s = (PyEncoderObject *)self; - Py_VISIT(s->markers); - Py_VISIT(s->defaultfn); - Py_VISIT(s->encoder); - Py_VISIT(s->indent); - Py_VISIT(s->key_separator); - Py_VISIT(s->item_separator); + Py_VISIT(self->markers); + Py_VISIT(self->defaultfn); + Py_VISIT(self->encoder); + Py_VISIT(self->indent); + Py_VISIT(self->key_separator); + Py_VISIT(self->item_separator); return 0; } static int -encoder_clear(PyObject *self) +encoder_clear(PyEncoderObject *self) { /* Deallocate Encoder */ - PyEncoderObject *s; - assert(PyEncoder_Check(self)); - s = (PyEncoderObject *)self; - Py_CLEAR(s->markers); - Py_CLEAR(s->defaultfn); - Py_CLEAR(s->encoder); - Py_CLEAR(s->indent); - Py_CLEAR(s->key_separator); - Py_CLEAR(s->item_separator); + Py_CLEAR(self->markers); + Py_CLEAR(self->defaultfn); + Py_CLEAR(self->encoder); + Py_CLEAR(self->indent); + Py_CLEAR(self->key_separator); + Py_CLEAR(self->item_separator); return 0; } PyDoc_STRVAR(encoder_doc, "_iterencode(obj, _current_indent_level) -> iterable"); -static -PyTypeObject PyEncoderType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_json.Encoder", /* tp_name */ - sizeof(PyEncoderObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - encoder_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 */ - encoder_call, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - encoder_doc, /* tp_doc */ - encoder_traverse, /* tp_traverse */ - encoder_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - encoder_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - encoder_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot PyEncoderType_slots[] = { + {Py_tp_doc, (void *)encoder_doc}, + {Py_tp_dealloc, encoder_dealloc}, + {Py_tp_call, encoder_call}, + {Py_tp_traverse, encoder_traverse}, + {Py_tp_clear, encoder_clear}, + {Py_tp_members, encoder_members}, + {Py_tp_new, encoder_new}, + {0, 0} +}; + +static PyType_Spec PyEncoderType_spec = { + "_json.Encoder", + sizeof(PyEncoderObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + PyEncoderType_slots }; static PyMethodDef speedups_methods[] = { @@ -1866,25 +1814,59 @@ PyDoc_STRVAR(module_doc, static int _json_exec(PyObject *module) { - if (PyType_Ready(&PyScannerType) < 0) { + PyObject *PyScannerType = PyType_FromSpec(&PyScannerType_spec); + if (PyScannerType == NULL) { return -1; } - if (PyType_Ready(&PyEncoderType) < 0) { + get_json_state(module)->PyScannerType = PyScannerType; + Py_INCREF(PyScannerType); + if (PyModule_AddObject(module, "make_scanner", get_json_state(module)->PyScannerType) < 0) { return -1; } - Py_INCREF((PyObject*)&PyScannerType); - if (PyModule_AddObject(module, "make_scanner", (PyObject*)&PyScannerType) < 0) { - Py_DECREF((PyObject*)&PyScannerType); + + PyObject *PyEncoderType = PyType_FromSpec(&PyEncoderType_spec); + if (PyEncoderType == NULL) { return -1; } - Py_INCREF((PyObject*)&PyEncoderType); - if (PyModule_AddObject(module, "make_encoder", (PyObject*)&PyEncoderType) < 0) { - Py_DECREF((PyObject*)&PyEncoderType); + get_json_state(module)->PyEncoderType = PyEncoderType; + Py_INCREF(PyEncoderType); + if (PyModule_AddObject(module, "make_encoder", get_json_state(module)->PyEncoderType) < 0) { return -1; } return 0; } +static int +_jsonmodule_traverse(PyObject *module, visitproc visit, void *arg) +{ + _jsonmodulestate *state = (_jsonmodulestate *)PyModule_GetState(module); + if (state) { + Py_VISIT(get_json_state(module)->PyScannerType); + Py_VISIT(get_json_state(module)->PyEncoderType); + } + return 0; +} + +static int +_jsonmodule_clear(PyObject *module) +{ + _jsonmodulestate *state = (_jsonmodulestate *)PyModule_GetState(module); + if (state) { + Py_CLEAR(get_json_state(module)->PyScannerType); + Py_CLEAR(get_json_state(module)->PyEncoderType); + } + return 0; +} + +static void +_jsonmodule_free(void *module) +{ + _jsonmodulestate *state = (_jsonmodulestate *)PyModule_GetState(module); + if (state) { + _jsonmodule_clear((PyObject *)module); + } +} + static PyModuleDef_Slot _json_slots[] = { {Py_mod_exec, _json_exec}, {0, NULL} @@ -1894,12 +1876,12 @@ static struct PyModuleDef jsonmodule = { PyModuleDef_HEAD_INIT, "_json", module_doc, - 0, + sizeof(_jsonmodulestate), speedups_methods, _json_slots, - NULL, - NULL, - NULL + _jsonmodule_traverse, + _jsonmodule_clear, + _jsonmodule_free, }; PyMODINIT_FUNC From 5db609a52c808b924938a1674d92a87fd060c7a6 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 27 Mar 2020 02:50:01 +0900 Subject: [PATCH 2/6] bpo-40077: Apply Victor's review part 1 --- Modules/_json.c | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/Modules/_json.c b/Modules/_json.c index 1dcf07cffcc939..30d45a980418d2 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -87,13 +87,13 @@ _build_rval_index_tuple(PyObject *rval, Py_ssize_t idx); static PyObject * scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static void -scanner_dealloc(PyScannerObject *self); +scanner_dealloc(PyObject *self); static int scanner_clear(PyScannerObject *self); static PyObject * encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static void -encoder_dealloc(PyEncoderObject *self); +encoder_dealloc(PyObject *self); static int encoder_clear(PyEncoderObject *self); static int @@ -634,14 +634,13 @@ py_encode_basestring(PyObject* Py_UNUSED(self), PyObject *pystr) } static void -scanner_dealloc(PyScannerObject *self) +scanner_dealloc(PyObject *self) { PyTypeObject *tp = Py_TYPE(self); /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(self); - scanner_clear(self); - freefunc free_func = PyType_GetSlot(tp, Py_tp_free); - free_func(self); + scanner_clear((PyScannerObject *)self); + tp->tp_free(self); Py_DECREF(tp); } @@ -1735,14 +1734,13 @@ encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, } static void -encoder_dealloc(PyEncoderObject *self) +encoder_dealloc(PyObject *self) { PyTypeObject *tp = Py_TYPE(self); /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(self); - encoder_clear(self); - freefunc free_func = PyType_GetSlot(tp, Py_tp_free); - free_func(self); + encoder_clear((PyEncoderObject *)self); + tp->tp_free(self); Py_DECREF(tp); } @@ -1821,6 +1819,7 @@ _json_exec(PyObject *module) get_json_state(module)->PyScannerType = PyScannerType; Py_INCREF(PyScannerType); if (PyModule_AddObject(module, "make_scanner", get_json_state(module)->PyScannerType) < 0) { + Py_DECREF((PyObject*)&PyScannerType); return -1; } @@ -1831,6 +1830,7 @@ _json_exec(PyObject *module) get_json_state(module)->PyEncoderType = PyEncoderType; Py_INCREF(PyEncoderType); if (PyModule_AddObject(module, "make_encoder", get_json_state(module)->PyEncoderType) < 0) { + Py_DECREF((PyObject*)&PyEncoderType); return -1; } return 0; @@ -1839,32 +1839,25 @@ _json_exec(PyObject *module) static int _jsonmodule_traverse(PyObject *module, visitproc visit, void *arg) { - _jsonmodulestate *state = (_jsonmodulestate *)PyModule_GetState(module); - if (state) { - Py_VISIT(get_json_state(module)->PyScannerType); - Py_VISIT(get_json_state(module)->PyEncoderType); - } + _jsonmodulestate *state = get_json_state(module); + Py_VISIT(state->PyScannerType); + Py_VISIT(state->PyEncoderType); return 0; } static int _jsonmodule_clear(PyObject *module) { - _jsonmodulestate *state = (_jsonmodulestate *)PyModule_GetState(module); - if (state) { - Py_CLEAR(get_json_state(module)->PyScannerType); - Py_CLEAR(get_json_state(module)->PyEncoderType); - } + _jsonmodulestate *state = get_json_state(module); + Py_CLEAR(state->PyScannerType); + Py_CLEAR(state->PyEncoderType); return 0; } static void _jsonmodule_free(void *module) { - _jsonmodulestate *state = (_jsonmodulestate *)PyModule_GetState(module); - if (state) { - _jsonmodule_clear((PyObject *)module); - } + _jsonmodule_clear((PyObject *)module); } static PyModuleDef_Slot _json_slots[] = { From e656cea462cbb56d39d0d5561d7a66e71a18ec27 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 27 Mar 2020 02:56:38 +0900 Subject: [PATCH 3/6] bpo-40077: Use C99 style --- Modules/_json.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Modules/_json.c b/Modules/_json.c index 30d45a980418d2..bf5453bec539e0 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1222,11 +1222,11 @@ static PyType_Slot PyScannerType_slots[] = { static PyType_Spec PyScannerType_spec = { - "_json.Scanner", - sizeof(PyScannerObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - PyScannerType_slots, + .name = "_json.Scanner", + .basicsize = sizeof(PyScannerObject), + .itemsize =0, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .slots = PyScannerType_slots, }; static PyObject * @@ -1783,11 +1783,11 @@ static PyType_Slot PyEncoderType_slots[] = { }; static PyType_Spec PyEncoderType_spec = { - "_json.Encoder", - sizeof(PyEncoderObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - PyEncoderType_slots + .name = "_json.Encoder", + .basicsize = sizeof(PyEncoderObject), + .itemsize = 0, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .slots = PyEncoderType_slots }; static PyMethodDef speedups_methods[] = { From e2d444df30dd4baa597eba3d9634a1ee17ffcfa3 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 27 Mar 2020 11:57:17 +0900 Subject: [PATCH 4/6] bpo-40077: Apply Victor's code review. --- Modules/_json.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/Modules/_json.c b/Modules/_json.c index bf5453bec539e0..f78d2d8cd069a7 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1166,8 +1166,7 @@ scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx)) return NULL; - allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc); - s = (PyScannerObject *)alloc_func(type, 0); + s = (PyScannerObject *)type->tp_alloc(type, 0); if (s == NULL) { return NULL; } @@ -1220,8 +1219,7 @@ static PyType_Slot PyScannerType_slots[] = { {0, 0} }; -static -PyType_Spec PyScannerType_spec = { +static PyType_Spec PyScannerType_spec = { .name = "_json.Scanner", .basicsize = sizeof(PyScannerObject), .itemsize =0, @@ -1252,8 +1250,7 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc); - s = (PyEncoderObject *)alloc_func(type, 0); + s = (PyEncoderObject *)type->tp_alloc(type, 0); if (s == NULL) return NULL; @@ -1812,27 +1809,31 @@ PyDoc_STRVAR(module_doc, static int _json_exec(PyObject *module) { - PyObject *PyScannerType = PyType_FromSpec(&PyScannerType_spec); - if (PyScannerType == NULL) { + _jsonmodulestate *state = get_json_state(module); + if (state == NULL) { return -1; } - get_json_state(module)->PyScannerType = PyScannerType; - Py_INCREF(PyScannerType); - if (PyModule_AddObject(module, "make_scanner", get_json_state(module)->PyScannerType) < 0) { - Py_DECREF((PyObject*)&PyScannerType); + + state->PyScannerType = PyType_FromSpec(&PyScannerType_spec); + if (state->PyScannerType == NULL) { + return -1; + } + Py_INCREF(state->PyScannerType); + if (PyModule_AddObject(module, "make_scanner", state->PyScannerType) < 0) { + Py_DECREF((PyObject*)state->PyScannerType); return -1; } - PyObject *PyEncoderType = PyType_FromSpec(&PyEncoderType_spec); - if (PyEncoderType == NULL) { + state->PyEncoderType = PyType_FromSpec(&PyEncoderType_spec); + if (state->PyEncoderType == NULL) { return -1; } - get_json_state(module)->PyEncoderType = PyEncoderType; - Py_INCREF(PyEncoderType); - if (PyModule_AddObject(module, "make_encoder", get_json_state(module)->PyEncoderType) < 0) { - Py_DECREF((PyObject*)&PyEncoderType); + Py_INCREF(state->PyEncoderType); + if (PyModule_AddObject(module, "make_encoder", state->PyEncoderType) < 0) { + Py_DECREF((PyObject*)state->PyEncoderType); return -1; } + return 0; } From 5b0b7b2475343ce7fa90f62f253c0e29d636ed51 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 27 Mar 2020 11:59:06 +0900 Subject: [PATCH 5/6] bpo-40077: nit --- Modules/_json.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_json.c b/Modules/_json.c index f78d2d8cd069a7..0d0ea9765eecd7 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1222,7 +1222,7 @@ static PyType_Slot PyScannerType_slots[] = { static PyType_Spec PyScannerType_spec = { .name = "_json.Scanner", .basicsize = sizeof(PyScannerObject), - .itemsize =0, + .itemsize = 0, .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .slots = PyScannerType_slots, }; From f5798c17f5163bfea58e2d527ff1bb4bb603a971 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Fri, 27 Mar 2020 15:43:29 +0900 Subject: [PATCH 6/6] bpo-40077: update --- Modules/_json.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/Modules/_json.c b/Modules/_json.c index 0d0ea9765eecd7..4682cf84621ee9 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1810,9 +1810,6 @@ static int _json_exec(PyObject *module) { _jsonmodulestate *state = get_json_state(module); - if (state == NULL) { - return -1; - } state->PyScannerType = PyType_FromSpec(&PyScannerType_spec); if (state->PyScannerType == NULL) {