Skip to content

Commit 49f1c30

Browse files
gh-139098: Use multiphase initialization in _testcapi (GH-139102)
Use multiphase initialization in the _testcapi module to allow loading in subinterpreters. The isolation here isn't perfect as there's still some use of globals, but _testcapi should generally work in other interpreters.
1 parent 70ad1b3 commit 49f1c30

File tree

2 files changed

+84
-86
lines changed

2 files changed

+84
-86
lines changed

Modules/_testcapi/heaptype.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -782,10 +782,7 @@ heapctypesubclasswithfinalizer_finalize(PyObject *self)
782782
/* Save the current exception, if any. */
783783
PyObject *exc = PyErr_GetRaisedException();
784784

785-
if (_testcapimodule == NULL) {
786-
goto cleanup_finalize;
787-
}
788-
PyObject *m = PyState_FindModule(_testcapimodule);
785+
PyObject *m = PyType_GetModule(Py_TYPE(self));
789786
if (m == NULL) {
790787
goto cleanup_finalize;
791788
}
@@ -1402,8 +1399,8 @@ _PyTestCapi_Init_Heaptype(PyObject *m) {
14021399
if (subclass_with_finalizer_bases == NULL) {
14031400
return -1;
14041401
}
1405-
PyObject *HeapCTypeSubclassWithFinalizer = PyType_FromSpecWithBases(
1406-
&HeapCTypeSubclassWithFinalizer_spec, subclass_with_finalizer_bases);
1402+
PyObject *HeapCTypeSubclassWithFinalizer = PyType_FromModuleAndSpec(
1403+
m, &HeapCTypeSubclassWithFinalizer_spec, subclass_with_finalizer_bases);
14071404
Py_DECREF(subclass_with_finalizer_bases);
14081405
ADD("HeapCTypeSubclassWithFinalizer", HeapCTypeSubclassWithFinalizer);
14091406

Modules/_testcapimodule.c

Lines changed: 81 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -3243,75 +3243,56 @@ create_managed_dict_type(void)
32433243
return PyType_FromSpec(&ManagedDict_spec);
32443244
}
32453245

3246-
static struct PyModuleDef _testcapimodule = {
3247-
PyModuleDef_HEAD_INIT,
3248-
.m_name = "_testcapi",
3249-
.m_size = sizeof(testcapistate_t),
3250-
.m_methods = TestMethods,
3251-
};
3252-
3253-
/* Per PEP 489, this module will not be converted to multi-phase initialization
3254-
*/
3255-
3256-
PyMODINIT_FUNC
3257-
PyInit__testcapi(void)
3246+
static int
3247+
_testcapi_exec(PyObject *m)
32583248
{
3259-
PyObject *m;
3260-
3261-
m = PyModule_Create(&_testcapimodule);
3262-
if (m == NULL)
3263-
return NULL;
3264-
#ifdef Py_GIL_DISABLED
3265-
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
3266-
#endif
3267-
32683249
Py_SET_TYPE(&_HashInheritanceTester_Type, &PyType_Type);
32693250
if (PyType_Ready(&_HashInheritanceTester_Type) < 0) {
3270-
return NULL;
3251+
return -1;
32713252
}
32723253
if (PyType_Ready(&matmulType) < 0)
3273-
return NULL;
3254+
return -1;
32743255
Py_INCREF(&matmulType);
32753256
PyModule_AddObject(m, "matmulType", (PyObject *)&matmulType);
32763257
if (PyType_Ready(&ipowType) < 0) {
3277-
return NULL;
3258+
return -1;
32783259
}
32793260
Py_INCREF(&ipowType);
32803261
PyModule_AddObject(m, "ipowType", (PyObject *)&ipowType);
32813262

32823263
if (PyType_Ready(&awaitType) < 0)
3283-
return NULL;
3264+
return -1;
32843265
Py_INCREF(&awaitType);
32853266
PyModule_AddObject(m, "awaitType", (PyObject *)&awaitType);
32863267

32873268
MyList_Type.tp_base = &PyList_Type;
32883269
if (PyType_Ready(&MyList_Type) < 0)
3289-
return NULL;
3270+
return -1;
32903271
Py_INCREF(&MyList_Type);
32913272
PyModule_AddObject(m, "MyList", (PyObject *)&MyList_Type);
32923273

32933274
if (PyType_Ready(&GenericAlias_Type) < 0)
3294-
return NULL;
3275+
return -1;
32953276
Py_INCREF(&GenericAlias_Type);
32963277
PyModule_AddObject(m, "GenericAlias", (PyObject *)&GenericAlias_Type);
32973278

32983279
if (PyType_Ready(&Generic_Type) < 0)
3299-
return NULL;
3280+
return -1;
33003281
Py_INCREF(&Generic_Type);
33013282
PyModule_AddObject(m, "Generic", (PyObject *)&Generic_Type);
33023283

33033284
if (PyType_Ready(&MethInstance_Type) < 0)
3304-
return NULL;
3285+
return -1;
33053286
Py_INCREF(&MethInstance_Type);
33063287
PyModule_AddObject(m, "MethInstance", (PyObject *)&MethInstance_Type);
33073288

33083289
if (PyType_Ready(&MethClass_Type) < 0)
3309-
return NULL;
3290+
return -1;
33103291
Py_INCREF(&MethClass_Type);
33113292
PyModule_AddObject(m, "MethClass", (PyObject *)&MethClass_Type);
33123293

33133294
if (PyType_Ready(&MethStatic_Type) < 0)
3314-
return NULL;
3295+
return -1;
33153296
Py_INCREF(&MethStatic_Type);
33163297
PyModule_AddObject(m, "MethStatic", (PyObject *)&MethStatic_Type);
33173298

@@ -3354,159 +3335,179 @@ PyInit__testcapi(void)
33543335
PyModule_AddObject(m, "UINT64_MAX", PyLong_FromUInt64(UINT64_MAX));
33553336

33563337
if (PyModule_AddIntMacro(m, Py_single_input)) {
3357-
return NULL;
3338+
return -1;
33583339
}
33593340
if (PyModule_AddIntMacro(m, Py_file_input)) {
3360-
return NULL;
3341+
return -1;
33613342
}
33623343
if (PyModule_AddIntMacro(m, Py_eval_input)) {
3363-
return NULL;
3344+
return -1;
33643345
}
33653346

33663347
testcapistate_t *state = get_testcapi_state(m);
33673348
state->error = PyErr_NewException("_testcapi.error", NULL, NULL);
33683349
PyModule_AddObject(m, "error", state->error);
33693350

33703351
if (PyType_Ready(&ContainerNoGC_type) < 0) {
3371-
return NULL;
3352+
return -1;
33723353
}
33733354
Py_INCREF(&ContainerNoGC_type);
33743355
if (PyModule_AddObject(m, "ContainerNoGC",
33753356
(PyObject *) &ContainerNoGC_type) < 0)
3376-
return NULL;
3357+
return -1;
33773358

33783359
PyObject *manual_heap_type = create_manual_heap_type();
33793360
if (manual_heap_type == NULL) {
3380-
return NULL;
3361+
return -1;
33813362
}
33823363
if (PyModule_Add(m, "ManualHeapType", manual_heap_type) < 0) {
3383-
return NULL;
3364+
return -1;
33843365
}
33853366

33863367
PyObject *managed_dict_type = create_managed_dict_type();
33873368
if (managed_dict_type == NULL) {
3388-
return NULL;
3369+
return -1;
33893370
}
33903371
if (PyModule_Add(m, "ManagedDictType", managed_dict_type) < 0) {
3391-
return NULL;
3372+
return -1;
33923373
}
33933374

33943375
/* Include tests from the _testcapi/ directory */
33953376
if (_PyTestCapi_Init_Vectorcall(m) < 0) {
3396-
return NULL;
3377+
return -1;
33973378
}
33983379
if (_PyTestCapi_Init_Heaptype(m) < 0) {
3399-
return NULL;
3380+
return -1;
34003381
}
34013382
if (_PyTestCapi_Init_Abstract(m) < 0) {
3402-
return NULL;
3383+
return -1;
34033384
}
34043385
if (_PyTestCapi_Init_Bytes(m) < 0) {
3405-
return NULL;
3386+
return -1;
34063387
}
34073388
if (_PyTestCapi_Init_Unicode(m) < 0) {
3408-
return NULL;
3389+
return -1;
34093390
}
34103391
if (_PyTestCapi_Init_GetArgs(m) < 0) {
3411-
return NULL;
3392+
return -1;
34123393
}
34133394
if (_PyTestCapi_Init_DateTime(m) < 0) {
3414-
return NULL;
3395+
return -1;
34153396
}
34163397
if (_PyTestCapi_Init_Docstring(m) < 0) {
3417-
return NULL;
3398+
return -1;
34183399
}
34193400
if (_PyTestCapi_Init_Mem(m) < 0) {
3420-
return NULL;
3401+
return -1;
34213402
}
34223403
if (_PyTestCapi_Init_Watchers(m) < 0) {
3423-
return NULL;
3404+
return -1;
34243405
}
34253406
if (_PyTestCapi_Init_Long(m) < 0) {
3426-
return NULL;
3407+
return -1;
34273408
}
34283409
if (_PyTestCapi_Init_Float(m) < 0) {
3429-
return NULL;
3410+
return -1;
34303411
}
34313412
if (_PyTestCapi_Init_Complex(m) < 0) {
3432-
return NULL;
3413+
return -1;
34333414
}
34343415
if (_PyTestCapi_Init_Numbers(m) < 0) {
3435-
return NULL;
3416+
return -1;
34363417
}
34373418
if (_PyTestCapi_Init_Dict(m) < 0) {
3438-
return NULL;
3419+
return -1;
34393420
}
34403421
if (_PyTestCapi_Init_Set(m) < 0) {
3441-
return NULL;
3422+
return -1;
34423423
}
34433424
if (_PyTestCapi_Init_List(m) < 0) {
3444-
return NULL;
3425+
return -1;
34453426
}
34463427
if (_PyTestCapi_Init_Tuple(m) < 0) {
3447-
return NULL;
3428+
return -1;
34483429
}
34493430
if (_PyTestCapi_Init_Structmember(m) < 0) {
3450-
return NULL;
3431+
return -1;
34513432
}
34523433
if (_PyTestCapi_Init_Exceptions(m) < 0) {
3453-
return NULL;
3434+
return -1;
34543435
}
34553436
if (_PyTestCapi_Init_Code(m) < 0) {
3456-
return NULL;
3437+
return -1;
34573438
}
34583439
if (_PyTestCapi_Init_Buffer(m) < 0) {
3459-
return NULL;
3440+
return -1;
34603441
}
34613442
if (_PyTestCapi_Init_File(m) < 0) {
3462-
return NULL;
3443+
return -1;
34633444
}
34643445
if (_PyTestCapi_Init_Codec(m) < 0) {
3465-
return NULL;
3446+
return -1;
34663447
}
34673448
if (_PyTestCapi_Init_Immortal(m) < 0) {
3468-
return NULL;
3449+
return -1;
34693450
}
34703451
if (_PyTestCapi_Init_GC(m) < 0) {
3471-
return NULL;
3452+
return -1;
34723453
}
34733454
if (_PyTestCapi_Init_PyAtomic(m) < 0) {
3474-
return NULL;
3455+
return -1;
34753456
}
34763457
if (_PyTestCapi_Init_Run(m) < 0) {
3477-
return NULL;
3458+
return -1;
34783459
}
34793460
if (_PyTestCapi_Init_Hash(m) < 0) {
3480-
return NULL;
3461+
return -1;
34813462
}
34823463
if (_PyTestCapi_Init_Time(m) < 0) {
3483-
return NULL;
3464+
return -1;
34843465
}
34853466
if (_PyTestCapi_Init_Modsupport(m) < 0) {
3486-
return NULL;
3467+
return -1;
34873468
}
34883469
if (_PyTestCapi_Init_Monitoring(m) < 0) {
3489-
return NULL;
3470+
return -1;
34903471
}
34913472
if (_PyTestCapi_Init_Object(m) < 0) {
3492-
return NULL;
3473+
return -1;
34933474
}
34943475
if (_PyTestCapi_Init_Config(m) < 0) {
3495-
return NULL;
3476+
return -1;
34963477
}
34973478
if (_PyTestCapi_Init_Import(m) < 0) {
3498-
return NULL;
3479+
return -1;
34993480
}
35003481
if (_PyTestCapi_Init_Frame(m) < 0) {
3501-
return NULL;
3482+
return -1;
35023483
}
35033484
if (_PyTestCapi_Init_Type(m) < 0) {
3504-
return NULL;
3485+
return -1;
35053486
}
35063487
if (_PyTestCapi_Init_Function(m) < 0) {
3507-
return NULL;
3488+
return -1;
35083489
}
35093490

3510-
PyState_AddModule(m, &_testcapimodule);
3511-
return m;
3491+
return 0;
3492+
}
3493+
3494+
static PyModuleDef_Slot _testcapi_slots[] = {
3495+
{Py_mod_exec, _testcapi_exec},
3496+
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
3497+
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
3498+
{0, NULL},
3499+
};
3500+
3501+
static struct PyModuleDef _testcapimodule = {
3502+
PyModuleDef_HEAD_INIT,
3503+
.m_name = "_testcapi",
3504+
.m_size = sizeof(testcapistate_t),
3505+
.m_methods = TestMethods,
3506+
.m_slots = _testcapi_slots
3507+
};
3508+
3509+
PyMODINIT_FUNC
3510+
PyInit__testcapi(void)
3511+
{
3512+
return PyModuleDef_Init(&_testcapimodule);
35123513
}

0 commit comments

Comments
 (0)