bpo-41798: Allocate _decimal extension module C API on the heap (GH-2… · python/cpython@fe9f446
@@ -5574,8 +5574,6 @@ static PyTypeObject PyDecContext_Type =
55745574/* C-API */
55755575/****************************************************************************/
557655765577-static void *_decimal_api[CPYTHON_DECIMAL_MAX_API];
5578-55795577/* Simple API */
55805578static int
55815579PyDec_TypeCheck(const PyObject *v)
@@ -5699,9 +5697,22 @@ PyDec_GetConst(const PyObject *v)
56995697return MPD(v);
57005698}
570156995700+static void
5701+destroy_api(PyObject *capsule)
5702+{
5703+void *capi = PyCapsule_GetPointer(capsule, PyDec_CAPSULE_NAME);
5704+PyMem_Free(capi);
5705+}
5706+57025707static PyObject *
57035708init_api(void)
57045709{
5710+void **_decimal_api = PyMem_Calloc(CPYTHON_DECIMAL_MAX_API, sizeof(void *));
5711+if (_decimal_api == NULL) {
5712+PyErr_NoMemory();
5713+return NULL;
5714+ }
5715+57055716/* Simple API */
57065717_decimal_api[PyDec_TypeCheck_INDEX] = (void *)PyDec_TypeCheck;
57075718_decimal_api[PyDec_IsSpecial_INDEX] = (void *)PyDec_IsSpecial;
@@ -5716,7 +5727,11 @@ init_api(void)
57165727_decimal_api[PyDec_Get_INDEX] = (void *)PyDec_Get;
57175728_decimal_api[PyDec_GetConst_INDEX] = (void *)PyDec_GetConst;
571857295719-return PyCapsule_New(_decimal_api, "_decimal._API", NULL);
5730+PyObject *capsule = PyCapsule_New(_decimal_api, PyDec_CAPSULE_NAME, destroy_api);
5731+if (!capsule) {
5732+PyMem_Free(_decimal_api);
5733+ }
5734+return capsule;
57205735}
5721573657225737@@ -6080,8 +6095,7 @@ PyInit__decimal(void)
60806095CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version()));
6081609660826097/* Add capsule API */
6083-Py_INCREF(capsule);
6084-if (PyModule_AddObject(m, "_API", capsule) < 0) {
6098+if (PyModule_AddObjectRef(m, "_API", capsule) < 0) {
60856099 goto error;
60866100 }
60876101@@ -6107,6 +6121,7 @@ PyInit__decimal(void)
61076121Py_CLEAR(basic_context_template); /* GCOV_NOT_REACHED */
61086122Py_CLEAR(extended_context_template); /* GCOV_NOT_REACHED */
61096123Py_CLEAR(m); /* GCOV_NOT_REACHED */
6124+Py_CLEAR(capsule); /* GCOV_NOT_REACHED */
6110612561116126return NULL; /* GCOV_NOT_REACHED */
61126127}