bpo-43687: Py_Initialize() creates singletons earlier (GH-25147)

Reorganize pycore_interp_init() to initialize singletons before the
the first PyType_Ready() call. Fix an issue when Python is configured
using --without-doc-strings.
This commit is contained in:
Victor Stinner 2021-04-02 15:28:13 +02:00 committed by GitHub
parent 58384c6ab0
commit 442ad74fc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 138 additions and 95 deletions

View File

@ -18,8 +18,8 @@ static inline PyObject* __PyLong_GetSmallInt_internal(int value)
assert(-_PY_NSMALLNEGINTS <= value && value < _PY_NSMALLPOSINTS); assert(-_PY_NSMALLNEGINTS <= value && value < _PY_NSMALLPOSINTS);
size_t index = _PY_NSMALLNEGINTS + value; size_t index = _PY_NSMALLNEGINTS + value;
PyObject *obj = (PyObject*)interp->small_ints[index]; PyObject *obj = (PyObject*)interp->small_ints[index];
// _PyLong_GetZero() and _PyLong_GetOne() must not be called // _PyLong_GetZero(), _PyLong_GetOne() and get_small_int() must not be
// before _PyLong_Init() nor after _PyLong_Fini() // called before _PyLong_Init() nor after _PyLong_Fini().
assert(obj != NULL); assert(obj != NULL);
return obj; return obj;
} }

View File

@ -50,9 +50,11 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc);
/* Various one-time initializers */ /* Various one-time initializers */
extern PyStatus _PyUnicode_Init(PyInterpreterState *interp); extern PyStatus _PyUnicode_Init(PyInterpreterState *interp);
extern PyStatus _PyUnicode_InitTypes(void);
extern PyStatus _PyBytes_Init(PyInterpreterState *interp); extern PyStatus _PyBytes_Init(PyInterpreterState *interp);
extern int _PyStructSequence_Init(void); extern int _PyStructSequence_Init(void);
extern int _PyLong_Init(PyInterpreterState *interp); extern int _PyLong_Init(PyInterpreterState *interp);
extern int _PyLong_InitTypes(void);
extern PyStatus _PyTuple_Init(PyInterpreterState *interp); extern PyStatus _PyTuple_Init(PyInterpreterState *interp);
extern PyStatus _PyFaulthandler_Init(int enable); extern PyStatus _PyFaulthandler_Init(int enable);
extern int _PyTraceMalloc_Init(int enable); extern int _PyTraceMalloc_Init(int enable);
@ -64,9 +66,10 @@ extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config); extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
extern int _PySys_UpdateConfig(PyThreadState *tstate); extern int _PySys_UpdateConfig(PyThreadState *tstate);
extern PyStatus _PyExc_Init(PyInterpreterState *interp); extern PyStatus _PyExc_Init(PyInterpreterState *interp);
extern PyStatus _PyErr_Init(void); extern PyStatus _PyErr_InitTypes(void);
extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod); extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod);
extern int _PyFloat_Init(void); extern void _PyFloat_Init(void);
extern int _PyFloat_InitTypes(void);
extern PyStatus _Py_HashRandomization_Init(const PyConfig *); extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
extern PyStatus _PyTypes_Init(void); extern PyStatus _PyTypes_Init(void);

View File

@ -1968,7 +1968,7 @@ PyTypeObject PyFloat_Type = {
.tp_vectorcall = (vectorcallfunc)float_vectorcall, .tp_vectorcall = (vectorcallfunc)float_vectorcall,
}; };
int void
_PyFloat_Init(void) _PyFloat_Init(void)
{ {
/* We attempt to determine if this machine is using IEEE /* We attempt to determine if this machine is using IEEE
@ -2016,14 +2016,18 @@ _PyFloat_Init(void)
double_format = detected_double_format; double_format = detected_double_format;
float_format = detected_float_format; float_format = detected_float_format;
}
int
_PyFloat_InitTypes(void)
{
/* Init float info */ /* Init float info */
if (FloatInfoType.tp_name == NULL) { if (FloatInfoType.tp_name == NULL) {
if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) { if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) {
return 0; return -1;
} }
} }
return 1; return 0;
} }
void void

View File

@ -5719,17 +5719,20 @@ _PyLong_Init(PyInterpreterState *interp)
interp->small_ints[i] = v; interp->small_ints[i] = v;
} }
return 0;
}
if (_Py_IsMainInterpreter(interp)) {
/* initialize int_info */ int
if (Int_InfoType.tp_name == NULL) { _PyLong_InitTypes(void)
if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) { {
return 0; /* initialize int_info */
} if (Int_InfoType.tp_name == NULL) {
if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) {
return -1;
} }
} }
return 0;
return 1;
} }
void void

View File

@ -579,7 +579,8 @@ int _PyStructSequence_Init(void)
if (_PyUnicode_FromId(&PyId_n_sequence_fields) == NULL if (_PyUnicode_FromId(&PyId_n_sequence_fields) == NULL
|| _PyUnicode_FromId(&PyId_n_fields) == NULL || _PyUnicode_FromId(&PyId_n_fields) == NULL
|| _PyUnicode_FromId(&PyId_n_unnamed_fields) == NULL) || _PyUnicode_FromId(&PyId_n_unnamed_fields) == NULL)
{
return -1; return -1;
}
return 0; return 0;
} }

View File

@ -15676,18 +15676,6 @@ PyTypeObject PyUnicode_Type = {
PyStatus PyStatus
_PyUnicode_Init(PyInterpreterState *interp) _PyUnicode_Init(PyInterpreterState *interp)
{ {
/* XXX - move this array to unicodectype.c ? */
const Py_UCS2 linebreak[] = {
0x000A, /* LINE FEED */
0x000D, /* CARRIAGE RETURN */
0x001C, /* FILE SEPARATOR */
0x001D, /* GROUP SEPARATOR */
0x001E, /* RECORD SEPARATOR */
0x0085, /* NEXT LINE */
0x2028, /* LINE SEPARATOR */
0x2029, /* PARAGRAPH SEPARATOR */
};
struct _Py_unicode_state *state = &interp->unicode; struct _Py_unicode_state *state = &interp->unicode;
if (unicode_create_empty_string_singleton(state) < 0) { if (unicode_create_empty_string_singleton(state) < 0) {
return _PyStatus_NO_MEMORY(); return _PyStatus_NO_MEMORY();
@ -15695,23 +15683,39 @@ _PyUnicode_Init(PyInterpreterState *interp)
if (_Py_IsMainInterpreter(interp)) { if (_Py_IsMainInterpreter(interp)) {
/* initialize the linebreak bloom filter */ /* initialize the linebreak bloom filter */
const Py_UCS2 linebreak[] = {
0x000A, /* LINE FEED */
0x000D, /* CARRIAGE RETURN */
0x001C, /* FILE SEPARATOR */
0x001D, /* GROUP SEPARATOR */
0x001E, /* RECORD SEPARATOR */
0x0085, /* NEXT LINE */
0x2028, /* LINE SEPARATOR */
0x2029, /* PARAGRAPH SEPARATOR */
};
bloom_linebreak = make_bloom_mask( bloom_linebreak = make_bloom_mask(
PyUnicode_2BYTE_KIND, linebreak, PyUnicode_2BYTE_KIND, linebreak,
Py_ARRAY_LENGTH(linebreak)); Py_ARRAY_LENGTH(linebreak));
}
if (PyType_Ready(&PyUnicode_Type) < 0) { return _PyStatus_OK();
return _PyStatus_ERR("Can't initialize unicode type"); }
}
if (PyType_Ready(&EncodingMapType) < 0) {
return _PyStatus_ERR("Can't initialize encoding map type"); PyStatus
} _PyUnicode_InitTypes(void)
if (PyType_Ready(&PyFieldNameIter_Type) < 0) { {
return _PyStatus_ERR("Can't initialize field name iterator type"); if (PyType_Ready(&PyUnicode_Type) < 0) {
} return _PyStatus_ERR("Can't initialize unicode type");
if (PyType_Ready(&PyFormatterIter_Type) < 0) { }
return _PyStatus_ERR("Can't initialize formatter iter type"); if (PyType_Ready(&EncodingMapType) < 0) {
} return _PyStatus_ERR("Can't initialize encoding map type");
}
if (PyType_Ready(&PyFieldNameIter_Type) < 0) {
return _PyStatus_ERR("Can't initialize field name iterator type");
}
if (PyType_Ready(&PyFormatterIter_Type) < 0) {
return _PyStatus_ERR("Can't initialize formatter iter type");
} }
return _PyStatus_OK(); return _PyStatus_OK();
} }

View File

@ -1192,7 +1192,7 @@ static PyStructSequence_Desc UnraisableHookArgs_desc = {
PyStatus PyStatus
_PyErr_Init(void) _PyErr_InitTypes(void)
{ {
if (UnraisableHookArgsType.tp_name == NULL) { if (UnraisableHookArgsType.tp_name == NULL) {
if (PyStructSequence_InitType2(&UnraisableHookArgsType, if (PyStructSequence_InitType2(&UnraisableHookArgsType,

View File

@ -628,38 +628,16 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
static PyStatus static PyStatus
pycore_init_types(PyInterpreterState *interp) pycore_init_singletons(PyInterpreterState *interp)
{ {
PyStatus status; PyStatus status;
int is_main_interp = _Py_IsMainInterpreter(interp);
status = _PyGC_Init(interp); if (_PyLong_Init(interp) < 0) {
if (_PyStatus_EXCEPTION(status)) {
return status;
}
// Create the empty tuple singleton. It must be created before the first
// PyType_Ready() call since PyType_Ready() creates tuples, for tp_bases
// for example.
status = _PyTuple_Init(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
if (is_main_interp) {
status = _PyTypes_Init();
if (_PyStatus_EXCEPTION(status)) {
return status;
}
}
if (!_PyLong_Init(interp)) {
return _PyStatus_ERR("can't init longs"); return _PyStatus_ERR("can't init longs");
} }
status = _PyUnicode_Init(interp); if (_Py_IsMainInterpreter(interp)) {
if (_PyStatus_EXCEPTION(status)) { _PyFloat_Init();
return status;
} }
status = _PyBytes_Init(interp); status = _PyBytes_Init(interp);
@ -667,22 +645,58 @@ pycore_init_types(PyInterpreterState *interp)
return status; return status;
} }
status = _PyUnicode_Init(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PyTuple_Init(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
return _PyStatus_OK();
}
static PyStatus
pycore_init_types(PyInterpreterState *interp)
{
PyStatus status;
int is_main_interp = _Py_IsMainInterpreter(interp);
if (is_main_interp) {
if (_PyStructSequence_Init() < 0) {
return _PyStatus_ERR("can't initialize structseq");
}
status = _PyTypes_Init();
if (_PyStatus_EXCEPTION(status)) {
return status;
}
if (_PyLong_InitTypes() < 0) {
return _PyStatus_ERR("can't init int type");
}
status = _PyUnicode_InitTypes();
if (_PyStatus_EXCEPTION(status)) {
return status;
}
}
if (is_main_interp) {
if (_PyFloat_InitTypes() < 0) {
return _PyStatus_ERR("can't init float");
}
}
status = _PyExc_Init(interp); status = _PyExc_Init(interp);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
if (is_main_interp) { status = _PyErr_InitTypes();
if (!_PyFloat_Init()) {
return _PyStatus_ERR("can't init float");
}
if (_PyStructSequence_Init() < 0) {
return _PyStatus_ERR("can't initialize structseq");
}
}
status = _PyErr_Init();
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
@ -693,22 +707,15 @@ pycore_init_types(PyInterpreterState *interp)
} }
} }
if (_PyWarnings_InitState(interp) < 0) {
return _PyStatus_ERR("can't initialize warnings");
}
status = _PyAtExit_Init(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
return _PyStatus_OK(); return _PyStatus_OK();
} }
static PyStatus static PyStatus
pycore_init_builtins(PyInterpreterState *interp) pycore_init_builtins(PyThreadState *tstate)
{ {
PyInterpreterState *interp = tstate->interp;
PyObject *bimod = _PyBuiltin_Init(interp); PyObject *bimod = _PyBuiltin_Init(interp);
if (bimod == NULL) { if (bimod == NULL) {
goto error; goto error;
@ -744,6 +751,7 @@ pycore_init_builtins(PyInterpreterState *interp)
} }
interp->import_func = Py_NewRef(import_func); interp->import_func = Py_NewRef(import_func);
assert(!_PyErr_Occurred(tstate));
return _PyStatus_OK(); return _PyStatus_OK();
error: error:
@ -755,29 +763,49 @@ error:
static PyStatus static PyStatus
pycore_interp_init(PyThreadState *tstate) pycore_interp_init(PyThreadState *tstate)
{ {
PyInterpreterState *interp = tstate->interp;
PyStatus status; PyStatus status;
PyObject *sysmod = NULL; PyObject *sysmod = NULL;
status = pycore_init_types(tstate->interp); // Create singletons before the first PyType_Ready() call, since
// PyType_Ready() uses singletons like the Unicode empty string (tp_doc)
// and the empty tuple singletons (tp_bases).
status = pycore_init_singletons(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
// The GC must be initialized before the first GC collection.
status = _PyGC_Init(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = pycore_init_types(interp);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
goto done; goto done;
} }
if (_PyWarnings_InitState(interp) < 0) {
return _PyStatus_ERR("can't initialize warnings");
}
status = _PyAtExit_Init(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
status = _PySys_Create(tstate, &sysmod); status = _PySys_Create(tstate, &sysmod);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
goto done; goto done;
} }
assert(!_PyErr_Occurred(tstate)); status = pycore_init_builtins(tstate);
status = pycore_init_builtins(tstate->interp);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
goto done; goto done;
} }
assert(!_PyErr_Occurred(tstate)); const PyConfig *config = _PyInterpreterState_GetConfig(interp);
const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
if (config->_install_importlib) { if (config->_install_importlib) {
/* This call sets up builtin and frozen import support */ /* This call sets up builtin and frozen import support */
if (init_importlib(tstate, sysmod) < 0) { if (init_importlib(tstate, sysmod) < 0) {