Skip to content

bpo-32030: Split Py_Main() into subfunctions #4399

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Include/import.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ extern "C" {
#endif

#ifndef Py_LIMITED_API
PyAPI_FUNC(void) _PyImportZip_Init(void);
PyAPI_FUNC(_PyInitError) _PyImportZip_Init(void);

PyMODINIT_FUNC PyInit_imp(void);
#endif /* !Py_LIMITED_API */
Expand Down
8 changes: 7 additions & 1 deletion Include/internal/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,16 @@ typedef struct pyruntimestate {
// XXX Consolidate globals found via the check-c-globals script.
} _PyRuntimeState;

#define _PyRuntimeState_INIT {.initialized = 0, .core_initialized = 0}

PyAPI_DATA(_PyRuntimeState) _PyRuntime;
PyAPI_FUNC(void) _PyRuntimeState_Init(_PyRuntimeState *);
PyAPI_FUNC(_PyInitError) _PyRuntimeState_Init(_PyRuntimeState *);
PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *);

/* Initialize _PyRuntimeState.
Return NULL on success, or return an error message on failure. */
PyAPI_FUNC(_PyInitError) _PyRuntime_Initialize(void);

#define _Py_CURRENTLY_FINALIZING(tstate) \
(_PyRuntime.finalizing == tstate)

Expand Down
44 changes: 35 additions & 9 deletions Include/pylifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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 */
Expand Down
4 changes: 4 additions & 0 deletions Include/pymem.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,10 @@ PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain,
PyAPI_FUNC(void) PyMem_SetupDebugHooks(void);
#endif

#ifdef Py_BUILD_CORE
PyAPI_FUNC(void) _PyMem_GetDefaultRawAllocator(PyMemAllocatorEx *alloc);
#endif

#ifdef __cplusplus
}
#endif
Expand Down
5 changes: 5 additions & 0 deletions Include/sysmodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ PyAPI_FUNC(PyObject *) PySys_GetXOptions(void);
PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *);
#endif

#ifdef Py_BUILD_CORE
PyAPI_FUNC(int) _PySys_AddXOptionWithError(const wchar_t *s);
PyAPI_FUNC(int) _PySys_AddWarnOptionWithError(PyObject *option);
#endif

#ifdef __cplusplus
}
#endif
Expand Down
79 changes: 47 additions & 32 deletions Modules/faulthandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1281,47 +1281,54 @@ PyInit_faulthandler(void)
return m;
}

/* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable
is defined, or if sys._xoptions has a 'faulthandler' key. */

static int
faulthandler_env_options(void)
faulthandler_init_enable(void)
{
PyObject *xoptions, *key, *module, *res;
char *p;
PyObject *module = PyImport_ImportModule("faulthandler");
if (module == NULL) {
return -1;
}

if (!((p = Py_GETENV("PYTHONFAULTHANDLER")) && *p != '\0')) {
/* PYTHONFAULTHANDLER environment variable is missing
or an empty string */
int has_key;
PyObject *res = _PyObject_CallMethodId(module, &PyId_enable, NULL);
Py_DECREF(module);
if (res == NULL) {
return -1;
}
Py_DECREF(res);

xoptions = PySys_GetXOptions();
if (xoptions == NULL)
return -1;
return 0;
}

key = PyUnicode_FromString("faulthandler");
if (key == NULL)
return -1;
/* Call faulthandler.enable() if the PYTHONFAULTHANDLER environment variable
is defined, or if sys._xoptions has a 'faulthandler' key. */

has_key = PyDict_Contains(xoptions, key);
Py_DECREF(key);
if (has_key <= 0)
return has_key;
static int
faulthandler_init_parse(void)
{
char *p = Py_GETENV("PYTHONFAULTHANDLER");
if (p && *p != '\0') {
return 1;
}

module = PyImport_ImportModule("faulthandler");
if (module == NULL) {
/* PYTHONFAULTHANDLER environment variable is missing
or an empty string */
PyObject *xoptions = PySys_GetXOptions();
if (xoptions == NULL) {
return -1;
}
res = _PyObject_CallMethodId(module, &PyId_enable, NULL);
Py_DECREF(module);
if (res == NULL)

PyObject *key = PyUnicode_FromString("faulthandler");
if (key == NULL) {
return -1;
Py_DECREF(res);
return 0;
}

int has_key = PyDict_Contains(xoptions, key);
Py_DECREF(key);
return has_key;
}

int _PyFaulthandler_Init(void)
_PyInitError
_PyFaulthandler_Init(void)
{
#ifdef HAVE_SIGALTSTACK
int err;
Expand All @@ -1345,14 +1352,22 @@ int _PyFaulthandler_Init(void)
thread.cancel_event = PyThread_allocate_lock();
thread.running = PyThread_allocate_lock();
if (!thread.cancel_event || !thread.running) {
PyErr_SetString(PyExc_RuntimeError,
"could not allocate locks for faulthandler");
return -1;
return _Py_INIT_ERR("failed to allocate locks for faulthandler");
}
PyThread_acquire_lock(thread.cancel_event, 1);
#endif

return faulthandler_env_options();
int enable = faulthandler_init_parse();
if (enable < 0) {
return _Py_INIT_ERR("failed to parse faulthandler env var and cmdline");
}

if (enable) {
if (faulthandler_init_enable() < 0) {
return _Py_INIT_ERR("failed to enable faulthandler");
}
}
return _Py_INIT_OK();
}

void _PyFaulthandler_Fini(void)
Expand Down
Loading