diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index de70199dae5..6f5c5442233 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -30,12 +30,13 @@ extern PyObject * _PyBuiltin_Init(void); extern _PyInitError _PySys_BeginInit(PyObject **sysmod); extern int _PySys_EndInit(PyObject *sysdict, PyInterpreterState *interp); extern _PyInitError _PyImport_Init(PyInterpreterState *interp); -extern _PyInitError _PyExc_Init(PyObject * bltinmod); +extern _PyInitError _PyExc_Init(void); +extern _PyInitError _PyBuiltins_AddExceptions(PyObject * bltinmod); extern _PyInitError _PyImportHooks_Init(void); extern int _PyFloat_Init(void); extern _PyInitError _Py_HashRandomization_Init(const _PyCoreConfig *); -extern void _Py_ReadyTypes(void); +extern _PyInitError _Py_ReadyTypes(void); /* Various internal finalizers */ diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-01-22-18-50-21.bpo-35713.bTeUsa.rst b/Misc/NEWS.d/next/Core and Builtins/2019-01-22-18-50-21.bpo-35713.bTeUsa.rst new file mode 100644 index 00000000000..67e766fa075 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-01-22-18-50-21.bpo-35713.bTeUsa.rst @@ -0,0 +1,2 @@ +Reorganize Python initialization to get working exceptions and sys.stderr +earlier. diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 8d81566c7f1..35e1df3ca1f 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2492,7 +2492,7 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning, #endif /* MS_WINDOWS */ _PyInitError -_PyExc_Init(PyObject *bltinmod) +_PyExc_Init(void) { #define PRE_INIT(TYPE) \ if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \ @@ -2502,21 +2502,6 @@ _PyExc_Init(PyObject *bltinmod) Py_INCREF(PyExc_ ## TYPE); \ } -#define POST_INIT(TYPE) \ - if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) { \ - return _Py_INIT_ERR("Module dictionary insertion problem."); \ - } - -#define INIT_ALIAS(NAME, TYPE) \ - do { \ - Py_INCREF(PyExc_ ## TYPE); \ - Py_XDECREF(PyExc_ ## NAME); \ - PyExc_ ## NAME = PyExc_ ## TYPE; \ - if (PyDict_SetItemString(bdict, # NAME, PyExc_ ## NAME)) { \ - return _Py_INIT_ERR("Module dictionary insertion problem."); \ - } \ - } while (0) - #define ADD_ERRNO(TYPE, CODE) \ do { \ PyObject *_code = PyLong_FromLong(CODE); \ @@ -2526,8 +2511,6 @@ _PyExc_Init(PyObject *bltinmod) Py_DECREF(_code); \ } while (0) - PyObject *bdict; - PRE_INIT(BaseException); PRE_INIT(Exception); PRE_INIT(TypeError); @@ -2596,6 +2579,68 @@ _PyExc_Init(PyObject *bltinmod) PRE_INIT(ProcessLookupError); PRE_INIT(TimeoutError); + if (preallocate_memerrors() < 0) { + return _Py_INIT_ERR("Could not preallocate MemoryError object"); + } + + /* Add exceptions to errnomap */ + if (!errnomap) { + errnomap = PyDict_New(); + if (!errnomap) { + return _Py_INIT_ERR("Cannot allocate map from errnos to OSError subclasses"); + } + } + + ADD_ERRNO(BlockingIOError, EAGAIN); + ADD_ERRNO(BlockingIOError, EALREADY); + ADD_ERRNO(BlockingIOError, EINPROGRESS); + ADD_ERRNO(BlockingIOError, EWOULDBLOCK); + ADD_ERRNO(BrokenPipeError, EPIPE); +#ifdef ESHUTDOWN + ADD_ERRNO(BrokenPipeError, ESHUTDOWN); +#endif + ADD_ERRNO(ChildProcessError, ECHILD); + ADD_ERRNO(ConnectionAbortedError, ECONNABORTED); + ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED); + ADD_ERRNO(ConnectionResetError, ECONNRESET); + ADD_ERRNO(FileExistsError, EEXIST); + ADD_ERRNO(FileNotFoundError, ENOENT); + ADD_ERRNO(IsADirectoryError, EISDIR); + ADD_ERRNO(NotADirectoryError, ENOTDIR); + ADD_ERRNO(InterruptedError, EINTR); + ADD_ERRNO(PermissionError, EACCES); + ADD_ERRNO(PermissionError, EPERM); + ADD_ERRNO(ProcessLookupError, ESRCH); + ADD_ERRNO(TimeoutError, ETIMEDOUT); + + return _Py_INIT_OK(); + +#undef PRE_INIT +#undef ADD_ERRNO +} + + +/* Add exception types to the builtins module */ +_PyInitError +_PyBuiltins_AddExceptions(PyObject *bltinmod) +{ +#define POST_INIT(TYPE) \ + if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) { \ + return _Py_INIT_ERR("Module dictionary insertion problem."); \ + } + +#define INIT_ALIAS(NAME, TYPE) \ + do { \ + Py_INCREF(PyExc_ ## TYPE); \ + Py_XDECREF(PyExc_ ## NAME); \ + PyExc_ ## NAME = PyExc_ ## TYPE; \ + if (PyDict_SetItemString(bdict, # NAME, PyExc_ ## NAME)) { \ + return _Py_INIT_ERR("Module dictionary insertion problem."); \ + } \ + } while (0) + + PyObject *bdict; + bdict = PyModule_GetDict(bltinmod); if (bdict == NULL) { return _Py_INIT_ERR("exceptions bootstrapping error."); @@ -2656,61 +2701,28 @@ _PyExc_Init(PyObject *bltinmod) POST_INIT(BytesWarning); POST_INIT(ResourceWarning); - if (!errnomap) { - errnomap = PyDict_New(); - if (!errnomap) { - return _Py_INIT_ERR("Cannot allocate map from errnos to OSError subclasses"); - } - } - /* OSError subclasses */ POST_INIT(ConnectionError); POST_INIT(BlockingIOError); - ADD_ERRNO(BlockingIOError, EAGAIN); - ADD_ERRNO(BlockingIOError, EALREADY); - ADD_ERRNO(BlockingIOError, EINPROGRESS); - ADD_ERRNO(BlockingIOError, EWOULDBLOCK); POST_INIT(BrokenPipeError); - ADD_ERRNO(BrokenPipeError, EPIPE); -#ifdef ESHUTDOWN - ADD_ERRNO(BrokenPipeError, ESHUTDOWN); -#endif POST_INIT(ChildProcessError); - ADD_ERRNO(ChildProcessError, ECHILD); POST_INIT(ConnectionAbortedError); - ADD_ERRNO(ConnectionAbortedError, ECONNABORTED); POST_INIT(ConnectionRefusedError); - ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED); POST_INIT(ConnectionResetError); - ADD_ERRNO(ConnectionResetError, ECONNRESET); POST_INIT(FileExistsError); - ADD_ERRNO(FileExistsError, EEXIST); POST_INIT(FileNotFoundError); - ADD_ERRNO(FileNotFoundError, ENOENT); POST_INIT(IsADirectoryError); - ADD_ERRNO(IsADirectoryError, EISDIR); POST_INIT(NotADirectoryError); - ADD_ERRNO(NotADirectoryError, ENOTDIR); POST_INIT(InterruptedError); - ADD_ERRNO(InterruptedError, EINTR); POST_INIT(PermissionError); - ADD_ERRNO(PermissionError, EACCES); - ADD_ERRNO(PermissionError, EPERM); POST_INIT(ProcessLookupError); - ADD_ERRNO(ProcessLookupError, ESRCH); POST_INIT(TimeoutError); - ADD_ERRNO(TimeoutError, ETIMEDOUT); - if (preallocate_memerrors() < 0) { - return _Py_INIT_ERR("Could not preallocate MemoryError object"); - } return _Py_INIT_OK(); -#undef PRE_INIT #undef POST_INIT #undef INIT_ALIAS -#undef ADD_ERRNO } void diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 313f1d0ac55..babaa05bdbc 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -359,6 +359,9 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args) Py_ssize_t n; int err; + /* The function can clear the current exception */ + assert(!PyErr_Occurred()); + if (self->fd < 0) { /* fd might be invalid on Windows * I can't raise an exception here. It may lead to an @@ -367,10 +370,11 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args) Py_RETURN_NONE; } - if (!PyArg_ParseTuple(args, "U", &unicode)) + if (!PyArg_ParseTuple(args, "U", &unicode)) { return NULL; + } - /* encode Unicode to UTF-8 */ + /* Encode Unicode to UTF-8/surrogateescape */ str = PyUnicode_AsUTF8AndSize(unicode, &n); if (str == NULL) { PyErr_Clear(); diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 67f9e5d5b4e..b952df88072 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1999,8 +1999,9 @@ _PyFloat_Init(void) /* Init float info */ if (FloatInfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) + if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) { return 0; + } } return 1; } diff --git a/Objects/longobject.c b/Objects/longobject.c index f42683e9d02..3c98385f539 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -5635,8 +5635,9 @@ _PyLong_Init(void) /* initialize int_info */ if (Int_InfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) + if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) { return 0; + } } return 1; diff --git a/Objects/object.c b/Objects/object.c index 6c2bd7717c0..2171d53523f 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1716,200 +1716,83 @@ PyObject _Py_NotImplementedStruct = { 1, &_PyNotImplemented_Type }; -void +_PyInitError _Py_ReadyTypes(void) { - if (PyType_Ready(&PyBaseObject_Type) < 0) - Py_FatalError("Can't initialize object type"); +#define INIT_TYPE(TYPE, NAME) \ + do { \ + if (PyType_Ready(TYPE) < 0) { \ + return _Py_INIT_ERR("Can't initialize " NAME " type"); \ + } \ + } while (0) - if (PyType_Ready(&PyType_Type) < 0) - Py_FatalError("Can't initialize type type"); + INIT_TYPE(&PyBaseObject_Type, "object"); + INIT_TYPE(&PyType_Type, "type"); + INIT_TYPE(&_PyWeakref_RefType, "weakref"); + INIT_TYPE(&_PyWeakref_CallableProxyType, "callable weakref proxy"); + INIT_TYPE(&_PyWeakref_ProxyType, "weakref proxy"); + INIT_TYPE(&PyLong_Type, "int"); + INIT_TYPE(&PyBool_Type, "bool"); + INIT_TYPE(&PyByteArray_Type, "bytearray"); + INIT_TYPE(&PyBytes_Type, "str"); + INIT_TYPE(&PyList_Type, "list"); + INIT_TYPE(&_PyNone_Type, "None"); + INIT_TYPE(&_PyNotImplemented_Type, "NotImplemented"); + INIT_TYPE(&PyTraceBack_Type, "traceback"); + INIT_TYPE(&PySuper_Type, "super"); + INIT_TYPE(&PyRange_Type, "range"); + INIT_TYPE(&PyDict_Type, "dict"); + INIT_TYPE(&PyDictKeys_Type, "dict keys"); + INIT_TYPE(&PyDictValues_Type, "dict values"); + INIT_TYPE(&PyDictItems_Type, "dict items"); + INIT_TYPE(&PyDictRevIterKey_Type, "reversed dict keys"); + INIT_TYPE(&PyDictRevIterValue_Type, "reversed dict values"); + INIT_TYPE(&PyDictRevIterItem_Type, "reversed dict items"); + INIT_TYPE(&PyODict_Type, "OrderedDict"); + INIT_TYPE(&PyODictKeys_Type, "odict_keys"); + INIT_TYPE(&PyODictItems_Type, "odict_items"); + INIT_TYPE(&PyODictValues_Type, "odict_values"); + INIT_TYPE(&PyODictIter_Type, "odict_keyiterator"); + INIT_TYPE(&PySet_Type, "set"); + INIT_TYPE(&PyUnicode_Type, "str"); + INIT_TYPE(&PySlice_Type, "slice"); + INIT_TYPE(&PyStaticMethod_Type, "static method"); + INIT_TYPE(&PyComplex_Type, "complex"); + INIT_TYPE(&PyFloat_Type, "float"); + INIT_TYPE(&PyFrozenSet_Type, "frozenset"); + INIT_TYPE(&PyProperty_Type, "property"); + INIT_TYPE(&_PyManagedBuffer_Type, "managed buffer"); + INIT_TYPE(&PyMemoryView_Type, "memoryview"); + INIT_TYPE(&PyTuple_Type, "tuple"); + INIT_TYPE(&PyEnum_Type, "enumerate"); + INIT_TYPE(&PyReversed_Type, "reversed"); + INIT_TYPE(&PyStdPrinter_Type, "StdPrinter"); + INIT_TYPE(&PyCode_Type, "code"); + INIT_TYPE(&PyFrame_Type, "frame"); + INIT_TYPE(&PyCFunction_Type, "builtin function"); + INIT_TYPE(&PyMethod_Type, "method"); + INIT_TYPE(&PyFunction_Type, "function"); + INIT_TYPE(&PyDictProxy_Type, "dict proxy"); + INIT_TYPE(&PyGen_Type, "generator"); + INIT_TYPE(&PyGetSetDescr_Type, "get-set descriptor"); + INIT_TYPE(&PyWrapperDescr_Type, "wrapper"); + INIT_TYPE(&_PyMethodWrapper_Type, "method wrapper"); + INIT_TYPE(&PyEllipsis_Type, "ellipsis"); + INIT_TYPE(&PyMemberDescr_Type, "member descriptor"); + INIT_TYPE(&_PyNamespace_Type, "namespace"); + INIT_TYPE(&PyCapsule_Type, "capsule"); + INIT_TYPE(&PyLongRangeIter_Type, "long range iterator"); + INIT_TYPE(&PyCell_Type, "cell"); + INIT_TYPE(&PyInstanceMethod_Type, "instance method"); + INIT_TYPE(&PyClassMethodDescr_Type, "class method descr"); + INIT_TYPE(&PyMethodDescr_Type, "method descr"); + INIT_TYPE(&PyCallIter_Type, "call iter"); + INIT_TYPE(&PySeqIter_Type, "sequence iterator"); + INIT_TYPE(&PyCoro_Type, "coroutine"); + INIT_TYPE(&_PyCoroWrapper_Type, "coroutine wrapper"); + return _Py_INIT_OK(); - if (PyType_Ready(&_PyWeakref_RefType) < 0) - Py_FatalError("Can't initialize weakref type"); - - if (PyType_Ready(&_PyWeakref_CallableProxyType) < 0) - Py_FatalError("Can't initialize callable weakref proxy type"); - - if (PyType_Ready(&_PyWeakref_ProxyType) < 0) - Py_FatalError("Can't initialize weakref proxy type"); - - if (PyType_Ready(&PyLong_Type) < 0) - Py_FatalError("Can't initialize int type"); - - if (PyType_Ready(&PyBool_Type) < 0) - Py_FatalError("Can't initialize bool type"); - - if (PyType_Ready(&PyByteArray_Type) < 0) - Py_FatalError("Can't initialize bytearray type"); - - if (PyType_Ready(&PyBytes_Type) < 0) - Py_FatalError("Can't initialize 'str'"); - - if (PyType_Ready(&PyList_Type) < 0) - Py_FatalError("Can't initialize list type"); - - if (PyType_Ready(&_PyNone_Type) < 0) - Py_FatalError("Can't initialize None type"); - - if (PyType_Ready(&_PyNotImplemented_Type) < 0) - Py_FatalError("Can't initialize NotImplemented type"); - - if (PyType_Ready(&PyTraceBack_Type) < 0) - Py_FatalError("Can't initialize traceback type"); - - if (PyType_Ready(&PySuper_Type) < 0) - Py_FatalError("Can't initialize super type"); - - if (PyType_Ready(&PyRange_Type) < 0) - Py_FatalError("Can't initialize range type"); - - if (PyType_Ready(&PyDict_Type) < 0) - Py_FatalError("Can't initialize dict type"); - - if (PyType_Ready(&PyDictKeys_Type) < 0) - Py_FatalError("Can't initialize dict keys type"); - - if (PyType_Ready(&PyDictValues_Type) < 0) - Py_FatalError("Can't initialize dict values type"); - - if (PyType_Ready(&PyDictItems_Type) < 0) - Py_FatalError("Can't initialize dict items type"); - - if (PyType_Ready(&PyDictRevIterKey_Type) < 0) - Py_FatalError("Can't initialize reversed dict keys type"); - - if (PyType_Ready(&PyDictRevIterValue_Type) < 0) - Py_FatalError("Can't initialize reversed dict values type"); - - if (PyType_Ready(&PyDictRevIterItem_Type) < 0) - Py_FatalError("Can't initialize reversed dict items type"); - - if (PyType_Ready(&PyODict_Type) < 0) - Py_FatalError("Can't initialize OrderedDict type"); - - if (PyType_Ready(&PyODictKeys_Type) < 0) - Py_FatalError("Can't initialize odict_keys type"); - - if (PyType_Ready(&PyODictItems_Type) < 0) - Py_FatalError("Can't initialize odict_items type"); - - if (PyType_Ready(&PyODictValues_Type) < 0) - Py_FatalError("Can't initialize odict_values type"); - - if (PyType_Ready(&PyODictIter_Type) < 0) - Py_FatalError("Can't initialize odict_keyiterator type"); - - if (PyType_Ready(&PySet_Type) < 0) - Py_FatalError("Can't initialize set type"); - - if (PyType_Ready(&PyUnicode_Type) < 0) - Py_FatalError("Can't initialize str type"); - - if (PyType_Ready(&PySlice_Type) < 0) - Py_FatalError("Can't initialize slice type"); - - if (PyType_Ready(&PyStaticMethod_Type) < 0) - Py_FatalError("Can't initialize static method type"); - - if (PyType_Ready(&PyComplex_Type) < 0) - Py_FatalError("Can't initialize complex type"); - - if (PyType_Ready(&PyFloat_Type) < 0) - Py_FatalError("Can't initialize float type"); - - if (PyType_Ready(&PyFrozenSet_Type) < 0) - Py_FatalError("Can't initialize frozenset type"); - - if (PyType_Ready(&PyProperty_Type) < 0) - Py_FatalError("Can't initialize property type"); - - if (PyType_Ready(&_PyManagedBuffer_Type) < 0) - Py_FatalError("Can't initialize managed buffer type"); - - if (PyType_Ready(&PyMemoryView_Type) < 0) - Py_FatalError("Can't initialize memoryview type"); - - if (PyType_Ready(&PyTuple_Type) < 0) - Py_FatalError("Can't initialize tuple type"); - - if (PyType_Ready(&PyEnum_Type) < 0) - Py_FatalError("Can't initialize enumerate type"); - - if (PyType_Ready(&PyReversed_Type) < 0) - Py_FatalError("Can't initialize reversed type"); - - if (PyType_Ready(&PyStdPrinter_Type) < 0) - Py_FatalError("Can't initialize StdPrinter"); - - if (PyType_Ready(&PyCode_Type) < 0) - Py_FatalError("Can't initialize code type"); - - if (PyType_Ready(&PyFrame_Type) < 0) - Py_FatalError("Can't initialize frame type"); - - if (PyType_Ready(&PyCFunction_Type) < 0) - Py_FatalError("Can't initialize builtin function type"); - - if (PyType_Ready(&PyMethod_Type) < 0) - Py_FatalError("Can't initialize method type"); - - if (PyType_Ready(&PyFunction_Type) < 0) - Py_FatalError("Can't initialize function type"); - - if (PyType_Ready(&PyDictProxy_Type) < 0) - Py_FatalError("Can't initialize dict proxy type"); - - if (PyType_Ready(&PyGen_Type) < 0) - Py_FatalError("Can't initialize generator type"); - - if (PyType_Ready(&PyGetSetDescr_Type) < 0) - Py_FatalError("Can't initialize get-set descriptor type"); - - if (PyType_Ready(&PyWrapperDescr_Type) < 0) - Py_FatalError("Can't initialize wrapper type"); - - if (PyType_Ready(&_PyMethodWrapper_Type) < 0) - Py_FatalError("Can't initialize method wrapper type"); - - if (PyType_Ready(&PyEllipsis_Type) < 0) - Py_FatalError("Can't initialize ellipsis type"); - - if (PyType_Ready(&PyMemberDescr_Type) < 0) - Py_FatalError("Can't initialize member descriptor type"); - - if (PyType_Ready(&_PyNamespace_Type) < 0) - Py_FatalError("Can't initialize namespace type"); - - if (PyType_Ready(&PyCapsule_Type) < 0) - Py_FatalError("Can't initialize capsule type"); - - if (PyType_Ready(&PyLongRangeIter_Type) < 0) - Py_FatalError("Can't initialize long range iterator type"); - - if (PyType_Ready(&PyCell_Type) < 0) - Py_FatalError("Can't initialize cell type"); - - if (PyType_Ready(&PyInstanceMethod_Type) < 0) - Py_FatalError("Can't initialize instance method type"); - - if (PyType_Ready(&PyClassMethodDescr_Type) < 0) - Py_FatalError("Can't initialize class method descr type"); - - if (PyType_Ready(&PyMethodDescr_Type) < 0) - Py_FatalError("Can't initialize method descr type"); - - if (PyType_Ready(&PyCallIter_Type) < 0) - Py_FatalError("Can't initialize call iter type"); - - if (PyType_Ready(&PySeqIter_Type) < 0) - Py_FatalError("Can't initialize sequence iterator type"); - - if (PyType_Ready(&PyCoro_Type) < 0) - Py_FatalError("Can't initialize coroutine type"); - - if (PyType_Ready(&_PyCoroWrapper_Type) < 0) - Py_FatalError("Can't initialize coroutine wrapper type"); +#undef INIT_TYPE } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index ea7bcabfc64..8141ce75741 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -15239,7 +15239,6 @@ _PyUnicode_Init(void) if (PyType_Ready(&PyFormatterIter_Type) < 0) { return _Py_INIT_ERR("Can't initialize formatter iter type"); } - return _Py_INIT_OK(); } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index f0e00ea48d4..86d87fb6030 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -464,9 +464,22 @@ _Py_SetLocaleFromEnv(int category) */ static _PyInitError -_Py_Initialize_ReconfigureCore(PyInterpreterState *interp, +_Py_Initialize_ReconfigureCore(PyInterpreterState **interp_p, const _PyCoreConfig *core_config) { + PyThreadState *tstate = _PyThreadState_GET(); + if (!tstate) { + return _Py_INIT_ERR("failed to read thread state"); + } + + PyInterpreterState *interp = tstate->interp; + if (interp == NULL) { + return _Py_INIT_ERR("can't make main interpreter"); + } + *interp_p = interp; + + /* bpo-34008: For backward compatibility reasons, calling Py_Main() after + Py_Initialize() ignores the new configuration. */ if (core_config->allocator != NULL) { const char *allocator = _PyMem_GetAllocatorsName(); if (allocator == NULL || strcmp(core_config->allocator, allocator) != 0) { @@ -492,57 +505,16 @@ _Py_Initialize_ReconfigureCore(PyInterpreterState *interp, } -/* Begin interpreter initialization - * - * On return, the first thread and interpreter state have been created, - * but the compiler, signal handling, multithreading and - * multiple interpreter support, and codec infrastructure are not yet - * available. - * - * The import system will support builtin and frozen modules only. - * The only supported io is writing to sys.stderr - * - * If any operation invoked by this function fails, a fatal error is - * issued and the function does not return. - * - * Any code invoked from this function should *not* assume it has access - * to the Python C API (unless the API is explicitly listed as being - * safe to call without calling Py_Initialize first) - * - * The caller is responsible to call _PyCoreConfig_Read(). - */ - static _PyInitError -_Py_InitializeCore_impl(PyInterpreterState **interp_p, - const _PyCoreConfig *core_config) +pycore_init_runtime(const _PyCoreConfig *core_config) { - PyInterpreterState *interp; - _PyInitError err; - - /* bpo-34008: For backward compatibility reasons, calling Py_Main() after - Py_Initialize() ignores the new configuration. */ - if (_PyRuntime.core_initialized) { - PyThreadState *tstate = _PyThreadState_GET(); - if (!tstate) { - return _Py_INIT_ERR("failed to read thread state"); - } - - interp = tstate->interp; - if (interp == NULL) { - return _Py_INIT_ERR("can't make main interpreter"); - } - *interp_p = interp; - - return _Py_Initialize_ReconfigureCore(interp, core_config); - } - if (_PyRuntime.initialized) { return _Py_INIT_ERR("main interpreter already initialized"); } _PyCoreConfig_SetGlobalConfig(core_config); - err = _PyRuntime_Initialize(); + _PyInitError err = _PyRuntime_Initialize(); if (_Py_INIT_FAILED(err)) { return err; } @@ -573,8 +545,15 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, if (_Py_INIT_FAILED(err)) { return err; } + return _Py_INIT_OK(); +} - interp = PyInterpreterState_New(); + +static _PyInitError +pycore_create_interpreter(const _PyCoreConfig *core_config, + PyInterpreterState **interp_p) +{ + PyInterpreterState *interp = PyInterpreterState_New(); if (interp == NULL) { return _Py_INIT_ERR("can't make main interpreter"); } @@ -603,24 +582,61 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, /* Create the GIL */ PyEval_InitThreads(); - _Py_ReadyTypes(); + return _Py_INIT_OK(); +} - if (!_PyLong_Init()) + +static _PyInitError +pycore_init_types(void) +{ + _PyInitError err = _Py_ReadyTypes(); + if (_Py_INIT_FAILED(err)) { + return err; + } + + err = _PyUnicode_Init(); + if (_Py_INIT_FAILED(err)) { + return err; + } + + if (_PyStructSequence_Init() < 0) { + return _Py_INIT_ERR("can't initialize structseq"); + } + + if (!_PyLong_Init()) { return _Py_INIT_ERR("can't init longs"); + } - if (!_PyFloat_Init()) + err = _PyExc_Init(); + if (_Py_INIT_FAILED(err)) { + return err; + } + + if (!_PyFloat_Init()) { return _Py_INIT_ERR("can't init float"); + } + if (!_PyContext_Init()) { + return _Py_INIT_ERR("can't init context"); + } + return _Py_INIT_OK(); +} + + +static _PyInitError +pycore_init_sys(PyInterpreterState *interp, PyObject **sysmod_p) +{ PyObject *modules = PyDict_New(); if (modules == NULL) return _Py_INIT_ERR("can't make modules dictionary"); interp->modules = modules; PyObject *sysmod; - err = _PySys_BeginInit(&sysmod); + _PyInitError err = _PySys_BeginInit(&sysmod); if (_Py_INIT_FAILED(err)) { return err; } + *sysmod_p = sysmod; interp->sysdict = PyModule_GetDict(sysmod); if (interp->sysdict == NULL) { @@ -631,39 +647,49 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, PyDict_SetItemString(interp->sysdict, "modules", modules); _PyImport_FixupBuiltin(sysmod, "sys", modules); - err = _PyUnicode_Init(); - if (_Py_INIT_FAILED(err)) { - return err; - } - - if (_PyStructSequence_Init() < 0) - return _Py_INIT_ERR("can't initialize structseq"); - - PyObject *bimod = _PyBuiltin_Init(); - if (bimod == NULL) - return _Py_INIT_ERR("can't initialize builtins modules"); - _PyImport_FixupBuiltin(bimod, "builtins", modules); - interp->builtins = PyModule_GetDict(bimod); - if (interp->builtins == NULL) - return _Py_INIT_ERR("can't initialize builtins dict"); - Py_INCREF(interp->builtins); - - /* initialize builtin exceptions */ - err = _PyExc_Init(bimod); - if (_Py_INIT_FAILED(err)) { - return err; - } - /* Set up a preliminary stderr printer until we have enough - infrastructure for the io module in place. */ + infrastructure for the io module in place. + + Use UTF-8/surrogateescape and ignore EAGAIN errors. */ PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr)); - if (pstderr == NULL) + if (pstderr == NULL) { return _Py_INIT_ERR("can't set preliminary stderr"); + } _PySys_SetObjectId(&PyId_stderr, pstderr); PySys_SetObject("__stderr__", pstderr); Py_DECREF(pstderr); - err = _PyImport_Init(interp); + return _Py_INIT_OK(); +} + + +static _PyInitError +pycore_init_builtins(PyInterpreterState *interp) +{ + PyObject *bimod = _PyBuiltin_Init(); + if (bimod == NULL) { + return _Py_INIT_ERR("can't initialize builtins modules"); + } + _PyImport_FixupBuiltin(bimod, "builtins", interp->modules); + + interp->builtins = PyModule_GetDict(bimod); + if (interp->builtins == NULL) { + return _Py_INIT_ERR("can't initialize builtins dict"); + } + Py_INCREF(interp->builtins); + + _PyInitError err = _PyBuiltins_AddExceptions(bimod); + if (_Py_INIT_FAILED(err)) { + return err; + } + return _Py_INIT_OK(); +} + + +static _PyInitError +pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod) +{ + _PyInitError err = _PyImport_Init(interp); if (_Py_INIT_FAILED(err)) { return err; } @@ -678,29 +704,85 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, return _Py_INIT_ERR("can't initialize warnings"); } - if (!_PyContext_Init()) - return _Py_INIT_ERR("can't init context"); - - if (core_config->_install_importlib) { - err = _PyCoreConfig_SetPathConfig(core_config); + if (interp->core_config._install_importlib) { + err = _PyCoreConfig_SetPathConfig(&interp->core_config); if (_Py_INIT_FAILED(err)) { return err; } } /* This call sets up builtin and frozen import support */ - if (core_config->_install_importlib) { + if (interp->core_config._install_importlib) { err = initimport(interp, sysmod); if (_Py_INIT_FAILED(err)) { return err; } } + return _Py_INIT_OK(); +} + + +static _PyInitError +_Py_InitializeCore_impl(PyInterpreterState **interp_p, + const _PyCoreConfig *core_config) +{ + PyInterpreterState *interp; + + _PyInitError err = pycore_init_runtime(core_config); + if (_Py_INIT_FAILED(err)) { + return err; + } + + err = pycore_create_interpreter(core_config, &interp); + if (_Py_INIT_FAILED(err)) { + return err; + } + core_config = &interp->core_config; + *interp_p = interp; + + err = pycore_init_types(); + if (_Py_INIT_FAILED(err)) { + return err; + } + + PyObject *sysmod; + err = pycore_init_sys(interp, &sysmod); + if (_Py_INIT_FAILED(err)) { + return err; + } + + err = pycore_init_builtins(interp); + if (_Py_INIT_FAILED(err)) { + return err; + } + + err = pycore_init_import_warnings(interp, sysmod); + if (_Py_INIT_FAILED(err)) { + return err; + } /* Only when we get here is the runtime core fully initialized */ _PyRuntime.core_initialized = 1; return _Py_INIT_OK(); } +/* Begin interpreter initialization + * + * On return, the first thread and interpreter state have been created, + * but the compiler, signal handling, multithreading and + * multiple interpreter support, and codec infrastructure are not yet + * available. + * + * The import system will support builtin and frozen modules only. + * The only supported io is writing to sys.stderr + * + * If any operation invoked by this function fails, a fatal error is + * issued and the function does not return. + * + * Any code invoked from this function should *not* assume it has access + * to the Python C API (unless the API is explicitly listed as being + * safe to call without calling Py_Initialize first) + */ _PyInitError _Py_InitializeCore(PyInterpreterState **interp_p, const _PyCoreConfig *src_config) @@ -730,7 +812,12 @@ _Py_InitializeCore(PyInterpreterState **interp_p, goto done; } - err = _Py_InitializeCore_impl(interp_p, &config); + if (!_PyRuntime.core_initialized) { + err = _Py_InitializeCore_impl(interp_p, &config); + } + else { + err = _Py_Initialize_ReconfigureCore(interp_p, &config); + } done: _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); @@ -1270,6 +1357,11 @@ new_interpreter(PyThreadState **tstate_p) return _Py_INIT_ERR("failed to copy main interpreter config"); } + err = _PyExc_Init(); + if (_Py_INIT_FAILED(err)) { + return err; + } + /* XXX The following is lax in error checking */ PyObject *modules = PyDict_New(); if (modules == NULL) { @@ -1301,18 +1393,15 @@ new_interpreter(PyThreadState **tstate_p) goto handle_error; } - /* initialize builtin exceptions */ - err = _PyExc_Init(bimod); - if (_Py_INIT_FAILED(err)) { - return err; - } - if (bimod != NULL && sysmod != NULL) { - PyObject *pstderr; + err = _PyBuiltins_AddExceptions(bimod); + if (_Py_INIT_FAILED(err)) { + return err; + } /* Set up a preliminary stderr printer until we have enough infrastructure for the io module in place. */ - pstderr = PyFile_NewStdPrinter(fileno(stderr)); + PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr)); if (pstderr == NULL) { return _Py_INIT_ERR("can't set preliminary stderr"); }