From 871ff77c1cd334a141d52b0d003c080a1928731e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 17 May 2019 23:54:00 +0200 Subject: [PATCH] bpo-36763: Add _PyInitError functions (GH-13395) * Add _PyInitError functions: * _PyInitError_Ok() * _PyInitError_Error() * _PyInitError_NoMemory() * _PyInitError_Exit() * _PyInitError_IsError() * _PyInitError_IsExit() * _PyInitError_Failed() * frozenmain.c and _testembed.c now use functions rather than macros. * Move _Py_INIT_xxx() macros to the internal API. * Move _PyWstrList_INIT macro to the internal API. --- Include/cpython/coreconfig.h | 37 ++++---------------- Include/internal/pycore_coreconfig.h | 32 +++++++++++++++++ Modules/faulthandler.c | 1 + Modules/getpath.c | 1 + Objects/exceptions.c | 1 + Objects/object.c | 1 + PC/getpathp.c | 1 + Programs/_freeze_importlib.c | 2 +- Programs/_testembed.c | 52 ++++++++++++++-------------- Python/bootstrap_hash.c | 1 + Python/coreconfig.c | 28 +++++++++++++++ Python/frozenmain.c | 4 +-- 12 files changed, 102 insertions(+), 59 deletions(-) diff --git a/Include/cpython/coreconfig.h b/Include/cpython/coreconfig.h index 73861a96d77..f05eddad912 100644 --- a/Include/cpython/coreconfig.h +++ b/Include/cpython/coreconfig.h @@ -18,34 +18,13 @@ typedef struct { int exitcode; } _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){._type = _Py_INIT_ERR_TYPE_OK,} - /* other fields are set to 0 */ -#define _Py_INIT_ERR(ERR_MSG) \ - (_PyInitError){ \ - ._type = _Py_INIT_ERR_TYPE_ERROR, \ - ._func = _Py_INIT_GET_FUNC(), \ - .err_msg = (ERR_MSG)} - /* other fields are set to 0 */ -#define _Py_INIT_NO_MEMORY() _Py_INIT_ERR("memory allocation failed") -#define _Py_INIT_EXIT(EXITCODE) \ - (_PyInitError){ \ - ._type = _Py_INIT_ERR_TYPE_EXIT, \ - .exitcode = (EXITCODE)} -#define _Py_INIT_IS_ERROR(err) \ - (err._type == _Py_INIT_ERR_TYPE_ERROR) -#define _Py_INIT_IS_EXIT(err) \ - (err._type == _Py_INIT_ERR_TYPE_EXIT) -#define _Py_INIT_FAILED(err) \ - (err._type != _Py_INIT_ERR_TYPE_OK) +PyAPI_FUNC(_PyInitError) _PyInitError_Ok(void); +PyAPI_FUNC(_PyInitError) _PyInitError_Error(const char *err_msg); +PyAPI_FUNC(_PyInitError) _PyInitError_NoMemory(void); +PyAPI_FUNC(_PyInitError) _PyInitError_Exit(int exitcode); +PyAPI_FUNC(int) _PyInitError_IsError(_PyInitError err); +PyAPI_FUNC(int) _PyInitError_IsExit(_PyInitError err); +PyAPI_FUNC(int) _PyInitError_Failed(_PyInitError err); /* --- _PyWstrList ------------------------------------------------ */ @@ -56,8 +35,6 @@ typedef struct { wchar_t **items; } _PyWstrList; -#define _PyWstrList_INIT (_PyWstrList){.length = 0, .items = NULL} - /* --- _PyPreConfig ----------------------------------------------- */ diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h index e9c6d9fee81..80aec21f2c8 100644 --- a/Include/internal/pycore_coreconfig.h +++ b/Include/internal/pycore_coreconfig.h @@ -10,9 +10,41 @@ extern "C" { #include "pycore_pystate.h" /* _PyRuntimeState */ +/* --- _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){._type = _Py_INIT_ERR_TYPE_OK,} + /* other fields are set to 0 */ +#define _Py_INIT_ERR(ERR_MSG) \ + (_PyInitError){ \ + ._type = _Py_INIT_ERR_TYPE_ERROR, \ + ._func = _Py_INIT_GET_FUNC(), \ + .err_msg = (ERR_MSG)} + /* other fields are set to 0 */ +#define _Py_INIT_NO_MEMORY() _Py_INIT_ERR("memory allocation failed") +#define _Py_INIT_EXIT(EXITCODE) \ + (_PyInitError){ \ + ._type = _Py_INIT_ERR_TYPE_EXIT, \ + .exitcode = (EXITCODE)} +#define _Py_INIT_IS_ERROR(err) \ + (err._type == _Py_INIT_ERR_TYPE_ERROR) +#define _Py_INIT_IS_EXIT(err) \ + (err._type == _Py_INIT_ERR_TYPE_EXIT) +#define _Py_INIT_FAILED(err) \ + (err._type != _Py_INIT_ERR_TYPE_OK) /* --- _PyWstrList ------------------------------------------------ */ +#define _PyWstrList_INIT (_PyWstrList){.length = 0, .items = NULL} + #ifndef NDEBUG PyAPI_FUNC(int) _PyWstrList_CheckConsistency(const _PyWstrList *list); #endif diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 63a9b91ac46..2083a03198f 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_coreconfig.h" #include "pythread.h" #include #include diff --git a/Modules/getpath.c b/Modules/getpath.c index 34357e47bc2..3dcfcef7bd7 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -1,6 +1,7 @@ /* Return the initial module search path. */ #include "Python.h" +#include "pycore_coreconfig.h" #include "osdefs.h" #include "pycore_fileutils.h" #include "pycore_pathconfig.h" diff --git a/Objects/exceptions.c b/Objects/exceptions.c index b40ecb78d45..4dad0b24cee 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -6,6 +6,7 @@ #define PY_SSIZE_T_CLEAN #include +#include "pycore_coreconfig.h" #include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" diff --git a/Objects/object.c b/Objects/object.c index cb727943cb3..604f5e0d488 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2,6 +2,7 @@ /* Generic object operations; and implementation of None */ #include "Python.h" +#include "pycore_coreconfig.h" #include "pycore_object.h" #include "pycore_pystate.h" #include "pycore_context.h" diff --git a/PC/getpathp.c b/PC/getpathp.c index 76d3a081b36..64aa1e0d141 100644 --- a/PC/getpathp.c +++ b/PC/getpathp.c @@ -80,6 +80,7 @@ #include "Python.h" +#include "pycore_coreconfig.h" #include "pycore_pystate.h" #include "osdefs.h" #include diff --git a/Programs/_freeze_importlib.c b/Programs/_freeze_importlib.c index bc29297a6b9..d89d66abee7 100644 --- a/Programs/_freeze_importlib.c +++ b/Programs/_freeze_importlib.c @@ -90,7 +90,7 @@ main(int argc, char *argv[]) _PyInitError err = _Py_InitializeFromConfig(&config); /* No need to call _PyCoreConfig_Clear() since we didn't allocate any memory: program_name is a constant string. */ - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 000b2fcec98..2352179cc6f 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -389,7 +389,7 @@ static int test_init_from_config(void) preconfig.utf8_mode = 1; err = _Py_PreInitialize(&preconfig); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } @@ -512,7 +512,7 @@ static int test_init_from_config(void) config.pathconfig_warnings = 0; err = _Py_InitializeFromConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } dump_config(); @@ -543,7 +543,7 @@ static int test_init_parse_argv(int parse_argv) config.parse_argv = parse_argv; err = _Py_InitializeFromConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } dump_config(); @@ -653,7 +653,7 @@ static int init_isolated_flag(void) test_init_env_dev_mode_putenvs(); err = _Py_InitializeFromConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } dump_config(); @@ -672,7 +672,7 @@ static int test_preinit_isolated1(void) preconfig.isolated = 1; err = _Py_PreInitialize(&preconfig); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } @@ -682,7 +682,7 @@ static int test_preinit_isolated1(void) test_init_env_dev_mode_putenvs(); err = _Py_InitializeFromConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } dump_config(); @@ -701,7 +701,7 @@ static int test_preinit_isolated2(void) preconfig.isolated = 0; err = _Py_PreInitialize(&preconfig); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } @@ -717,7 +717,7 @@ static int test_preinit_isolated2(void) test_init_env_dev_mode_putenvs(); err = _Py_InitializeFromConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } dump_config(); @@ -734,7 +734,7 @@ static int init_isolated_config(void) _PyPreConfig_InitIsolatedConfig(&preconfig); err = _Py_PreInitialize(&preconfig); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } @@ -744,13 +744,13 @@ static int init_isolated_config(void) _PyCoreConfig config; err = _PyCoreConfig_InitIsolatedConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } config.program_name = L"./_testembed"; err = _Py_InitializeFromConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } dump_config(); @@ -767,19 +767,19 @@ static int init_python_config(void) _PyPreConfig_InitPythonConfig(&preconfig); err = _Py_PreInitialize(&preconfig); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } _PyCoreConfig config; err = _PyCoreConfig_InitPythonConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } config.program_name = L"./_testembed"; err = _Py_InitializeFromConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } dump_config(); @@ -798,14 +798,14 @@ static int init_dont_configure_locale(void) preconfig.coerce_c_locale_warn = 1; err = _Py_PreInitialize(&preconfig); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } _PyCoreConfig config = _PyCoreConfig_INIT; config.program_name = L"./_testembed"; err = _Py_InitializeFromConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } @@ -824,7 +824,7 @@ static int init_dev_mode(void) config.dev_mode = 1; config.program_name = L"./_testembed"; _PyInitError err = _Py_InitializeFromConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } dump_config(); @@ -840,30 +840,30 @@ static int test_init_read_set(void) _PyCoreConfig_Init(&config); err = _PyCoreConfig_DecodeLocale(&config.program_name, "./init_read_set"); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { goto fail; } err = _PyCoreConfig_Read(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { goto fail; } if (_PyWstrList_Append(&config.module_search_paths, L"init_read_set_path") < 0) { - err = _Py_INIT_NO_MEMORY(); + err = _PyInitError_NoMemory(); goto fail; } /* override executable computed by _PyCoreConfig_Read() */ err = _PyCoreConfig_SetString(&config.executable, L"my_executable"); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { goto fail; } err = _Py_InitializeFromConfig(&config); _PyCoreConfig_Clear(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { goto fail; } dump_config(); @@ -898,7 +898,7 @@ static int test_init_run_main(void) configure_init_main(&config); _PyInitError err = _Py_InitializeFromConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } @@ -914,7 +914,7 @@ static int test_init_main(void) config._init_main = 0; _PyInitError err = _Py_InitializeFromConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } @@ -928,7 +928,7 @@ static int test_init_main(void) } err = _Py_InitializeMain(); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } @@ -951,7 +951,7 @@ static int test_run_main(void) config.program_name = L"./python3"; _PyInitError err = _Py_InitializeFromConfig(&config); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } diff --git a/Python/bootstrap_hash.c b/Python/bootstrap_hash.c index dd752b86094..fe71cc388a0 100644 --- a/Python/bootstrap_hash.c +++ b/Python/bootstrap_hash.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_coreconfig.h" #ifdef MS_WINDOWS # include /* All sample MSDN wincrypt programs include the header below. It is at least diff --git a/Python/coreconfig.c b/Python/coreconfig.c index 2e8f4cf6f10..3c17e3536d8 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -203,6 +203,34 @@ fail: } +/* --- _PyInitError ----------------------------------------------- */ + +_PyInitError _PyInitError_Ok(void) +{ return _Py_INIT_OK(); } + +_PyInitError _PyInitError_Error(const char *err_msg) +{ + return (_PyInitError){._type = _Py_INIT_ERR_TYPE_ERROR, + .err_msg = err_msg}; +} + +_PyInitError _PyInitError_NoMemory(void) +{ return _PyInitError_Error("memory allocation failed"); } + +_PyInitError _PyInitError_Exit(int exitcode) +{ return _Py_INIT_EXIT(exitcode); } + + +int _PyInitError_IsError(_PyInitError err) +{ return _Py_INIT_IS_ERROR(err); } + +int _PyInitError_IsExit(_PyInitError err) +{ return _Py_INIT_IS_EXIT(err); } + +int _PyInitError_Failed(_PyInitError err) +{ return _Py_INIT_FAILED(err); } + + /* --- _PyWstrList ------------------------------------------------ */ #ifndef NDEBUG diff --git a/Python/frozenmain.c b/Python/frozenmain.c index 0175e42596b..7b232bb8023 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -17,7 +17,7 @@ int Py_FrozenMain(int argc, char **argv) { _PyInitError err = _PyRuntime_Initialize(); - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } @@ -84,7 +84,7 @@ Py_FrozenMain(int argc, char **argv) err = _Py_InitializeFromConfig(&config); /* No need to call _PyCoreConfig_Clear() since we didn't allocate any memory: program_name is a constant string. */ - if (_Py_INIT_FAILED(err)) { + if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); }