Skip to content

Commit 81fe5bd

Browse files
authored
bpo-38858: new_interpreter() reuses _PySys_Create() (GH-17481)
new_interpreter() now calls _PySys_Create() to create a new sys module isolated from the main interpreter. It now calls _PySys_InitCore() and _PyImport_FixupBuiltin(). init_interp_main() now calls _PySys_InitMain().
1 parent 44ea525 commit 81fe5bd

File tree

3 files changed

+46
-55
lines changed

3 files changed

+46
-55
lines changed

Include/internal/pycore_pylifecycle.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ extern PyObject * _PyBuiltin_Init(PyThreadState *tstate);
4040
extern PyStatus _PySys_Create(
4141
PyThreadState *tstate,
4242
PyObject **sysmod_p);
43-
extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict);
4443
extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
4544
extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
4645
extern int _PySys_InitMain(PyThreadState *tstate);

Python/pylifecycle.c

Lines changed: 32 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,8 @@ pycore_init_types(PyThreadState *tstate)
622622
static PyStatus
623623
pycore_init_builtins(PyThreadState *tstate)
624624
{
625+
assert(!_PyErr_Occurred(tstate));
626+
625627
PyObject *bimod = _PyBuiltin_Init(tstate);
626628
if (bimod == NULL) {
627629
goto error;
@@ -649,6 +651,9 @@ pycore_init_builtins(PyThreadState *tstate)
649651
goto error;
650652
}
651653
Py_DECREF(bimod);
654+
655+
assert(!_PyErr_Occurred(tstate));
656+
652657
return _PyStatus_OK();
653658

654659
error:
@@ -660,13 +665,14 @@ pycore_init_builtins(PyThreadState *tstate)
660665
static PyStatus
661666
pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod)
662667
{
663-
const PyConfig *config = &tstate->interp->config;
668+
assert(!_PyErr_Occurred(tstate));
664669

665670
PyStatus status = _PyImportHooks_Init(tstate);
666671
if (_PyStatus_EXCEPTION(status)) {
667672
return status;
668673
}
669674

675+
const PyConfig *config = &tstate->interp->config;
670676
if (_Py_IsMainInterpreter(tstate)) {
671677
/* Initialize _warnings. */
672678
if (_PyWarnings_Init() == NULL) {
@@ -688,6 +694,9 @@ pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod)
688694
return status;
689695
}
690696
}
697+
698+
assert(!_PyErr_Occurred(tstate));
699+
691700
return _PyStatus_OK();
692701
}
693702

@@ -929,6 +938,8 @@ _Py_ReconfigureMainInterpreter(PyThreadState *tstate)
929938
static PyStatus
930939
init_interp_main(PyThreadState *tstate)
931940
{
941+
assert(!_PyErr_Occurred(tstate));
942+
932943
PyStatus status;
933944
int is_main_interp = _Py_IsMainInterpreter(tstate);
934945
PyInterpreterState *interp = tstate->interp;
@@ -950,10 +961,10 @@ init_interp_main(PyThreadState *tstate)
950961
if (_PyTime_Init() < 0) {
951962
return _PyStatus_ERR("can't initialize time");
952963
}
964+
}
953965

954-
if (_PySys_InitMain(tstate) < 0) {
955-
return _PyStatus_ERR("can't finish initializing sys");
956-
}
966+
if (_PySys_InitMain(tstate) < 0) {
967+
return _PyStatus_ERR("can't finish initializing sys");
957968
}
958969

959970
status = init_importlib_external(tstate);
@@ -1031,6 +1042,8 @@ init_interp_main(PyThreadState *tstate)
10311042
#endif
10321043
}
10331044

1045+
assert(!_PyErr_Occurred(tstate));
1046+
10341047
return _PyStatus_OK();
10351048
}
10361049

@@ -1534,70 +1547,40 @@ new_interpreter(PyThreadState **tstate_p)
15341547

15351548
status = _PyConfig_Copy(&interp->config, config);
15361549
if (_PyStatus_EXCEPTION(status)) {
1537-
goto done;
1550+
goto error;
15381551
}
15391552
config = &interp->config;
15401553

15411554
status = pycore_init_types(tstate);
1542-
1543-
/* XXX The following is lax in error checking */
1544-
PyObject *modules = PyDict_New();
1545-
if (modules == NULL) {
1546-
status = _PyStatus_ERR("can't make modules dictionary");
1547-
goto done;
1555+
if (_PyStatus_EXCEPTION(status)) {
1556+
goto error;
15481557
}
1549-
interp->modules = modules;
15501558

1551-
PyObject *sysmod = _PyImport_FindBuiltin(tstate, "sys");
1552-
if (sysmod != NULL) {
1553-
interp->sysdict = PyModule_GetDict(sysmod);
1554-
if (interp->sysdict == NULL) {
1555-
goto handle_exc;
1556-
}
1557-
Py_INCREF(interp->sysdict);
1558-
PyDict_SetItemString(interp->sysdict, "modules", modules);
1559-
if (_PySys_InitMain(tstate) < 0) {
1560-
status = _PyStatus_ERR("can't finish initializing sys");
1561-
goto done;
1562-
}
1563-
}
1564-
else if (_PyErr_Occurred(tstate)) {
1565-
goto handle_exc;
1559+
PyObject *sysmod;
1560+
status = _PySys_Create(tstate, &sysmod);
1561+
if (_PyStatus_EXCEPTION(status)) {
1562+
return status;
15661563
}
15671564

15681565
status = pycore_init_builtins(tstate);
15691566
if (_PyStatus_EXCEPTION(status)) {
1570-
goto done;
1567+
goto error;
15711568
}
15721569

1573-
if (sysmod != NULL) {
1574-
status = _PySys_SetPreliminaryStderr(interp->sysdict);
1575-
if (_PyStatus_EXCEPTION(status)) {
1576-
goto done;
1577-
}
1578-
1579-
status = pycore_init_import_warnings(tstate, sysmod);
1580-
if (_PyStatus_EXCEPTION(status)) {
1581-
goto done;
1582-
}
1583-
1584-
status = init_interp_main(tstate);
1585-
if (_PyStatus_EXCEPTION(status)) {
1586-
goto done;
1587-
}
1570+
status = pycore_init_import_warnings(tstate, sysmod);
1571+
if (_PyStatus_EXCEPTION(status)) {
1572+
goto error;
15881573
}
15891574

1590-
if (_PyErr_Occurred(tstate)) {
1591-
goto handle_exc;
1575+
status = init_interp_main(tstate);
1576+
if (_PyStatus_EXCEPTION(status)) {
1577+
goto error;
15921578
}
15931579

15941580
*tstate_p = tstate;
15951581
return _PyStatus_OK();
15961582

1597-
handle_exc:
1598-
status = _PyStatus_OK();
1599-
1600-
done:
1583+
error:
16011584
*tstate_p = NULL;
16021585

16031586
/* Oops, it didn't work. Undo it all. */

Python/sysmodule.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2919,7 +2919,7 @@ _PySys_InitMain(PyThreadState *tstate)
29192919
infrastructure for the io module in place.
29202920
29212921
Use UTF-8/surrogateescape and ignore EAGAIN errors. */
2922-
PyStatus
2922+
static PyStatus
29232923
_PySys_SetPreliminaryStderr(PyObject *sysdict)
29242924
{
29252925
PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr));
@@ -2946,11 +2946,13 @@ _PySys_SetPreliminaryStderr(PyObject *sysdict)
29462946
PyStatus
29472947
_PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
29482948
{
2949+
assert(!_PyErr_Occurred(tstate));
2950+
29492951
PyInterpreterState *interp = tstate->interp;
29502952

29512953
PyObject *modules = PyDict_New();
29522954
if (modules == NULL) {
2953-
return _PyStatus_ERR("can't make modules dictionary");
2955+
goto error;
29542956
}
29552957
interp->modules = modules;
29562958

@@ -2961,13 +2963,13 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
29612963

29622964
PyObject *sysdict = PyModule_GetDict(sysmod);
29632965
if (sysdict == NULL) {
2964-
return _PyStatus_ERR("can't initialize sys dict");
2966+
goto error;
29652967
}
29662968
Py_INCREF(sysdict);
29672969
interp->sysdict = sysdict;
29682970

29692971
if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) {
2970-
return _PyStatus_ERR("can't initialize sys module");
2972+
goto error;
29712973
}
29722974

29732975
PyStatus status = _PySys_SetPreliminaryStderr(sysdict);
@@ -2980,10 +2982,17 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
29802982
return status;
29812983
}
29822984

2983-
_PyImport_FixupBuiltin(sysmod, "sys", interp->modules);
2985+
if (_PyImport_FixupBuiltin(sysmod, "sys", interp->modules) < 0) {
2986+
goto error;
2987+
}
2988+
2989+
assert(!_PyErr_Occurred(tstate));
29842990

29852991
*sysmod_p = sysmod;
29862992
return _PyStatus_OK();
2993+
2994+
error:
2995+
return _PyStatus_ERR("can't initialize sys module");
29872996
}
29882997

29892998

0 commit comments

Comments
 (0)