support multi-phase initialization PiperOrigin-RevId: 811797785
diff --git a/python/_brotli.c b/python/_brotli.c index 0307347..8b02d17 100644 --- a/python/_brotli.c +++ b/python/_brotli.c
@@ -892,6 +892,8 @@ /* Module definition */ +static int init_brotli_mod(PyObject* m); + static PyMethodDef brotli_methods[] = { {"decompress", (PyCFunction)brotli_decompress, METH_VARARGS | METH_KEYWORDS, brotli_decompress__doc__}, @@ -920,16 +922,29 @@ #if PY_MAJOR_VERSION >= 3 +#if PY_MINOR_VERSION >= 5 +static PyModuleDef_Slot brotli_mod_slots[] = { + {Py_mod_exec, init_brotli_mod}, +#if PY_MINOR_VERSION >= 12 + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, +#endif + {0, NULL}}; +#endif + static struct PyModuleDef brotli_module = { PyModuleDef_HEAD_INIT, "_brotli", /* m_name */ brotli_doc, /* m_doc */ 0, /* m_size */ brotli_methods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ +#if PY_MINOR_VERSION >= 5 + brotli_mod_slots, /* m_slots */ +#else + NULL, /* m_reload */ +#endif + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ }; static PyType_Slot brotli_Compressor_slots[] = { @@ -958,6 +973,20 @@ "brotli.Decompressor", sizeof(PyBrotli_Decompressor), 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, brotli_Decompressor_slots}; +PyMODINIT_FUNC PyInit__brotli(void) { +#if PY_MINOR_VERSION < 5 + PyObject* m = PyModule_Create(&brotli_module); + if (m == NULL) return NULL; + if (init_brotli_mod(m) < 0) { + Py_DECREF(m); + m = NULL; + } + return m; +#else + return PyModuleDef_Init(&brotli_module); +#endif +} + #else static PyTypeObject brotli_CompressorType = { @@ -1042,18 +1071,12 @@ brotli_Decompressor_new, /* tp_new */ }; -#endif +PyMODINIT_FUNC init_brotli(void) { + PyObject* m = Py_InitModule3("_brotli", brotli_methods, brotli_doc); + if (m == NULL) return; + init_brotli_mod(m); +} -#if PY_MAJOR_VERSION >= 3 -#define INIT_BROTLI PyInit__brotli -#define CREATE_BROTLI PyModule_Create(&brotli_module) -#define RETURN_BROTLI return m -#define RETURN_NULL return NULL -#else -#define INIT_BROTLI init_brotli -#define CREATE_BROTLI Py_InitModule3("_brotli", brotli_methods, brotli_doc) -#define RETURN_BROTLI return -#define RETURN_NULL return #endif /* Emulates PyModule_AddObject */ @@ -1070,13 +1093,11 @@ #endif } -PyMODINIT_FUNC INIT_BROTLI(void) { - PyObject* m = CREATE_BROTLI; +static int init_brotli_mod(PyObject* m) { PyObject* error_type = NULL; PyObject* compressor_type = NULL; PyObject* decompressor_type = NULL; - - if (m == NULL) goto error; + assert(m != NULL); error_type = PyErr_NewExceptionWithDoc((char*)"brotli.error", brotli_error_doc, NULL, NULL); @@ -1124,13 +1145,9 @@ (decoderVersion >> 12) & 0xFFF, decoderVersion & 0xFFF); PyModule_AddStringConstant(m, "__version__", version); - RETURN_BROTLI; + return 0; error: - if (m != NULL) { - Py_DECREF(m); - m = NULL; - } if (error_type != NULL) { Py_DECREF(error_type); error_type = NULL; @@ -1143,5 +1160,5 @@ Py_DECREF(decompressor_type); decompressor_type = NULL; } - RETURN_NULL; + return -1; }