mirror of https://github.com/python/cpython
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)
This commit is contained in:
parent
43605e6bfa
commit
f7e5b56c37
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1281,47 +1281,54 @@ PyInit_faulthandler(void)
|
|||
return m;
|
||||
}
|
||||
|
||||
static int
|
||||
faulthandler_init_enable(void)
|
||||
{
|
||||
PyObject *module = PyImport_ImportModule("faulthandler");
|
||||
if (module == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyObject *res = _PyObject_CallMethodId(module, &PyId_enable, NULL);
|
||||
Py_DECREF(module);
|
||||
if (res == NULL) {
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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_parse(void)
|
||||
{
|
||||
PyObject *xoptions, *key, *module, *res;
|
||||
char *p;
|
||||
char *p = Py_GETENV("PYTHONFAULTHANDLER");
|
||||
if (p && *p != '\0') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!((p = Py_GETENV("PYTHONFAULTHANDLER")) && *p != '\0')) {
|
||||
/* PYTHONFAULTHANDLER environment variable is missing
|
||||
or an empty string */
|
||||
int has_key;
|
||||
|
||||
xoptions = PySys_GetXOptions();
|
||||
if (xoptions == NULL)
|
||||
PyObject *xoptions = PySys_GetXOptions();
|
||||
if (xoptions == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
key = PyUnicode_FromString("faulthandler");
|
||||
if (key == NULL)
|
||||
PyObject *key = PyUnicode_FromString("faulthandler");
|
||||
if (key == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
has_key = PyDict_Contains(xoptions, key);
|
||||
int has_key = PyDict_Contains(xoptions, key);
|
||||
Py_DECREF(key);
|
||||
if (has_key <= 0)
|
||||
return has_key;
|
||||
}
|
||||
|
||||
module = PyImport_ImportModule("faulthandler");
|
||||
if (module == NULL) {
|
||||
return -1;
|
||||
}
|
||||
res = _PyObject_CallMethodId(module, &PyId_enable, NULL);
|
||||
Py_DECREF(module);
|
||||
if (res == NULL)
|
||||
return -1;
|
||||
Py_DECREF(res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _PyFaulthandler_Init(void)
|
||||
_PyInitError
|
||||
_PyFaulthandler_Init(void)
|
||||
{
|
||||
#ifdef HAVE_SIGALTSTACK
|
||||
int err;
|
||||
|
@ -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)
|
||||
|
|
1032
Modules/main.c
1032
Modules/main.c
File diff suppressed because it is too large
Load Diff
|
@ -182,31 +182,17 @@ static struct {
|
|||
|
||||
|
||||
#define _PyMem_Raw _PyRuntime.mem.allocators.raw
|
||||
static const PyMemAllocatorEx _pymem_raw = {
|
||||
#ifdef Py_DEBUG
|
||||
&_PyMem_Debug.raw, PYRAWDBG_FUNCS
|
||||
#else
|
||||
NULL, PYRAW_FUNCS
|
||||
#endif
|
||||
};
|
||||
|
||||
#define _PyMem _PyRuntime.mem.allocators.mem
|
||||
static const PyMemAllocatorEx _pymem = {
|
||||
#ifdef Py_DEBUG
|
||||
&_PyMem_Debug.mem, PYDBG_FUNCS
|
||||
#else
|
||||
NULL, PYMEM_FUNCS
|
||||
#endif
|
||||
};
|
||||
|
||||
#define _PyObject _PyRuntime.mem.allocators.obj
|
||||
static const PyMemAllocatorEx _pyobject = {
|
||||
#ifdef Py_DEBUG
|
||||
&_PyMem_Debug.obj, PYDBG_FUNCS
|
||||
#else
|
||||
NULL, PYOBJ_FUNCS
|
||||
#endif
|
||||
};
|
||||
|
||||
void
|
||||
_PyMem_GetDefaultRawAllocator(PyMemAllocatorEx *alloc_p)
|
||||
{
|
||||
PyMemAllocatorEx alloc = {NULL, PYRAW_FUNCS};
|
||||
*alloc_p = alloc;
|
||||
}
|
||||
|
||||
int
|
||||
_PyMem_SetupAllocators(const char *opt)
|
||||
|
@ -267,13 +253,11 @@ _PyMem_SetupAllocators(const char *opt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#undef PYRAW_FUNCS
|
||||
#undef PYMEM_FUNCS
|
||||
#undef PYOBJ_FUNCS
|
||||
#undef PYRAWDBG_FUNCS
|
||||
#undef PYDBG_FUNCS
|
||||
|
||||
static const PyObjectArenaAllocator _PyObject_Arena = {NULL,
|
||||
void
|
||||
_PyObject_Initialize(struct _pyobj_runtime_state *state)
|
||||
{
|
||||
PyObjectArenaAllocator _PyObject_Arena = {NULL,
|
||||
#ifdef MS_WINDOWS
|
||||
_PyObject_ArenaVirtualAlloc, _PyObject_ArenaVirtualFree
|
||||
#elif defined(ARENAS_USE_MMAP)
|
||||
|
@ -283,18 +267,38 @@ static const PyObjectArenaAllocator _PyObject_Arena = {NULL,
|
|||
#endif
|
||||
};
|
||||
|
||||
void
|
||||
_PyObject_Initialize(struct _pyobj_runtime_state *state)
|
||||
{
|
||||
state->allocator_arenas = _PyObject_Arena;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyMem_Initialize(struct _pymem_runtime_state *state)
|
||||
{
|
||||
state->allocators.raw = _pymem_raw;
|
||||
state->allocators.mem = _pymem;
|
||||
state->allocators.obj = _pyobject;
|
||||
PyMemAllocatorEx pymem_raw = {
|
||||
#ifdef Py_DEBUG
|
||||
&_PyMem_Debug.raw, PYRAWDBG_FUNCS
|
||||
#else
|
||||
NULL, PYRAW_FUNCS
|
||||
#endif
|
||||
};
|
||||
PyMemAllocatorEx pymem = {
|
||||
#ifdef Py_DEBUG
|
||||
&_PyMem_Debug.mem, PYDBG_FUNCS
|
||||
#else
|
||||
NULL, PYMEM_FUNCS
|
||||
#endif
|
||||
};
|
||||
PyMemAllocatorEx pyobject = {
|
||||
#ifdef Py_DEBUG
|
||||
&_PyMem_Debug.obj, PYDBG_FUNCS
|
||||
#else
|
||||
NULL, PYOBJ_FUNCS
|
||||
#endif
|
||||
};
|
||||
|
||||
state->allocators.raw = pymem_raw;
|
||||
state->allocators.mem = pymem;
|
||||
state->allocators.obj = pyobject;
|
||||
|
||||
#ifdef WITH_PYMALLOC
|
||||
Py_BUILD_ASSERT(NB_SMALL_SIZE_CLASSES == 64);
|
||||
|
@ -311,6 +315,7 @@ _PyMem_Initialize(struct _pymem_runtime_state *state)
|
|||
#endif /* WITH_PYMALLOC */
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_PYMALLOC
|
||||
static int
|
||||
_PyMem_DebugEnabled(void)
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>Py_BUILD_CORE;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
|
|
@ -27,13 +27,11 @@
|
|||
int Py_DebugFlag;
|
||||
int Py_VerboseFlag;
|
||||
int Py_IgnoreEnvironmentFlag;
|
||||
_PyRuntimeState _PyRuntime = {0, 0};
|
||||
_PyRuntimeState _PyRuntime = _PyRuntimeState_INIT;
|
||||
|
||||
/* Forward */
|
||||
grammar *getgrammar(const char *filename);
|
||||
|
||||
void Py_Exit(int) _Py_NO_RETURN;
|
||||
|
||||
void
|
||||
Py_Exit(int sts)
|
||||
{
|
||||
|
|
|
@ -81,7 +81,10 @@ main(int argc, char *argv[])
|
|||
|
||||
Py_SetProgramName(L"./_freeze_importlib");
|
||||
/* Don't install importlib, since it could execute outdated bytecode. */
|
||||
_Py_InitializeEx_Private(1, 0);
|
||||
_PyInitError err = _Py_InitializeEx_Private(1, 0);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
_Py_FatalInitError(err);
|
||||
}
|
||||
|
||||
if (strstr(inpath, "_external") != NULL) {
|
||||
is_bootstrap = 0;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* Minimal main program -- everything is loaded from the library */
|
||||
|
||||
#include "Python.h"
|
||||
#include "internal/pystate.h"
|
||||
#include <locale.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
@ -22,9 +23,16 @@ main(int argc, char **argv)
|
|||
wchar_t **argv_copy;
|
||||
/* We need a second copy, as Python might modify the first one. */
|
||||
wchar_t **argv_copy2;
|
||||
int i, res;
|
||||
int i, status;
|
||||
char *oldloc;
|
||||
|
||||
_PyInitError err = _PyRuntime_Initialize();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
fprintf(stderr, "Fatal Python error: %s\n", err.msg);
|
||||
fflush(stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Force malloc() allocator to bootstrap Python */
|
||||
#ifdef Py_DEBUG
|
||||
(void)_PyMem_SetupAllocators("malloc_debug");
|
||||
|
@ -88,7 +96,7 @@ main(int argc, char **argv)
|
|||
setlocale(LC_ALL, oldloc);
|
||||
PyMem_RawFree(oldloc);
|
||||
|
||||
res = Py_Main(argc, argv_copy);
|
||||
status = Py_Main(argc, argv_copy);
|
||||
|
||||
/* Force again malloc() allocator to release memory blocks allocated
|
||||
before Py_Main() */
|
||||
|
@ -103,6 +111,6 @@ main(int argc, char **argv)
|
|||
}
|
||||
PyMem_RawFree(argv_copy);
|
||||
PyMem_RawFree(argv_copy2);
|
||||
return res;
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -561,15 +561,16 @@ int Py_ReadHashSeed(char *seed_text,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
static _PyInitError
|
||||
init_hash_secret(int use_hash_seed,
|
||||
unsigned long hash_seed)
|
||||
{
|
||||
void *secret = &_Py_HashSecret;
|
||||
Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
|
||||
|
||||
if (_Py_HashSecret_Initialized)
|
||||
return;
|
||||
if (_Py_HashSecret_Initialized) {
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
_Py_HashSecret_Initialized = 1;
|
||||
|
||||
if (use_hash_seed) {
|
||||
|
@ -593,12 +594,14 @@ init_hash_secret(int use_hash_seed,
|
|||
pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */
|
||||
res = pyurandom(secret, secret_size, 0, 0);
|
||||
if (res < 0) {
|
||||
Py_FatalError("failed to get random numbers to initialize Python");
|
||||
return _Py_INIT_ERR("failed to get random numbers "
|
||||
"to initialize Python");
|
||||
}
|
||||
}
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
void
|
||||
_PyInitError
|
||||
_Py_HashRandomization_Init(_PyCoreConfig *core_config)
|
||||
{
|
||||
char *seed_text;
|
||||
|
@ -608,13 +611,13 @@ _Py_HashRandomization_Init(_PyCoreConfig *core_config)
|
|||
if (use_hash_seed < 0) {
|
||||
seed_text = Py_GETENV("PYTHONHASHSEED");
|
||||
if (Py_ReadHashSeed(seed_text, &use_hash_seed, &hash_seed) < 0) {
|
||||
Py_FatalError("PYTHONHASHSEED must be \"random\" or an integer "
|
||||
"in range [0; 4294967295]");
|
||||
return _Py_INIT_USER_ERR("PYTHONHASHSEED must be \"random\" "
|
||||
"or an integer in range [0; 4294967295]");
|
||||
}
|
||||
core_config->use_hash_seed = use_hash_seed;
|
||||
core_config->hash_seed = hash_seed;
|
||||
}
|
||||
init_hash_secret(use_hash_seed, hash_seed);
|
||||
return init_hash_secret(use_hash_seed, hash_seed);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
/* Python interpreter main program for frozen scripts */
|
||||
|
||||
#include "Python.h"
|
||||
#include "internal/pystate.h"
|
||||
#include <locale.h>
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
|
@ -15,6 +16,13 @@ extern int PyInitFrozenExtensions(void);
|
|||
int
|
||||
Py_FrozenMain(int argc, char **argv)
|
||||
{
|
||||
_PyInitError err = _PyRuntime_Initialize();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
fprintf(stderr, "Fatal Python error: %s\n", err.msg);
|
||||
fflush(stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *p;
|
||||
int i, n, sts = 1;
|
||||
int inspect = 0;
|
||||
|
|
|
@ -42,19 +42,23 @@ module _imp
|
|||
|
||||
/* Initialize things */
|
||||
|
||||
void
|
||||
_PyInitError
|
||||
_PyImport_Init(void)
|
||||
{
|
||||
PyInterpreterState *interp = PyThreadState_Get()->interp;
|
||||
initstr = PyUnicode_InternFromString("__init__");
|
||||
if (initstr == NULL)
|
||||
Py_FatalError("Can't initialize import variables");
|
||||
if (initstr == NULL) {
|
||||
return _Py_INIT_ERR("Can't initialize import variables");
|
||||
}
|
||||
|
||||
interp->builtins_copy = PyDict_Copy(interp->builtins);
|
||||
if (interp->builtins_copy == NULL)
|
||||
Py_FatalError("Can't backup builtins dict");
|
||||
if (interp->builtins_copy == NULL) {
|
||||
return _Py_INIT_ERR("Can't backup builtins dict");
|
||||
}
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
void
|
||||
_PyInitError
|
||||
_PyImportHooks_Init(void)
|
||||
{
|
||||
PyObject *v, *path_hooks = NULL;
|
||||
|
@ -80,15 +84,18 @@ _PyImportHooks_Init(void)
|
|||
goto error;
|
||||
err = PySys_SetObject("path_hooks", path_hooks);
|
||||
if (err) {
|
||||
error:
|
||||
PyErr_Print();
|
||||
Py_FatalError("initializing sys.meta_path, sys.path_hooks, "
|
||||
"or path_importer_cache failed");
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(path_hooks);
|
||||
return _Py_INIT_OK();
|
||||
|
||||
error:
|
||||
PyErr_Print();
|
||||
return _Py_INIT_ERR("initializing sys.meta_path, sys.path_hooks, "
|
||||
"or path_importer_cache failed");
|
||||
}
|
||||
|
||||
void
|
||||
_PyInitError
|
||||
_PyImportZip_Init(void)
|
||||
{
|
||||
PyObject *path_hooks, *zimpimport;
|
||||
|
@ -133,11 +140,11 @@ _PyImportZip_Init(void)
|
|||
}
|
||||
}
|
||||
|
||||
return;
|
||||
return _Py_INIT_OK();
|
||||
|
||||
error:
|
||||
PyErr_Print();
|
||||
Py_FatalError("initializing zipimport failed");
|
||||
return _Py_INIT_ERR("initializing zipimport failed");
|
||||
}
|
||||
|
||||
/* Locking primitives to prevent parallel imports of the same module
|
||||
|
|
|
@ -53,11 +53,11 @@ extern wchar_t *Py_GetPath(void);
|
|||
extern grammar _PyParser_Grammar; /* From graminit.c */
|
||||
|
||||
/* Forward */
|
||||
static void initmain(PyInterpreterState *interp);
|
||||
static int initfsencoding(PyInterpreterState *interp);
|
||||
static void initsite(void);
|
||||
static _PyInitError add_main_module(PyInterpreterState *interp);
|
||||
static _PyInitError initfsencoding(PyInterpreterState *interp);
|
||||
static _PyInitError initsite(void);
|
||||
static int initstdio(void);
|
||||
static void initsigs(void);
|
||||
static _PyInitError initsigs(void);
|
||||
static void call_py_exitfuncs(void);
|
||||
static void wait_for_thread_shutdown(void);
|
||||
static void call_ll_exitfuncs(void);
|
||||
|
@ -66,7 +66,7 @@ extern int _PyStructSequence_Init(void);
|
|||
extern void _PyUnicode_Fini(void);
|
||||
extern int _PyLong_Init(void);
|
||||
extern void PyLong_Fini(void);
|
||||
extern int _PyFaulthandler_Init(void);
|
||||
extern _PyInitError _PyFaulthandler_Init(void);
|
||||
extern void _PyFaulthandler_Fini(void);
|
||||
extern void _PyHash_Fini(void);
|
||||
extern int _PyTraceMalloc_Init(void);
|
||||
|
@ -76,9 +76,9 @@ extern void _Py_ReadyTypes(void);
|
|||
extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *);
|
||||
extern void _PyGILState_Fini(void);
|
||||
|
||||
_PyRuntimeState _PyRuntime = {0, 0};
|
||||
_PyRuntimeState _PyRuntime = _PyRuntimeState_INIT;
|
||||
|
||||
void
|
||||
_PyInitError
|
||||
_PyRuntime_Initialize(void)
|
||||
{
|
||||
/* XXX We only initialize once in the process, which aligns with
|
||||
|
@ -88,10 +88,12 @@ _PyRuntime_Initialize(void)
|
|||
This is because the runtime state is not properly finalized
|
||||
currently. */
|
||||
static int initialized = 0;
|
||||
if (initialized)
|
||||
return;
|
||||
if (initialized) {
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
initialized = 1;
|
||||
_PyRuntimeState_Init(&_PyRuntime);
|
||||
|
||||
return _PyRuntimeState_Init(&_PyRuntime);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -282,43 +284,44 @@ get_locale_encoding(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
/* Return NULL on success, or return an error message on failure */
|
||||
static _PyInitError
|
||||
initimport(PyInterpreterState *interp, PyObject *sysmod)
|
||||
{
|
||||
PyObject *importlib;
|
||||
PyObject *impmod;
|
||||
PyObject *value;
|
||||
_PyInitError err;
|
||||
|
||||
/* Import _importlib through its frozen version, _frozen_importlib. */
|
||||
if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) {
|
||||
Py_FatalError("Py_Initialize: can't import _frozen_importlib");
|
||||
return _Py_INIT_ERR("can't import _frozen_importlib");
|
||||
}
|
||||
else if (Py_VerboseFlag) {
|
||||
PySys_FormatStderr("import _frozen_importlib # frozen\n");
|
||||
}
|
||||
importlib = PyImport_AddModule("_frozen_importlib");
|
||||
if (importlib == NULL) {
|
||||
Py_FatalError("Py_Initialize: couldn't get _frozen_importlib from "
|
||||
"sys.modules");
|
||||
return _Py_INIT_ERR("couldn't get _frozen_importlib from sys.modules");
|
||||
}
|
||||
interp->importlib = importlib;
|
||||
Py_INCREF(interp->importlib);
|
||||
|
||||
interp->import_func = PyDict_GetItemString(interp->builtins, "__import__");
|
||||
if (interp->import_func == NULL)
|
||||
Py_FatalError("Py_Initialize: __import__ not found");
|
||||
return _Py_INIT_ERR("__import__ not found");
|
||||
Py_INCREF(interp->import_func);
|
||||
|
||||
/* Import the _imp module */
|
||||
impmod = PyInit_imp();
|
||||
if (impmod == NULL) {
|
||||
Py_FatalError("Py_Initialize: can't import _imp");
|
||||
return _Py_INIT_ERR("can't import _imp");
|
||||
}
|
||||
else if (Py_VerboseFlag) {
|
||||
PySys_FormatStderr("import _imp # builtin\n");
|
||||
}
|
||||
if (_PyImport_SetModuleString("_imp", impmod) < 0) {
|
||||
Py_FatalError("Py_Initialize: can't save _imp to sys.modules");
|
||||
return _Py_INIT_ERR("can't save _imp to sys.modules");
|
||||
}
|
||||
|
||||
/* Install importlib as the implementation of import */
|
||||
|
@ -330,15 +333,21 @@ initimport(PyInterpreterState *interp, PyObject *sysmod)
|
|||
}
|
||||
if (value == NULL) {
|
||||
PyErr_Print();
|
||||
Py_FatalError("Py_Initialize: importlib install failed");
|
||||
return _Py_INIT_ERR("importlib install failed");
|
||||
}
|
||||
Py_DECREF(value);
|
||||
Py_DECREF(impmod);
|
||||
|
||||
_PyImportZip_Init();
|
||||
err = _PyImportZip_Init();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
static void
|
||||
/* Return NULL on success, or return an error message on failure */
|
||||
static _PyInitError
|
||||
initexternalimport(PyInterpreterState *interp)
|
||||
{
|
||||
PyObject *value;
|
||||
|
@ -346,9 +355,10 @@ initexternalimport(PyInterpreterState *interp)
|
|||
"_install_external_importers", "");
|
||||
if (value == NULL) {
|
||||
PyErr_Print();
|
||||
Py_FatalError("Py_EndInitialization: external importer setup failed");
|
||||
return _Py_INIT_ERR("external importer setup failed");
|
||||
}
|
||||
Py_DECREF(value);
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
/* Helper functions to better handle the legacy C locale
|
||||
|
@ -613,13 +623,16 @@ _Py_SetLocaleFromEnv(int category)
|
|||
* 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)
|
||||
*
|
||||
* Return NULL on success, or return an error message on failure.
|
||||
*/
|
||||
|
||||
/* TODO: Progressively move functionality from Py_BeginInitialization to
|
||||
* Py_ReadConfig and Py_EndInitialization
|
||||
*/
|
||||
|
||||
void _Py_InitializeCore(const _PyCoreConfig *config)
|
||||
_PyInitError
|
||||
_Py_InitializeCore(const _PyCoreConfig *config)
|
||||
{
|
||||
PyInterpreterState *interp;
|
||||
PyThreadState *tstate;
|
||||
|
@ -627,18 +640,26 @@ void _Py_InitializeCore(const _PyCoreConfig *config)
|
|||
char *p;
|
||||
_PyCoreConfig core_config = _PyCoreConfig_INIT;
|
||||
_PyMainInterpreterConfig preinit_config = _PyMainInterpreterConfig_INIT;
|
||||
_PyInitError err;
|
||||
|
||||
_PyRuntime_Initialize();
|
||||
err = _PyRuntime_Initialize();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (config != NULL) {
|
||||
core_config = *config;
|
||||
}
|
||||
|
||||
if (_PyMem_SetupAllocators(core_config.allocator) < 0) {
|
||||
return _Py_INIT_ERR("Unknown PYTHONMALLOC allocator");
|
||||
}
|
||||
|
||||
if (_PyRuntime.initialized) {
|
||||
Py_FatalError("Py_InitializeCore: main interpreter already initialized");
|
||||
return _Py_INIT_ERR("main interpreter already initialized");
|
||||
}
|
||||
if (_PyRuntime.core_initialized) {
|
||||
Py_FatalError("Py_InitializeCore: runtime core already initialized");
|
||||
return _Py_INIT_ERR("runtime core already initialized");
|
||||
}
|
||||
|
||||
/* Py_Finalize leaves _Py_Finalizing set in order to help daemon
|
||||
|
@ -652,13 +673,6 @@ void _Py_InitializeCore(const _PyCoreConfig *config)
|
|||
*/
|
||||
_PyRuntime.finalizing = NULL;
|
||||
|
||||
if (_PyMem_SetupAllocators(core_config.allocator) < 0) {
|
||||
fprintf(stderr,
|
||||
"Error in PYTHONMALLOC: unknown allocator \"%s\"!\n",
|
||||
core_config.allocator);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifndef MS_WINDOWS
|
||||
/* Set up the LC_CTYPE locale, so we can obtain
|
||||
the locale's charset without having to switch
|
||||
|
@ -692,7 +706,11 @@ void _Py_InitializeCore(const _PyCoreConfig *config)
|
|||
set_flag(&Py_LegacyWindowsStdioFlag, p);
|
||||
#endif
|
||||
|
||||
_Py_HashRandomization_Init(&core_config);
|
||||
err = _Py_HashRandomization_Init(&core_config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!core_config.use_hash_seed || core_config.hash_seed) {
|
||||
/* Random or non-zero hash seed */
|
||||
Py_HashRandomizationFlag = 1;
|
||||
|
@ -701,13 +719,13 @@ void _Py_InitializeCore(const _PyCoreConfig *config)
|
|||
_PyInterpreterState_Enable(&_PyRuntime);
|
||||
interp = PyInterpreterState_New();
|
||||
if (interp == NULL)
|
||||
Py_FatalError("Py_InitializeCore: can't make main interpreter");
|
||||
return _Py_INIT_ERR("can't make main interpreter");
|
||||
interp->core_config = core_config;
|
||||
interp->config = preinit_config;
|
||||
|
||||
tstate = PyThreadState_New(interp);
|
||||
if (tstate == NULL)
|
||||
Py_FatalError("Py_InitializeCore: can't make first thread");
|
||||
return _Py_INIT_ERR("can't make first thread");
|
||||
(void) PyThreadState_Swap(tstate);
|
||||
|
||||
/* We can't call _PyEval_FiniThreads() in Py_FinalizeEx because
|
||||
|
@ -722,46 +740,50 @@ void _Py_InitializeCore(const _PyCoreConfig *config)
|
|||
_Py_ReadyTypes();
|
||||
|
||||
if (!_PyFrame_Init())
|
||||
Py_FatalError("Py_InitializeCore: can't init frames");
|
||||
return _Py_INIT_ERR("can't init frames");
|
||||
|
||||
if (!_PyLong_Init())
|
||||
Py_FatalError("Py_InitializeCore: can't init longs");
|
||||
return _Py_INIT_ERR("can't init longs");
|
||||
|
||||
if (!PyByteArray_Init())
|
||||
Py_FatalError("Py_InitializeCore: can't init bytearray");
|
||||
return _Py_INIT_ERR("can't init bytearray");
|
||||
|
||||
if (!_PyFloat_Init())
|
||||
Py_FatalError("Py_InitializeCore: can't init float");
|
||||
return _Py_INIT_ERR("can't init float");
|
||||
|
||||
PyObject *modules = PyDict_New();
|
||||
if (modules == NULL)
|
||||
Py_FatalError("Py_InitializeCore: can't make modules dictionary");
|
||||
return _Py_INIT_ERR("can't make modules dictionary");
|
||||
interp->modules = modules;
|
||||
|
||||
sysmod = _PySys_BeginInit();
|
||||
if (sysmod == NULL)
|
||||
Py_FatalError("Py_InitializeCore: can't initialize sys");
|
||||
err = _PySys_BeginInit(&sysmod);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
interp->sysdict = PyModule_GetDict(sysmod);
|
||||
if (interp->sysdict == NULL)
|
||||
Py_FatalError("Py_InitializeCore: can't initialize sys dict");
|
||||
if (interp->sysdict == NULL) {
|
||||
return _Py_INIT_ERR("can't initialize sys dict");
|
||||
}
|
||||
|
||||
Py_INCREF(interp->sysdict);
|
||||
PyDict_SetItemString(interp->sysdict, "modules", modules);
|
||||
_PyImport_FixupBuiltin(sysmod, "sys", modules);
|
||||
|
||||
/* Init Unicode implementation; relies on the codec registry */
|
||||
if (_PyUnicode_Init() < 0)
|
||||
Py_FatalError("Py_InitializeCore: can't initialize unicode");
|
||||
return _Py_INIT_ERR("can't initialize unicode");
|
||||
|
||||
if (_PyStructSequence_Init() < 0)
|
||||
Py_FatalError("Py_InitializeCore: can't initialize structseq");
|
||||
return _Py_INIT_ERR("can't initialize structseq");
|
||||
|
||||
bimod = _PyBuiltin_Init();
|
||||
if (bimod == NULL)
|
||||
Py_FatalError("Py_InitializeCore: can't initialize builtins modules");
|
||||
return _Py_INIT_ERR("can't initialize builtins modules");
|
||||
_PyImport_FixupBuiltin(bimod, "builtins", modules);
|
||||
interp->builtins = PyModule_GetDict(bimod);
|
||||
if (interp->builtins == NULL)
|
||||
Py_FatalError("Py_InitializeCore: can't initialize builtins dict");
|
||||
return _Py_INIT_ERR("can't initialize builtins dict");
|
||||
Py_INCREF(interp->builtins);
|
||||
|
||||
/* initialize builtin exceptions */
|
||||
|
@ -771,25 +793,35 @@ void _Py_InitializeCore(const _PyCoreConfig *config)
|
|||
infrastructure for the io module in place. */
|
||||
pstderr = PyFile_NewStdPrinter(fileno(stderr));
|
||||
if (pstderr == NULL)
|
||||
Py_FatalError("Py_InitializeCore: can't set preliminary stderr");
|
||||
return _Py_INIT_ERR("can't set preliminary stderr");
|
||||
_PySys_SetObjectId(&PyId_stderr, pstderr);
|
||||
PySys_SetObject("__stderr__", pstderr);
|
||||
Py_DECREF(pstderr);
|
||||
|
||||
_PyImport_Init();
|
||||
err = _PyImport_Init();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
_PyImportHooks_Init();
|
||||
err = _PyImportHooks_Init();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Initialize _warnings. */
|
||||
_PyWarnings_Init();
|
||||
|
||||
/* This call sets up builtin and frozen import support */
|
||||
if (!interp->core_config._disable_importlib) {
|
||||
initimport(interp, sysmod);
|
||||
err = initimport(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();
|
||||
}
|
||||
|
||||
/* Read configuration settings from standard locations
|
||||
|
@ -802,16 +834,18 @@ void _Py_InitializeCore(const _PyCoreConfig *config)
|
|||
*
|
||||
* More advanced selective initialization tricks are possible by calling
|
||||
* this function multiple times with various preconfigured settings.
|
||||
*
|
||||
* Return NULL on success, or return an error message on failure.
|
||||
*/
|
||||
|
||||
int _Py_ReadMainInterpreterConfig(_PyMainInterpreterConfig *config)
|
||||
_PyInitError
|
||||
_Py_ReadMainInterpreterConfig(_PyMainInterpreterConfig *config)
|
||||
{
|
||||
/* Signal handlers are installed by default */
|
||||
if (config->install_signal_handlers < 0) {
|
||||
config->install_signal_handlers = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
/* Update interpreter state based on supplied configuration settings
|
||||
|
@ -824,26 +858,30 @@ int _Py_ReadMainInterpreterConfig(_PyMainInterpreterConfig *config)
|
|||
* initialized or without a valid current thread state is a fatal error.
|
||||
* Other errors should be reported as normal Python exceptions with a
|
||||
* non-zero return code.
|
||||
*
|
||||
* Return NULL on success, or return an error message on failure.
|
||||
*/
|
||||
int _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config)
|
||||
_PyInitError
|
||||
_Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config)
|
||||
{
|
||||
PyInterpreterState *interp;
|
||||
PyThreadState *tstate;
|
||||
_PyInitError err;
|
||||
|
||||
if (!_PyRuntime.core_initialized) {
|
||||
Py_FatalError("Py_InitializeMainInterpreter: runtime core not initialized");
|
||||
return _Py_INIT_ERR("runtime core not initialized");
|
||||
}
|
||||
if (_PyRuntime.initialized) {
|
||||
Py_FatalError("Py_InitializeMainInterpreter: main interpreter already initialized");
|
||||
return _Py_INIT_ERR("main interpreter already initialized");
|
||||
}
|
||||
|
||||
/* Get current thread state and interpreter pointer */
|
||||
tstate = PyThreadState_GET();
|
||||
if (!tstate)
|
||||
Py_FatalError("Py_InitializeMainInterpreter: failed to read thread state");
|
||||
return _Py_INIT_ERR("failed to read thread state");
|
||||
interp = tstate->interp;
|
||||
if (!interp)
|
||||
Py_FatalError("Py_InitializeMainInterpreter: failed to get interpreter");
|
||||
return _Py_INIT_ERR("failed to get interpreter");
|
||||
|
||||
/* Now finish configuring the main interpreter */
|
||||
interp->config = *config;
|
||||
|
@ -855,12 +893,12 @@ int _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config)
|
|||
* or pure Python code in the standard library won't work.
|
||||
*/
|
||||
_PyRuntime.initialized = 1;
|
||||
return 0;
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
/* TODO: Report exceptions rather than fatal errors below here */
|
||||
|
||||
if (_PyTime_Init() < 0)
|
||||
Py_FatalError("Py_InitializeMainInterpreter: can't initialize time");
|
||||
return _Py_INIT_ERR("can't initialize time");
|
||||
|
||||
/* Finish setting up the sys module and import system */
|
||||
/* GetPath may initialize state that _PySys_EndInit locks
|
||||
|
@ -868,26 +906,40 @@ int _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config)
|
|||
/* TODO: Call Py_GetPath() in Py_ReadConfig, rather than here */
|
||||
PySys_SetPath(Py_GetPath());
|
||||
if (_PySys_EndInit(interp->sysdict) < 0)
|
||||
Py_FatalError("Py_InitializeMainInterpreter: can't finish initializing sys");
|
||||
initexternalimport(interp);
|
||||
return _Py_INIT_ERR("can't finish initializing sys");
|
||||
err = initexternalimport(interp);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* initialize the faulthandler module */
|
||||
if (_PyFaulthandler_Init())
|
||||
Py_FatalError("Py_InitializeMainInterpreter: can't initialize faulthandler");
|
||||
err = _PyFaulthandler_Init();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (initfsencoding(interp) < 0)
|
||||
Py_FatalError("Py_InitializeMainInterpreter: unable to load the file system codec");
|
||||
err = initfsencoding(interp);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (config->install_signal_handlers)
|
||||
initsigs(); /* Signal handling stuff, including initintr() */
|
||||
if (config->install_signal_handlers) {
|
||||
err = initsigs(); /* Signal handling stuff, including initintr() */
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (_PyTraceMalloc_Init() < 0)
|
||||
Py_FatalError("Py_InitializeMainInterpreter: can't initialize tracemalloc");
|
||||
return _Py_INIT_ERR("can't initialize tracemalloc");
|
||||
|
||||
initmain(interp); /* Module __main__ */
|
||||
if (initstdio() < 0)
|
||||
Py_FatalError(
|
||||
"Py_InitializeMainInterpreter: can't initialize sys standard streams");
|
||||
err = add_main_module(interp);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
if (initstdio() < 0) {
|
||||
return _Py_INIT_ERR("can't initialize sys standard streams");
|
||||
}
|
||||
|
||||
/* Initialize warnings. */
|
||||
if (PySys_HasWarnOptions()) {
|
||||
|
@ -901,37 +953,57 @@ int _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config)
|
|||
|
||||
_PyRuntime.initialized = 1;
|
||||
|
||||
if (!Py_NoSiteFlag)
|
||||
initsite(); /* Module site */
|
||||
if (!Py_NoSiteFlag) {
|
||||
err = initsite(); /* Module site */
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
#undef _INIT_DEBUG_PRINT
|
||||
|
||||
void
|
||||
_PyInitError
|
||||
_Py_InitializeEx_Private(int install_sigs, int install_importlib)
|
||||
{
|
||||
_PyCoreConfig core_config = _PyCoreConfig_INIT;
|
||||
_PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT;
|
||||
_PyInitError err;
|
||||
|
||||
/* TODO: Moar config options! */
|
||||
core_config.ignore_environment = Py_IgnoreEnvironmentFlag;
|
||||
core_config._disable_importlib = !install_importlib;
|
||||
config.install_signal_handlers = install_sigs;
|
||||
_Py_InitializeCore(&core_config);
|
||||
|
||||
err = _Py_InitializeCore(&core_config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* TODO: Print any exceptions raised by these operations */
|
||||
if (_Py_ReadMainInterpreterConfig(&config))
|
||||
Py_FatalError("Py_Initialize: Py_ReadMainInterpreterConfig failed");
|
||||
if (_Py_InitializeMainInterpreter(&config))
|
||||
Py_FatalError("Py_Initialize: Py_InitializeMainInterpreter failed");
|
||||
err = _Py_ReadMainInterpreterConfig(&config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = _Py_InitializeMainInterpreter(&config);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Py_InitializeEx(int install_sigs)
|
||||
{
|
||||
_Py_InitializeEx_Private(install_sigs, 1);
|
||||
_PyInitError err = _Py_InitializeEx_Private(install_sigs, 1);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
_Py_FatalInitError(err);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1236,6 +1308,7 @@ Py_NewInterpreter(void)
|
|||
PyInterpreterState *interp;
|
||||
PyThreadState *tstate, *save_tstate;
|
||||
PyObject *bimod, *sysmod;
|
||||
_PyInitError err = _Py_INIT_OK();
|
||||
|
||||
if (!_PyRuntime.initialized)
|
||||
Py_FatalError("Py_NewInterpreter: call Py_Initialize first");
|
||||
|
@ -1308,25 +1381,50 @@ Py_NewInterpreter(void)
|
|||
PySys_SetObject("__stderr__", pstderr);
|
||||
Py_DECREF(pstderr);
|
||||
|
||||
_PyImportHooks_Init();
|
||||
err = _PyImportHooks_Init();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
initimport(interp, sysmod);
|
||||
initexternalimport(interp);
|
||||
err = initimport(interp, sysmod);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
if (initfsencoding(interp) < 0)
|
||||
goto handle_error;
|
||||
err = initexternalimport(interp);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
if (initstdio() < 0)
|
||||
Py_FatalError(
|
||||
"Py_NewInterpreter: can't initialize sys standard streams");
|
||||
initmain(interp);
|
||||
if (!Py_NoSiteFlag)
|
||||
initsite();
|
||||
err = initfsencoding(interp);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
if (initstdio() < 0) {
|
||||
err = _Py_INIT_ERR("can't initialize sys standard streams");
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
err = add_main_module(interp);
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto init_failed;
|
||||
}
|
||||
|
||||
if (!Py_NoSiteFlag) {
|
||||
err = initsite();
|
||||
if (_Py_INIT_FAILED(err)) {
|
||||
goto init_failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PyErr_Occurred())
|
||||
return tstate;
|
||||
|
||||
init_failed:
|
||||
_Py_FatalInitError(err);
|
||||
|
||||
handle_error:
|
||||
/* Oops, it didn't work. Undo it all. */
|
||||
|
||||
|
@ -1417,32 +1515,35 @@ Py_GetPythonHome(void)
|
|||
return home;
|
||||
}
|
||||
|
||||
/* Create __main__ module */
|
||||
/* Add the __main__ module */
|
||||
|
||||
static void
|
||||
initmain(PyInterpreterState *interp)
|
||||
static _PyInitError
|
||||
add_main_module(PyInterpreterState *interp)
|
||||
{
|
||||
PyObject *m, *d, *loader, *ann_dict;
|
||||
m = PyImport_AddModule("__main__");
|
||||
if (m == NULL)
|
||||
Py_FatalError("can't create __main__ module");
|
||||
return _Py_INIT_ERR("can't create __main__ module");
|
||||
|
||||
d = PyModule_GetDict(m);
|
||||
ann_dict = PyDict_New();
|
||||
if ((ann_dict == NULL) ||
|
||||
(PyDict_SetItemString(d, "__annotations__", ann_dict) < 0)) {
|
||||
Py_FatalError("Failed to initialize __main__.__annotations__");
|
||||
return _Py_INIT_ERR("Failed to initialize __main__.__annotations__");
|
||||
}
|
||||
Py_DECREF(ann_dict);
|
||||
|
||||
if (PyDict_GetItemString(d, "__builtins__") == NULL) {
|
||||
PyObject *bimod = PyImport_ImportModule("builtins");
|
||||
if (bimod == NULL) {
|
||||
Py_FatalError("Failed to retrieve builtins module");
|
||||
return _Py_INIT_ERR("Failed to retrieve builtins module");
|
||||
}
|
||||
if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) {
|
||||
Py_FatalError("Failed to initialize __main__.__builtins__");
|
||||
return _Py_INIT_ERR("Failed to initialize __main__.__builtins__");
|
||||
}
|
||||
Py_DECREF(bimod);
|
||||
}
|
||||
|
||||
/* Main is a little special - imp.is_builtin("__main__") will return
|
||||
* False, but BuiltinImporter is still the most appropriate initial
|
||||
* setting for its __loader__ attribute. A more suitable value will
|
||||
|
@ -1454,41 +1555,40 @@ initmain(PyInterpreterState *interp)
|
|||
PyObject *loader = PyObject_GetAttrString(interp->importlib,
|
||||
"BuiltinImporter");
|
||||
if (loader == NULL) {
|
||||
Py_FatalError("Failed to retrieve BuiltinImporter");
|
||||
return _Py_INIT_ERR("Failed to retrieve BuiltinImporter");
|
||||
}
|
||||
if (PyDict_SetItemString(d, "__loader__", loader) < 0) {
|
||||
Py_FatalError("Failed to initialize __main__.__loader__");
|
||||
return _Py_INIT_ERR("Failed to initialize __main__.__loader__");
|
||||
}
|
||||
Py_DECREF(loader);
|
||||
}
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
static int
|
||||
static _PyInitError
|
||||
initfsencoding(PyInterpreterState *interp)
|
||||
{
|
||||
PyObject *codec;
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
if (Py_LegacyWindowsFSEncodingFlag)
|
||||
{
|
||||
if (Py_LegacyWindowsFSEncodingFlag) {
|
||||
Py_FileSystemDefaultEncoding = "mbcs";
|
||||
Py_FileSystemDefaultEncodeErrors = "replace";
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
Py_FileSystemDefaultEncoding = "utf-8";
|
||||
Py_FileSystemDefaultEncodeErrors = "surrogatepass";
|
||||
}
|
||||
#else
|
||||
if (Py_FileSystemDefaultEncoding == NULL)
|
||||
{
|
||||
if (Py_FileSystemDefaultEncoding == NULL) {
|
||||
Py_FileSystemDefaultEncoding = get_locale_encoding();
|
||||
if (Py_FileSystemDefaultEncoding == NULL)
|
||||
Py_FatalError("Py_Initialize: Unable to get the locale encoding");
|
||||
if (Py_FileSystemDefaultEncoding == NULL) {
|
||||
return _Py_INIT_ERR("Unable to get the locale encoding");
|
||||
}
|
||||
|
||||
Py_HasFileSystemDefaultEncoding = 0;
|
||||
interp->fscodec_initialized = 1;
|
||||
return 0;
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1498,29 +1598,25 @@ initfsencoding(PyInterpreterState *interp)
|
|||
/* Such error can only occurs in critical situations: no more
|
||||
* memory, import a module of the standard library failed,
|
||||
* etc. */
|
||||
return -1;
|
||||
return _Py_INIT_ERR("unable to load the file system codec");
|
||||
}
|
||||
Py_DECREF(codec);
|
||||
interp->fscodec_initialized = 1;
|
||||
return 0;
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
/* Import the site module (not into __main__ though) */
|
||||
|
||||
static void
|
||||
static _PyInitError
|
||||
initsite(void)
|
||||
{
|
||||
PyObject *m;
|
||||
m = PyImport_ImportModule("site");
|
||||
if (m == NULL) {
|
||||
fprintf(stderr, "Failed to import the site module\n");
|
||||
PyErr_Print();
|
||||
Py_Finalize();
|
||||
exit(1);
|
||||
return _Py_INIT_USER_ERR("Failed to import the site module");
|
||||
}
|
||||
else {
|
||||
Py_DECREF(m);
|
||||
}
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
/* Check if a file descriptor is valid or not.
|
||||
|
@ -1926,8 +2022,8 @@ fatal_output_debug(const char *msg)
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
Py_FatalError(const char *msg)
|
||||
static void
|
||||
fatal_error(const char *prefix, const char *msg, int status)
|
||||
{
|
||||
const int fd = fileno(stderr);
|
||||
static int reentrant = 0;
|
||||
|
@ -1939,7 +2035,18 @@ Py_FatalError(const char *msg)
|
|||
}
|
||||
reentrant = 1;
|
||||
|
||||
fprintf(stderr, "Fatal Python error: %s\n", msg);
|
||||
fprintf(stderr, "Fatal Python error: ");
|
||||
if (prefix) {
|
||||
fputs(prefix, stderr);
|
||||
fputs(": ", stderr);
|
||||
}
|
||||
if (msg) {
|
||||
fputs(msg, stderr);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "<message not set>");
|
||||
}
|
||||
fputs("\n", stderr);
|
||||
fflush(stderr); /* it helps in Windows debug build */
|
||||
|
||||
/* Print the exception (if an exception is set) with its traceback,
|
||||
|
@ -1965,10 +2072,30 @@ Py_FatalError(const char *msg)
|
|||
#endif /* MS_WINDOWS */
|
||||
|
||||
exit:
|
||||
if (status < 0) {
|
||||
#if defined(MS_WINDOWS) && defined(_DEBUG)
|
||||
DebugBreak();
|
||||
#endif
|
||||
abort();
|
||||
}
|
||||
else {
|
||||
exit(status);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Py_FatalError(const char *msg)
|
||||
{
|
||||
fatal_error(NULL, msg, -1);
|
||||
}
|
||||
|
||||
void
|
||||
_Py_FatalInitError(_PyInitError err)
|
||||
{
|
||||
/* On "user" error: exit with status 1.
|
||||
For all other errors, call abort(). */
|
||||
int status = err.user_err ? 1 : -1;
|
||||
fatal_error(err.prefix, err.msg, status);
|
||||
}
|
||||
|
||||
/* Clean up and exit */
|
||||
|
@ -2045,7 +2172,7 @@ Py_Exit(int sts)
|
|||
exit(sts);
|
||||
}
|
||||
|
||||
static void
|
||||
static _PyInitError
|
||||
initsigs(void)
|
||||
{
|
||||
#ifdef SIGPIPE
|
||||
|
@ -2059,8 +2186,9 @@ initsigs(void)
|
|||
#endif
|
||||
PyOS_InitInterrupts(); /* May imply initsignal() */
|
||||
if (PyErr_Occurred()) {
|
||||
Py_FatalError("Py_Initialize: can't import signal");
|
||||
return _Py_INIT_ERR("can't import signal");
|
||||
}
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ to avoid the expense of doing their own locking).
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
void
|
||||
_PyInitError
|
||||
_PyRuntimeState_Init(_PyRuntimeState *runtime)
|
||||
{
|
||||
memset(runtime, 0, sizeof(*runtime));
|
||||
|
@ -46,17 +46,19 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
|
|||
_PyEval_Initialize(&runtime->ceval);
|
||||
|
||||
runtime->gilstate.check_enabled = 1;
|
||||
|
||||
/* A TSS key must be initialized with Py_tss_NEEDS_INIT
|
||||
in accordance with the specification. */
|
||||
{
|
||||
Py_tss_t initial = Py_tss_NEEDS_INIT;
|
||||
runtime->gilstate.autoTSSkey = initial;
|
||||
}
|
||||
|
||||
runtime->interpreters.mutex = PyThread_allocate_lock();
|
||||
if (runtime->interpreters.mutex == NULL)
|
||||
Py_FatalError("Can't initialize threads for interpreter");
|
||||
if (runtime->interpreters.mutex == NULL) {
|
||||
return _Py_INIT_ERR("Can't initialize threads for interpreter");
|
||||
}
|
||||
|
||||
runtime->interpreters.next_id = -1;
|
||||
return _Py_INIT_OK();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1582,13 +1582,23 @@ PySys_ResetWarnOptions(void)
|
|||
PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
|
||||
}
|
||||
|
||||
void
|
||||
PySys_AddWarnOptionUnicode(PyObject *unicode)
|
||||
int
|
||||
_PySys_AddWarnOptionWithError(PyObject *option)
|
||||
{
|
||||
PyObject *warnoptions = get_warnoptions();
|
||||
if (warnoptions == NULL)
|
||||
return;
|
||||
PyList_Append(warnoptions, unicode);
|
||||
if (warnoptions == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (PyList_Append(warnoptions, option)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PySys_AddWarnOptionUnicode(PyObject *option)
|
||||
{
|
||||
(void)_PySys_AddWarnOptionWithError(option);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1627,18 +1637,17 @@ get_xoptions(void)
|
|||
return xoptions;
|
||||
}
|
||||
|
||||
void
|
||||
PySys_AddXOption(const wchar_t *s)
|
||||
int
|
||||
_PySys_AddXOptionWithError(const wchar_t *s)
|
||||
{
|
||||
PyObject *opts;
|
||||
PyObject *name = NULL, *value = NULL;
|
||||
const wchar_t *name_end;
|
||||
|
||||
opts = get_xoptions();
|
||||
if (opts == NULL)
|
||||
PyObject *opts = get_xoptions();
|
||||
if (opts == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
name_end = wcschr(s, L'=');
|
||||
const wchar_t *name_end = wcschr(s, L'=');
|
||||
if (!name_end) {
|
||||
name = PyUnicode_FromWideChar(s, -1);
|
||||
value = Py_True;
|
||||
|
@ -1648,20 +1657,31 @@ PySys_AddXOption(const wchar_t *s)
|
|||
name = PyUnicode_FromWideChar(s, name_end - s);
|
||||
value = PyUnicode_FromWideChar(name_end + 1, -1);
|
||||
}
|
||||
if (name == NULL || value == NULL)
|
||||
if (name == NULL || value == NULL) {
|
||||
goto error;
|
||||
PyDict_SetItem(opts, name, value);
|
||||
}
|
||||
if (PyDict_SetItem(opts, name, value) < 0) {
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(name);
|
||||
Py_DECREF(value);
|
||||
return;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
Py_XDECREF(name);
|
||||
Py_XDECREF(value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
PySys_AddXOption(const wchar_t *s)
|
||||
{
|
||||
if (_PySys_AddXOptionWithError(s) < 0) {
|
||||
/* No return value, therefore clear error state if possible */
|
||||
if (_PyThreadState_UncheckedGet()) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *
|
||||
|
@ -1999,34 +2019,38 @@ static struct PyModuleDef sysmodule = {
|
|||
#define SET_SYS_FROM_STRING_BORROW(key, value) \
|
||||
do { \
|
||||
PyObject *v = (value); \
|
||||
if (v == NULL) \
|
||||
return NULL; \
|
||||
if (v == NULL) { \
|
||||
goto err_occurred; \
|
||||
} \
|
||||
res = PyDict_SetItemString(sysdict, key, v); \
|
||||
if (res < 0) { \
|
||||
return NULL; \
|
||||
goto err_occurred; \
|
||||
} \
|
||||
} while (0)
|
||||
#define SET_SYS_FROM_STRING(key, value) \
|
||||
do { \
|
||||
PyObject *v = (value); \
|
||||
if (v == NULL) \
|
||||
return NULL; \
|
||||
if (v == NULL) { \
|
||||
goto err_occurred; \
|
||||
} \
|
||||
res = PyDict_SetItemString(sysdict, key, v); \
|
||||
Py_DECREF(v); \
|
||||
if (res < 0) { \
|
||||
return NULL; \
|
||||
goto err_occurred; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
PyObject *
|
||||
_PySys_BeginInit(void)
|
||||
|
||||
_PyInitError
|
||||
_PySys_BeginInit(PyObject **sysmod)
|
||||
{
|
||||
PyObject *m, *sysdict, *version_info;
|
||||
int res;
|
||||
|
||||
m = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
if (m == NULL) {
|
||||
return _Py_INIT_ERR("failed to create a module object");
|
||||
}
|
||||
sysdict = PyModule_GetDict(m);
|
||||
|
||||
/* Check that stdin is not a directory
|
||||
|
@ -2034,15 +2058,13 @@ _PySys_BeginInit(void)
|
|||
crashing the Python interpreter. Catch this common mistake here
|
||||
and output a useful error message. Note that under MS Windows,
|
||||
the shell already prevents that. */
|
||||
#if !defined(MS_WINDOWS)
|
||||
#ifndef MS_WINDOWS
|
||||
{
|
||||
struct _Py_stat_struct sb;
|
||||
if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 &&
|
||||
S_ISDIR(sb.st_mode)) {
|
||||
/* There's nothing more we can do. */
|
||||
/* Py_FatalError() will core dump, so just exit. */
|
||||
PySys_WriteStderr("Python error: <stdin> is a directory, cannot continue\n");
|
||||
exit(EXIT_FAILURE);
|
||||
return _Py_INIT_USER_ERR("<stdin> is a directory, "
|
||||
"cannot continue");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -2078,8 +2100,9 @@ _PySys_BeginInit(void)
|
|||
PyLong_GetInfo());
|
||||
/* initialize hash_info */
|
||||
if (Hash_InfoType.tp_name == NULL) {
|
||||
if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0)
|
||||
return NULL;
|
||||
if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) {
|
||||
goto type_init_failed;
|
||||
}
|
||||
}
|
||||
SET_SYS_FROM_STRING("hash_info",
|
||||
get_hash_info());
|
||||
|
@ -2109,8 +2132,9 @@ _PySys_BeginInit(void)
|
|||
/* version_info */
|
||||
if (VersionInfoType.tp_name == NULL) {
|
||||
if (PyStructSequence_InitType2(&VersionInfoType,
|
||||
&version_info_desc) < 0)
|
||||
return NULL;
|
||||
&version_info_desc) < 0) {
|
||||
goto type_init_failed;
|
||||
}
|
||||
}
|
||||
version_info = make_version_info();
|
||||
SET_SYS_FROM_STRING("version_info", version_info);
|
||||
|
@ -2126,8 +2150,9 @@ _PySys_BeginInit(void)
|
|||
|
||||
/* flags */
|
||||
if (FlagsType.tp_name == 0) {
|
||||
if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0)
|
||||
return NULL;
|
||||
if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0) {
|
||||
goto type_init_failed;
|
||||
}
|
||||
}
|
||||
/* Set flags to their default values */
|
||||
SET_SYS_FROM_STRING("flags", make_flags());
|
||||
|
@ -2136,14 +2161,17 @@ _PySys_BeginInit(void)
|
|||
/* getwindowsversion */
|
||||
if (WindowsVersionType.tp_name == 0)
|
||||
if (PyStructSequence_InitType2(&WindowsVersionType,
|
||||
&windows_version_desc) < 0)
|
||||
return NULL;
|
||||
&windows_version_desc) < 0) {
|
||||
goto type_init_failed;
|
||||
}
|
||||
/* prevent user from creating new instances */
|
||||
WindowsVersionType.tp_init = NULL;
|
||||
WindowsVersionType.tp_new = NULL;
|
||||
assert(!PyErr_Occurred());
|
||||
res = PyDict_DelItemString(WindowsVersionType.tp_dict, "__new__");
|
||||
if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
|
||||
if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
|
||||
|
@ -2161,13 +2189,22 @@ _PySys_BeginInit(void)
|
|||
if (AsyncGenHooksType.tp_name == NULL) {
|
||||
if (PyStructSequence_InitType2(
|
||||
&AsyncGenHooksType, &asyncgen_hooks_desc) < 0) {
|
||||
return NULL;
|
||||
goto type_init_failed;
|
||||
}
|
||||
}
|
||||
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
return m;
|
||||
if (PyErr_Occurred()) {
|
||||
goto err_occurred;
|
||||
}
|
||||
|
||||
*sysmod = m;
|
||||
return _Py_INIT_OK();
|
||||
|
||||
type_init_failed:
|
||||
return _Py_INIT_ERR("failed to initialize a type");
|
||||
|
||||
err_occurred:
|
||||
return _Py_INIT_ERR("can't initialize sys module");
|
||||
}
|
||||
|
||||
#undef SET_SYS_FROM_STRING
|
||||
|
|
Loading…
Reference in New Issue