diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2017-11-15 23:48:08 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-15 23:48:08 (GMT) |
commit | f7e5b56c37eb859e225e886c79c5d742c567ee95 (patch) | |
tree | 7d722ca38595aaa68e02a1ee1ea53e17a54b0188 /Include/pylifecycle.h | |
parent | 43605e6bfa8d49612df4a38460d063d6ba781906 (diff) | |
download | cpython-f7e5b56c37eb859e225e886c79c5d742c567ee95.zip cpython-f7e5b56c37eb859e225e886c79c5d742c567ee95.tar.gz cpython-f7e5b56c37eb859e225e886c79c5d742c567ee95.tar.bz2 |
bpo-32030: Split Py_Main() into subfunctions (#4399)
* Don't use "Python runtime" anymore to parse command line options or
to get environment variables: pymain_init() is now a strict
separation.
* Use an error message rather than "crashing" directly with
Py_FatalError(). Limit the number of calls to Py_FatalError(). It
prepares the code to handle errors more nicely later.
* Warnings options (-W, PYTHONWARNINGS) and "XOptions" (-X) are now
only added to the sys module once Python core is properly
initialized.
* _PyMain is now the well identified owner of some important strings
like: warnings options, XOptions, and the "program name". The
program name string is now properly freed at exit.
pymain_free() is now responsible to free the "command" string.
* Rename most methods in Modules/main.c to use a "pymain_" prefix to
avoid conflits and ease debug.
* Replace _Py_CommandLineDetails_INIT with memset(0)
* Reorder a lot of code to fix the initialization ordering. For
example, initializing standard streams now comes before parsing
PYTHONWARNINGS.
* Py_Main() now handles errors when adding warnings options and
XOptions.
* Add _PyMem_GetDefaultRawAllocator() private function.
* Cleanup _PyMem_Initialize(): remove useless global constants: move
them into _PyMem_Initialize().
* Call _PyRuntime_Initialize() as soon as possible:
_PyRuntime_Initialize() now returns an error message on failure.
* Add _PyInitError structure and following macros:
* _Py_INIT_OK()
* _Py_INIT_ERR(msg)
* _Py_INIT_USER_ERR(msg): "user" error, don't abort() in that case
* _Py_INIT_FAILED(err)
Diffstat (limited to 'Include/pylifecycle.h')
-rw-r--r-- | Include/pylifecycle.h | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h index f7286f3..a75b77c 100644 --- a/Include/pylifecycle.h +++ b/Include/pylifecycle.h @@ -20,18 +20,44 @@ PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void); PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding, const char *errors); +typedef struct { + const char *prefix; + const char *msg; + int user_err; +} _PyInitError; + +/* Almost all errors causing Python initialization to fail */ +#ifdef _MSC_VER + /* Visual Studio 2015 doesn't implement C99 __func__ in C */ +# define _Py_INIT_GET_FUNC() __FUNCTION__ +#else +# define _Py_INIT_GET_FUNC() __func__ +#endif + +#define _Py_INIT_OK() \ + (_PyInitError){.prefix = NULL, .msg = NULL, .user_err = 0} +#define _Py_INIT_ERR(MSG) \ + (_PyInitError){.prefix = _Py_INIT_GET_FUNC(), .msg = (MSG), .user_err = 0} +/* Error that can be fixed by the user like invalid input parameter. + Don't abort() the process on such error. */ +#define _Py_INIT_USER_ERR(MSG) \ + (_PyInitError){.prefix = _Py_INIT_GET_FUNC(), .msg = (MSG), .user_err = 1} +#define _Py_INIT_FAILED(err) \ + (err.msg != NULL) + /* PEP 432 Multi-phase initialization API (Private while provisional!) */ -PyAPI_FUNC(void) _Py_InitializeCore(const _PyCoreConfig *); +PyAPI_FUNC(_PyInitError) _Py_InitializeCore(const _PyCoreConfig *); PyAPI_FUNC(int) _Py_IsCoreInitialized(void); -PyAPI_FUNC(int) _Py_ReadMainInterpreterConfig(_PyMainInterpreterConfig *); -PyAPI_FUNC(int) _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *); +PyAPI_FUNC(_PyInitError) _Py_ReadMainInterpreterConfig(_PyMainInterpreterConfig *); +PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *); #endif /* Initialization and finalization */ PyAPI_FUNC(void) Py_Initialize(void); PyAPI_FUNC(void) Py_InitializeEx(int); #ifndef Py_LIMITED_API -PyAPI_FUNC(void) _Py_InitializeEx_Private(int, int); +PyAPI_FUNC(_PyInitError) _Py_InitializeEx_Private(int, int); +PyAPI_FUNC(void) _Py_FatalInitError(_PyInitError err) _Py_NO_RETURN; #endif PyAPI_FUNC(void) Py_Finalize(void); PyAPI_FUNC(int) Py_FinalizeEx(void); @@ -50,7 +76,7 @@ PyAPI_FUNC(void) _Py_PyAtExit(void (*func)(void)); #endif PyAPI_FUNC(int) Py_AtExit(void (*func)(void)); -PyAPI_FUNC(void) Py_Exit(int); +PyAPI_FUNC(void) Py_Exit(int) _Py_NO_RETURN; /* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */ #ifndef Py_LIMITED_API @@ -86,15 +112,15 @@ PyAPI_FUNC(const char *) _Py_gitversion(void); /* Internal -- various one-time initializations */ #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void); -PyAPI_FUNC(PyObject *) _PySys_BeginInit(void); +PyAPI_FUNC(_PyInitError) _PySys_BeginInit(PyObject **sysmod); PyAPI_FUNC(int) _PySys_EndInit(PyObject *sysdict); -PyAPI_FUNC(void) _PyImport_Init(void); +PyAPI_FUNC(_PyInitError) _PyImport_Init(void); PyAPI_FUNC(void) _PyExc_Init(PyObject * bltinmod); -PyAPI_FUNC(void) _PyImportHooks_Init(void); +PyAPI_FUNC(_PyInitError) _PyImportHooks_Init(void); PyAPI_FUNC(int) _PyFrame_Init(void); PyAPI_FUNC(int) _PyFloat_Init(void); PyAPI_FUNC(int) PyByteArray_Init(void); -PyAPI_FUNC(void) _Py_HashRandomization_Init(_PyCoreConfig *core_config); +PyAPI_FUNC(_PyInitError) _Py_HashRandomization_Init(_PyCoreConfig *core_config); #endif /* Various internal finalizers */ |