bpo-1635741: Port _blake2 module to multi-phase init (GH-21856) · python/cpython@a7f0268
@@ -12,62 +12,81 @@
12121313#include "impl/blake2.h"
141415-extern PyTypeObject PyBlake2_BLAKE2bType;
16-extern PyTypeObject PyBlake2_BLAKE2sType;
17-15+extern PyType_Spec blake2b_type_spec;
16+extern PyType_Spec blake2s_type_spec;
18171918PyDoc_STRVAR(blake2mod__doc__,
2019"_blake2b provides BLAKE2b for hashlib\n"
2120);
222122+typedef struct {
23+PyTypeObject* blake2b_type;
24+PyTypeObject* blake2s_type;
25+} Blake2State;
26+27+static inline Blake2State*
28+blake2_get_state(PyObject *module)
29+{
30+void *state = PyModule_GetState(module);
31+assert(state != NULL);
32+return (Blake2State *)state;
33+}
23342435static struct PyMethodDef blake2mod_functions[] = {
2536 {NULL, NULL}
2637};
273828-static struct PyModuleDef blake2_module = {
29-PyModuleDef_HEAD_INIT,
30-"_blake2",
31-blake2mod__doc__,
32--1,
33-blake2mod_functions,
34-NULL,
35-NULL,
36-NULL,
37-NULL
38-};
39+static int
40+_blake2_traverse(PyObject *module, visitproc visit, void *arg)
41+{
42+Blake2State *state = blake2_get_state(module);
43+Py_VISIT(state->blake2b_type);
44+Py_VISIT(state->blake2s_type);
45+return 0;
46+}
47+48+static int
49+_blake2_clear(PyObject *module)
50+{
51+Blake2State *state = blake2_get_state(module);
52+Py_CLEAR(state->blake2b_type);
53+Py_CLEAR(state->blake2s_type);
54+return 0;
55+}
56+57+static void
58+_blake2_free(void *module)
59+{
60+_blake2_clear((PyObject *)module);
61+}
39624063#define ADD_INT(d, name, value) do { \
4164 PyObject *x = PyLong_FromLong(value); \
42- if (!x) { \
43- Py_DECREF(m); \
44- return NULL; \
45- } \
65+ if (!x) \
66+ return -1; \
4667 if (PyDict_SetItemString(d, name, x) < 0) { \
47- Py_DECREF(m); \
48- return NULL; \
68+ Py_DECREF(x); \
69+ return -1; \
4970 } \
5071 Py_DECREF(x); \
5172} while(0)
527353-54-PyMODINIT_FUNC
55-PyInit__blake2(void)
74+static int
75+blake2_exec(PyObject *m)
5676{
57-PyObject *m;
58-PyObject *d;
77+Blake2State* st = blake2_get_state(m);
597860-m = PyModule_Create(&blake2_module);
61-if (m == NULL)
62-return NULL;
79+st->blake2b_type = (PyTypeObject *)PyType_FromModuleAndSpec(
80+m, &blake2b_type_spec, NULL);
638182+if (NULL == st->blake2b_type)
83+return -1;
6484/* BLAKE2b */
65-Py_SET_TYPE(&PyBlake2_BLAKE2bType, &PyType_Type);
66-if (PyModule_AddType(m, &PyBlake2_BLAKE2bType) < 0) {
67-return NULL;
85+if (PyModule_AddType(m, st->blake2b_type) < 0) {
86+return -1;
6887 }
698870-d = PyBlake2_BLAKE2bType.tp_dict;
89+PyObject *d = st->blake2b_type->tp_dict;
7190ADD_INT(d, "SALT_SIZE", BLAKE2B_SALTBYTES);
7291ADD_INT(d, "PERSON_SIZE", BLAKE2B_PERSONALBYTES);
7392ADD_INT(d, "MAX_KEY_SIZE", BLAKE2B_KEYBYTES);
@@ -79,12 +98,17 @@ PyInit__blake2(void)
7998PyModule_AddIntConstant(m, "BLAKE2B_MAX_DIGEST_SIZE", BLAKE2B_OUTBYTES);
809981100/* BLAKE2s */
82-Py_SET_TYPE(&PyBlake2_BLAKE2sType, &PyType_Type);
83-if (PyModule_AddType(m, &PyBlake2_BLAKE2sType) < 0) {
84-return NULL;
101+st->blake2s_type = (PyTypeObject *)PyType_FromModuleAndSpec(
102+m, &blake2s_type_spec, NULL);
103+104+if (NULL == st->blake2s_type)
105+return -1;
106+107+if (PyModule_AddType(m, st->blake2s_type) < 0) {
108+return -1;
85109 }
8611087-d = PyBlake2_BLAKE2sType.tp_dict;
111+d = st->blake2s_type->tp_dict;
88112ADD_INT(d, "SALT_SIZE", BLAKE2S_SALTBYTES);
89113ADD_INT(d, "PERSON_SIZE", BLAKE2S_PERSONALBYTES);
90114ADD_INT(d, "MAX_KEY_SIZE", BLAKE2S_KEYBYTES);
@@ -95,5 +119,28 @@ PyInit__blake2(void)
95119PyModule_AddIntConstant(m, "BLAKE2S_MAX_KEY_SIZE", BLAKE2S_KEYBYTES);
96120PyModule_AddIntConstant(m, "BLAKE2S_MAX_DIGEST_SIZE", BLAKE2S_OUTBYTES);
9712198-return m;
122+return 0;
99123}
124+125+static PyModuleDef_Slot _blake2_slots[] = {
126+ {Py_mod_exec, blake2_exec},
127+ {0, NULL}
128+};
129+130+static struct PyModuleDef blake2_module = {
131+PyModuleDef_HEAD_INIT,
132+"_blake2",
133+ .m_doc = blake2mod__doc__,
134+ .m_size = sizeof(Blake2State),
135+ .m_methods = blake2mod_functions,
136+ .m_slots = _blake2_slots,
137+ .m_traverse = _blake2_traverse,
138+ .m_clear = _blake2_clear,
139+ .m_free = _blake2_free,
140+};
141+142+PyMODINIT_FUNC
143+PyInit__blake2(void)
144+{
145+return PyModuleDef_Init(&blake2_module);
146+}