From a7f026870d2dab7015a94e287bec6dd46cdbf604 Mon Sep 17 00:00:00 2001 From: Mohamed Koubaa Date: Wed, 2 Sep 2020 04:45:13 -0500 Subject: bpo-1635741: Port _blake2 module to multi-phase init (GH-21856) Port the _blake2 extension module to the multi-phase initialization API (PEP 489). --- .../2020-08-13-07-18-05.bpo-1635741.FC13e7.rst | 1 + Modules/_blake2/blake2b_impl.c | 57 +++------- Modules/_blake2/blake2module.c | 121 ++++++++++++++------- Modules/_blake2/blake2s_impl.c | 58 +++------- 4 files changed, 119 insertions(+), 118 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-18-05.bpo-1635741.FC13e7.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-18-05.bpo-1635741.FC13e7.rst b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-18-05.bpo-1635741.FC13e7.rst new file mode 100644 index 0000000..cdfee87 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-08-13-07-18-05.bpo-1635741.FC13e7.rst @@ -0,0 +1 @@ +Port the :mod:`_blake2` extension module to the multi-phase initialization API (:pep:`489`). diff --git a/Modules/_blake2/blake2b_impl.c b/Modules/_blake2/blake2b_impl.c index 7fb1296..8e1acce 100644 --- a/Modules/_blake2/blake2b_impl.c +++ b/Modules/_blake2/blake2b_impl.c @@ -34,7 +34,7 @@ #endif -extern PyTypeObject PyBlake2_BLAKE2bType; +extern PyType_Spec blake2b_type_spec; typedef struct { PyObject_HEAD @@ -391,47 +391,24 @@ py_blake2b_dealloc(PyObject *self) PyThread_free_lock(obj->lock); obj->lock = NULL; } + + PyTypeObject *type = Py_TYPE(self); PyObject_Del(self); + Py_DECREF(type); } +static PyType_Slot blake2b_type_slots[] = { + {Py_tp_dealloc, py_blake2b_dealloc}, + {Py_tp_doc, (char *)py_blake2b_new__doc__}, + {Py_tp_methods, py_blake2b_methods}, + {Py_tp_getset, py_blake2b_getsetters}, + {Py_tp_new, py_blake2b_new}, + {0,0} +}; -PyTypeObject PyBlake2_BLAKE2bType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_blake2.blake2b", /* tp_name */ - sizeof(BLAKE2bObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - py_blake2b_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 */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - py_blake2b_new__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - py_blake2b_methods, /* tp_methods */ - 0, /* tp_members */ - py_blake2b_getsetters, /* 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 */ - py_blake2b_new, /* tp_new */ +PyType_Spec blake2b_type_spec = { + .name = "_blake2.blake2b", + .basicsize = sizeof(BLAKE2bObject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = blake2b_type_slots }; diff --git a/Modules/_blake2/blake2module.c b/Modules/_blake2/blake2module.c index ff142c9..631de2c 100644 --- a/Modules/_blake2/blake2module.c +++ b/Modules/_blake2/blake2module.c @@ -12,62 +12,81 @@ #include "impl/blake2.h" -extern PyTypeObject PyBlake2_BLAKE2bType; -extern PyTypeObject PyBlake2_BLAKE2sType; - +extern PyType_Spec blake2b_type_spec; +extern PyType_Spec blake2s_type_spec; PyDoc_STRVAR(blake2mod__doc__, "_blake2b provides BLAKE2b for hashlib\n" ); +typedef struct { + PyTypeObject* blake2b_type; + PyTypeObject* blake2s_type; +} Blake2State; + +static inline Blake2State* +blake2_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (Blake2State *)state; +} static struct PyMethodDef blake2mod_functions[] = { {NULL, NULL} }; -static struct PyModuleDef blake2_module = { - PyModuleDef_HEAD_INIT, - "_blake2", - blake2mod__doc__, - -1, - blake2mod_functions, - NULL, - NULL, - NULL, - NULL -}; +static int +_blake2_traverse(PyObject *module, visitproc visit, void *arg) +{ + Blake2State *state = blake2_get_state(module); + Py_VISIT(state->blake2b_type); + Py_VISIT(state->blake2s_type); + return 0; +} + +static int +_blake2_clear(PyObject *module) +{ + Blake2State *state = blake2_get_state(module); + Py_CLEAR(state->blake2b_type); + Py_CLEAR(state->blake2s_type); + return 0; +} + +static void +_blake2_free(void *module) +{ + _blake2_clear((PyObject *)module); +} #define ADD_INT(d, name, value) do { \ PyObject *x = PyLong_FromLong(value); \ - if (!x) { \ - Py_DECREF(m); \ - return NULL; \ - } \ + if (!x) \ + return -1; \ if (PyDict_SetItemString(d, name, x) < 0) { \ - Py_DECREF(m); \ - return NULL; \ + Py_DECREF(x); \ + return -1; \ } \ Py_DECREF(x); \ } while(0) - -PyMODINIT_FUNC -PyInit__blake2(void) +static int +blake2_exec(PyObject *m) { - PyObject *m; - PyObject *d; + Blake2State* st = blake2_get_state(m); - m = PyModule_Create(&blake2_module); - if (m == NULL) - return NULL; + st->blake2b_type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &blake2b_type_spec, NULL); + if (NULL == st->blake2b_type) + return -1; /* BLAKE2b */ - Py_SET_TYPE(&PyBlake2_BLAKE2bType, &PyType_Type); - if (PyModule_AddType(m, &PyBlake2_BLAKE2bType) < 0) { - return NULL; + if (PyModule_AddType(m, st->blake2b_type) < 0) { + return -1; } - d = PyBlake2_BLAKE2bType.tp_dict; + PyObject *d = st->blake2b_type->tp_dict; ADD_INT(d, "SALT_SIZE", BLAKE2B_SALTBYTES); ADD_INT(d, "PERSON_SIZE", BLAKE2B_PERSONALBYTES); ADD_INT(d, "MAX_KEY_SIZE", BLAKE2B_KEYBYTES); @@ -79,12 +98,17 @@ PyInit__blake2(void) PyModule_AddIntConstant(m, "BLAKE2B_MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES); /* BLAKE2s */ - Py_SET_TYPE(&PyBlake2_BLAKE2sType, &PyType_Type); - if (PyModule_AddType(m, &PyBlake2_BLAKE2sType) < 0) { - return NULL; + st->blake2s_type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &blake2s_type_spec, NULL); + + if (NULL == st->blake2s_type) + return -1; + + if (PyModule_AddType(m, st->blake2s_type) < 0) { + return -1; } - d = PyBlake2_BLAKE2sType.tp_dict; + d = st->blake2s_type->tp_dict; ADD_INT(d, "SALT_SIZE", BLAKE2S_SALTBYTES); ADD_INT(d, "PERSON_SIZE", BLAKE2S_PERSONALBYTES); ADD_INT(d, "MAX_KEY_SIZE", BLAKE2S_KEYBYTES); @@ -95,5 +119,28 @@ PyInit__blake2(void) PyModule_AddIntConstant(m, "BLAKE2S_MAX_KEY_SIZE", BLAKE2S_KEYBYTES); PyModule_AddIntConstant(m, "BLAKE2S_MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES); - return m; + return 0; } + +static PyModuleDef_Slot _blake2_slots[] = { + {Py_mod_exec, blake2_exec}, + {0, NULL} +}; + +static struct PyModuleDef blake2_module = { + PyModuleDef_HEAD_INIT, + "_blake2", + .m_doc = blake2mod__doc__, + .m_size = sizeof(Blake2State), + .m_methods = blake2mod_functions, + .m_slots = _blake2_slots, + .m_traverse = _blake2_traverse, + .m_clear = _blake2_clear, + .m_free = _blake2_free, +}; + +PyMODINIT_FUNC +PyInit__blake2(void) +{ + return PyModuleDef_Init(&blake2_module); +} \ No newline at end of file diff --git a/Modules/_blake2/blake2s_impl.c b/Modules/_blake2/blake2s_impl.c index e3e90d0..e1de5df 100644 --- a/Modules/_blake2/blake2s_impl.c +++ b/Modules/_blake2/blake2s_impl.c @@ -33,8 +33,7 @@ #include "impl/blake2s-ref.c" #endif - -extern PyTypeObject PyBlake2_BLAKE2sType; +extern PyType_Spec blake2s_type_spec; typedef struct { PyObject_HEAD @@ -391,47 +390,24 @@ py_blake2s_dealloc(PyObject *self) PyThread_free_lock(obj->lock); obj->lock = NULL; } + + PyTypeObject *type = Py_TYPE(self); PyObject_Del(self); + Py_DECREF(type); } +static PyType_Slot blake2s_type_slots[] = { + {Py_tp_dealloc, py_blake2s_dealloc}, + {Py_tp_doc, (char *)py_blake2s_new__doc__}, + {Py_tp_methods, py_blake2s_methods}, + {Py_tp_getset, py_blake2s_getsetters}, + {Py_tp_new, py_blake2s_new}, + {0,0} +}; -PyTypeObject PyBlake2_BLAKE2sType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_blake2.blake2s", /* tp_name */ - sizeof(BLAKE2sObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - py_blake2s_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 */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - py_blake2s_new__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - py_blake2s_methods, /* tp_methods */ - 0, /* tp_members */ - py_blake2s_getsetters, /* 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 */ - py_blake2s_new, /* tp_new */ +PyType_Spec blake2s_type_spec = { + .name = "_blake2.blake2s", + .basicsize = sizeof(BLAKE2sObject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = blake2s_type_slots }; -- cgit v0.12