Browse Source
bpo-34170: Add Python/coreconfig.c for _PyCoreConfig (GH-8607)
bpo-34170: Add Python/coreconfig.c for _PyCoreConfig (GH-8607)
* Add Include/coreconfig.h * Move config_*() and _PyCoreConfig_*() functions from Modules/main.c to a new Python/coreconfig.c file. * Inline _Py_ReadHashSeed() into config_init_hash_seed() * Move global configuration variables to coreconfig.cpull/8608/head
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1314 additions and 1288 deletions
-
1Include/Python.h
-
318Include/coreconfig.h
-
6Include/internal/pystate.h
-
46Include/pylifecycle.h
-
256Include/pystate.h
-
4Makefile.pre.in
-
923Modules/main.c
-
2PCbuild/pythoncore.vcxproj
-
6PCbuild/pythoncore.vcxproj.filters
-
23Python/bltinmodule.c
-
29Python/bootstrap_hash.c
-
964Python/coreconfig.c
-
2Python/import.c
-
22Python/pylifecycle.c
@ -0,0 +1,318 @@ |
|||
#ifndef Py_PYCORECONFIG_H |
|||
#define Py_PYCORECONFIG_H |
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
|
|||
#ifndef Py_LIMITED_API |
|||
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_NO_MEMORY() _Py_INIT_USER_ERR("memory allocation failed") |
|||
#define _Py_INIT_FAILED(err) \ |
|||
(err.msg != NULL) |
|||
|
|||
#endif /* !defined(Py_LIMITED_API) */ |
|||
|
|||
|
|||
typedef struct { |
|||
/* Install signal handlers? Yes by default. */ |
|||
int install_signal_handlers; |
|||
|
|||
/* If greater than 0: use environment variables. |
|||
Set to 0 by -E command line option. If set to -1 (default), it is |
|||
set to !Py_IgnoreEnvironmentFlag. */ |
|||
int use_environment; |
|||
|
|||
int use_hash_seed; /* PYTHONHASHSEED=x */ |
|||
unsigned long hash_seed; |
|||
|
|||
const char *allocator; /* Memory allocator: PYTHONMALLOC */ |
|||
int dev_mode; /* PYTHONDEVMODE, -X dev */ |
|||
|
|||
/* Enable faulthandler? |
|||
Set to 1 by -X faulthandler and PYTHONFAULTHANDLER. -1 means unset. */ |
|||
int faulthandler; |
|||
|
|||
/* Enable tracemalloc? |
|||
Set by -X tracemalloc=N and PYTHONTRACEMALLOC. -1 means unset */ |
|||
int tracemalloc; |
|||
|
|||
int import_time; /* PYTHONPROFILEIMPORTTIME, -X importtime */ |
|||
int show_ref_count; /* -X showrefcount */ |
|||
int show_alloc_count; /* -X showalloccount */ |
|||
int dump_refs; /* PYTHONDUMPREFS */ |
|||
int malloc_stats; /* PYTHONMALLOCSTATS */ |
|||
int coerce_c_locale; /* PYTHONCOERCECLOCALE, -1 means unknown */ |
|||
int coerce_c_locale_warn; /* PYTHONCOERCECLOCALE=warn */ |
|||
|
|||
/* Enable UTF-8 mode? |
|||
Set by -X utf8 command line option and PYTHONUTF8 environment variable. |
|||
If set to -1 (default), inherit Py_UTF8Mode value. */ |
|||
int utf8_mode; |
|||
|
|||
wchar_t *pycache_prefix; /* PYTHONPYCACHEPREFIX, -X pycache_prefix=PATH */ |
|||
|
|||
wchar_t *program_name; /* Program name, see also Py_GetProgramName() */ |
|||
int argc; /* Number of command line arguments, |
|||
-1 means unset */ |
|||
wchar_t **argv; /* Command line arguments */ |
|||
wchar_t *program; /* argv[0] or "" */ |
|||
|
|||
int nxoption; /* Number of -X options */ |
|||
wchar_t **xoptions; /* -X options */ |
|||
|
|||
int nwarnoption; /* Number of warnings options */ |
|||
wchar_t **warnoptions; /* Warnings options */ |
|||
|
|||
/* Path configuration inputs */ |
|||
wchar_t *module_search_path_env; /* PYTHONPATH environment variable */ |
|||
wchar_t *home; /* PYTHONHOME environment variable, |
|||
see also Py_SetPythonHome(). */ |
|||
|
|||
/* Path configuration outputs */ |
|||
int nmodule_search_path; /* Number of sys.path paths, |
|||
-1 means unset */ |
|||
wchar_t **module_search_paths; /* sys.path paths */ |
|||
wchar_t *executable; /* sys.executable */ |
|||
wchar_t *prefix; /* sys.prefix */ |
|||
wchar_t *base_prefix; /* sys.base_prefix */ |
|||
wchar_t *exec_prefix; /* sys.exec_prefix */ |
|||
wchar_t *base_exec_prefix; /* sys.base_exec_prefix */ |
|||
#ifdef MS_WINDOWS |
|||
wchar_t *dll_path; /* Windows DLL path */ |
|||
#endif |
|||
|
|||
/* If greater than 0, enable isolated mode: sys.path contains |
|||
neither the script's directory nor the user's site-packages directory. |
|||
|
|||
Set to 1 by the -I command line option. If set to -1 (default), inherit |
|||
Py_IsolatedFlag value. */ |
|||
int isolated; |
|||
|
|||
/* If equal to zero, disable the import of the module site and the |
|||
site-dependent manipulations of sys.path that it entails. Also disable |
|||
these manipulations if site is explicitly imported later (call |
|||
site.main() if you want them to be triggered). |
|||
|
|||
Set to 0 by the -S command line option. If set to -1 (default), it is |
|||
set to !Py_NoSiteFlag. */ |
|||
int site_import; |
|||
|
|||
/* Bytes warnings: |
|||
|
|||
* If equal to 1, issue a warning when comparing bytes or bytearray with |
|||
str or bytes with int. |
|||
* If equal or greater to 2, issue an error. |
|||
|
|||
Incremented by the -b command line option. If set to -1 (default), inherit |
|||
Py_BytesWarningFlag value. */ |
|||
int bytes_warning; |
|||
|
|||
/* If greater than 0, enable inspect: when a script is passed as first |
|||
argument or the -c option is used, enter interactive mode after |
|||
executing the script or the command, even when sys.stdin does not appear |
|||
to be a terminal. |
|||
|
|||
Incremented by the -i command line option. Set to 1 if the PYTHONINSPECT |
|||
environment variable is non-empty. If set to -1 (default), inherit |
|||
Py_InspectFlag value. */ |
|||
int inspect; |
|||
|
|||
/* If greater than 0: enable the interactive mode (REPL). |
|||
|
|||
Incremented by the -i command line option. If set to -1 (default), |
|||
inherit Py_InteractiveFlag value. */ |
|||
int interactive; |
|||
|
|||
/* Optimization level. |
|||
|
|||
Incremented by the -O command line option. Set by the PYTHONOPTIMIZE |
|||
environment variable. If set to -1 (default), inherit Py_OptimizeFlag |
|||
value. */ |
|||
int optimization_level; |
|||
|
|||
/* If greater than 0, enable the debug mode: turn on parser debugging |
|||
output (for expert only, depending on compilation options). |
|||
|
|||
Incremented by the -d command line option. Set by the PYTHONDEBUG |
|||
environment variable. If set to -1 (default), inherit Py_DebugFlag |
|||
value. */ |
|||
int parser_debug; |
|||
|
|||
/* If equal to 0, Python won't try to write ``.pyc`` files on the |
|||
import of source modules. |
|||
|
|||
Set to 0 by the -B command line option and the PYTHONDONTWRITEBYTECODE |
|||
environment variable. If set to -1 (default), it is set to |
|||
!Py_DontWriteBytecodeFlag. */ |
|||
int write_bytecode; |
|||
|
|||
/* If greater than 0, enable the verbose mode: print a message each time a |
|||
module is initialized, showing the place (filename or built-in module) |
|||
from which it is loaded. |
|||
|
|||
If greater or equal to 2, print a message for each file that is checked |
|||
for when searching for a module. Also provides information on module |
|||
cleanup at exit. |
|||
|
|||
Incremented by the -v option. Set by the PYTHONVERBOSE environment |
|||
variable. If set to -1 (default), inherit Py_VerboseFlag value. */ |
|||
int verbose; |
|||
|
|||
/* If greater than 0, enable the quiet mode: Don't display the copyright |
|||
and version messages even in interactive mode. |
|||
|
|||
Incremented by the -q option. If set to -1 (default), inherit |
|||
Py_QuietFlag value. */ |
|||
int quiet; |
|||
|
|||
/* If greater than 0, don't add the user site-packages directory to |
|||
sys.path. |
|||
|
|||
Set to 0 by the -s and -I command line options , and the PYTHONNOUSERSITE |
|||
environment variable. If set to -1 (default), it is set to |
|||
!Py_NoUserSiteDirectory. */ |
|||
int user_site_directory; |
|||
|
|||
/* If equal to 0, enable unbuffered mode: force the stdout and stderr |
|||
streams to be unbuffered. |
|||
|
|||
Set to 0 by the -u option. Set by the PYTHONUNBUFFERED environment |
|||
variable. |
|||
If set to -1 (default), it is set to !Py_UnbufferedStdioFlag. */ |
|||
int buffered_stdio; |
|||
|
|||
#ifdef MS_WINDOWS |
|||
/* If greater than 1, use the "mbcs" encoding instead of the UTF-8 |
|||
encoding for the filesystem encoding. |
|||
|
|||
Set to 1 if the PYTHONLEGACYWINDOWSFSENCODING environment variable is |
|||
set to a non-empty string. If set to -1 (default), inherit |
|||
Py_LegacyWindowsFSEncodingFlag value. |
|||
|
|||
See PEP 529 for more details. */ |
|||
int legacy_windows_fs_encoding; |
|||
|
|||
/* If greater than zero, use io.FileIO instead of WindowsConsoleIO for sys |
|||
standard streams. |
|||
|
|||
Set to 1 if the PYTHONLEGACYWINDOWSSTDIO environment variable is set to |
|||
a non-empty string. If set to -1 (default), inherit |
|||
Py_LegacyWindowsStdioFlag value. |
|||
|
|||
See PEP 528 for more details. */ |
|||
int legacy_windows_stdio; |
|||
#endif |
|||
|
|||
/* --- Private fields -------- */ |
|||
|
|||
/* Install importlib? If set to 0, importlib is not initialized at all. |
|||
Needed by freeze_importlib. */ |
|||
int _install_importlib; |
|||
|
|||
/* Value of the --check-hash-based-pycs configure option. Valid values: |
|||
|
|||
- "default" means the 'check_source' flag in hash-based pycs |
|||
determines invalidation |
|||
- "always" causes the interpreter to hash the source file for |
|||
invalidation regardless of value of 'check_source' bit |
|||
- "never" causes the interpreter to always assume hash-based pycs are |
|||
valid |
|||
|
|||
Set by the --check-hash-based-pycs command line option. |
|||
If set to NULL (default), inherit _Py_CheckHashBasedPycsMode value. |
|||
|
|||
See PEP 552 "Deterministic pycs" for more details. */ |
|||
const char *_check_hash_pycs_mode; |
|||
|
|||
/* If greater than 0, suppress _PyPathConfig_Calculate() warnings. |
|||
|
|||
If set to -1 (default), inherit Py_FrozenFlag value. */ |
|||
int _frozen; |
|||
|
|||
} _PyCoreConfig; |
|||
|
|||
#ifdef MS_WINDOWS |
|||
# define _PyCoreConfig_WINDOWS_INIT \ |
|||
.legacy_windows_fs_encoding = -1, \ |
|||
.legacy_windows_stdio = -1, |
|||
#else |
|||
# define _PyCoreConfig_WINDOWS_INIT |
|||
#endif |
|||
|
|||
#define _PyCoreConfig_INIT \ |
|||
(_PyCoreConfig){ \ |
|||
.install_signal_handlers = 1, \ |
|||
.use_environment = -1, \ |
|||
.use_hash_seed = -1, \ |
|||
.faulthandler = -1, \ |
|||
.tracemalloc = -1, \ |
|||
.coerce_c_locale = -1, \ |
|||
.utf8_mode = -1, \ |
|||
.argc = -1, \ |
|||
.nmodule_search_path = -1, \ |
|||
.isolated = -1, \ |
|||
.site_import = -1, \ |
|||
.bytes_warning = -1, \ |
|||
.inspect = -1, \ |
|||
.interactive = -1, \ |
|||
.optimization_level = -1, \ |
|||
.parser_debug= -1, \ |
|||
.write_bytecode = -1, \ |
|||
.verbose = -1, \ |
|||
.quiet = -1, \ |
|||
.user_site_directory = -1, \ |
|||
.buffered_stdio = -1, \ |
|||
_PyCoreConfig_WINDOWS_INIT \ |
|||
._install_importlib = 1, \ |
|||
._frozen = -1} |
|||
/* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */ |
|||
|
|||
|
|||
#ifndef Py_LIMITED_API |
|||
PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config); |
|||
PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *); |
|||
PyAPI_FUNC(int) _PyCoreConfig_Copy( |
|||
_PyCoreConfig *config, |
|||
const _PyCoreConfig *config2); |
|||
PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPathConfig(_PyCoreConfig *config); |
|||
PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPathConfig( |
|||
const _PyCoreConfig *config); |
|||
PyAPI_FUNC(void) _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config); |
|||
PyAPI_FUNC(void) _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config); |
|||
PyAPI_FUNC(const char*) _PyCoreConfig_GetEnv( |
|||
const _PyCoreConfig *config, |
|||
const char *name); |
|||
PyAPI_FUNC(int) _PyCoreConfig_GetEnvDup( |
|||
const _PyCoreConfig *config, |
|||
wchar_t **dest, |
|||
wchar_t *wname, |
|||
char *name); |
|||
#endif |
|||
|
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
#endif /* !Py_PYCORECONFIG_H */ |
|||
923
Modules/main.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,964 @@ |
|||
#include "Python.h" |
|||
#include "internal/import.h" |
|||
#include "internal/pystate.h" |
|||
|
|||
|
|||
#define DECODE_LOCALE_ERR(NAME, LEN) \ |
|||
(((LEN) == -2) \ |
|||
? _Py_INIT_USER_ERR("cannot decode " NAME) \ |
|||
: _Py_INIT_NO_MEMORY()) |
|||
|
|||
|
|||
/* Global configuration variables */ |
|||
|
|||
/* The default encoding used by the platform file system APIs |
|||
Can remain NULL for all platforms that don't have such a concept |
|||
|
|||
Don't forget to modify PyUnicode_DecodeFSDefault() if you touch any of the |
|||
values for Py_FileSystemDefaultEncoding! |
|||
*/ |
|||
#if defined(__APPLE__) |
|||
const char *Py_FileSystemDefaultEncoding = "utf-8"; |
|||
int Py_HasFileSystemDefaultEncoding = 1; |
|||
#elif defined(MS_WINDOWS) |
|||
/* may be changed by initfsencoding(), but should never be free()d */ |
|||
const char *Py_FileSystemDefaultEncoding = "utf-8"; |
|||
int Py_HasFileSystemDefaultEncoding = 1; |
|||
#else |
|||
const char *Py_FileSystemDefaultEncoding = NULL; /* set by initfsencoding() */ |
|||
int Py_HasFileSystemDefaultEncoding = 0; |
|||
#endif |
|||
const char *Py_FileSystemDefaultEncodeErrors = "surrogateescape"; |
|||
/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change |
|||
stdin and stdout error handler to "surrogateescape". It is equal to |
|||
-1 by default: unknown, will be set by Py_Main() */ |
|||
int Py_UTF8Mode = -1; |
|||
int Py_DebugFlag = 0; /* Needed by parser.c */ |
|||
int Py_VerboseFlag = 0; /* Needed by import.c */ |
|||
int Py_QuietFlag = 0; /* Needed by sysmodule.c */ |
|||
int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */ |
|||
int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */ |
|||
int Py_OptimizeFlag = 0; /* Needed by compile.c */ |
|||
int Py_NoSiteFlag = 0; /* Suppress 'import site' */ |
|||
int Py_BytesWarningFlag = 0; /* Warn on str(bytes) and str(buffer) */ |
|||
int Py_FrozenFlag = 0; /* Needed by getpath.c */ |
|||
int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */ |
|||
int Py_DontWriteBytecodeFlag = 0; /* Suppress writing bytecode files (*.pyc) */ |
|||
int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ |
|||
int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */ |
|||
int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */ |
|||
int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */ |
|||
#ifdef MS_WINDOWS |
|||
int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */ |
|||
int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */ |
|||
#endif |
|||
const char *_Py_CheckHashBasedPycsMode = "default"; |
|||
|
|||
|
|||
void |
|||
_Py_wstrlist_clear(int len, wchar_t **list) |
|||
{ |
|||
for (int i=0; i < len; i++) { |
|||
PyMem_RawFree(list[i]); |
|||
} |
|||
PyMem_RawFree(list); |
|||
} |
|||
|
|||
|
|||
wchar_t** |
|||
_Py_wstrlist_copy(int len, wchar_t **list) |
|||
{ |
|||
assert((len > 0 && list != NULL) || len == 0); |
|||
size_t size = len * sizeof(list[0]); |
|||
wchar_t **list_copy = PyMem_RawMalloc(size); |
|||
for (int i=0; i < len; i++) { |
|||
wchar_t* arg = _PyMem_RawWcsdup(list[i]); |
|||
if (arg == NULL) { |
|||
_Py_wstrlist_clear(i, list); |
|||
return NULL; |
|||
} |
|||
list_copy[i] = arg; |
|||
} |
|||
return list_copy; |
|||
} |
|||
|
|||
|
|||
/* Free memory allocated in config, but don't clear all attributes */ |
|||
void |
|||
_PyCoreConfig_Clear(_PyCoreConfig *config) |
|||
{ |
|||
#define CLEAR(ATTR) \ |
|||
do { \ |
|||
PyMem_RawFree(ATTR); \ |
|||
ATTR = NULL; \ |
|||
} while (0) |
|||
#define CLEAR_WSTRLIST(LEN, LIST) \ |
|||
do { \ |
|||
_Py_wstrlist_clear(LEN, LIST); \ |
|||
LEN = 0; \ |
|||
LIST = NULL; \ |
|||
} while (0) |
|||
|
|||
CLEAR(config->pycache_prefix); |
|||
CLEAR(config->module_search_path_env); |
|||
CLEAR(config->home); |
|||
CLEAR(config->program_name); |
|||
CLEAR(config->program); |
|||
|
|||
CLEAR_WSTRLIST(config->argc, config->argv); |
|||
config->argc = -1; |
|||
|
|||
CLEAR_WSTRLIST(config->nwarnoption, config->warnoptions); |
|||
CLEAR_WSTRLIST(config->nxoption, config->xoptions); |
|||
CLEAR_WSTRLIST(config->nmodule_search_path, config->module_search_paths); |
|||
config->nmodule_search_path = -1; |
|||
|
|||
CLEAR(config->executable); |
|||
CLEAR(config->prefix); |
|||
CLEAR(config->base_prefix); |
|||
CLEAR(config->exec_prefix); |
|||
#ifdef MS_WINDOWS |
|||
CLEAR(config->dll_path); |
|||
#endif |
|||
CLEAR(config->base_exec_prefix); |
|||
#undef CLEAR |
|||
#undef CLEAR_WSTRLIST |
|||
} |
|||
|
|||
|
|||
int |
|||
_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) |
|||
{ |
|||
_PyCoreConfig_Clear(config); |
|||
|
|||
#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR |
|||
#define COPY_STR_ATTR(ATTR) \ |
|||
do { \ |
|||
if (config2->ATTR != NULL) { \ |
|||
config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \ |
|||
if (config->ATTR == NULL) { \ |
|||
return -1; \ |
|||
} \ |
|||
} \ |
|||
} while (0) |
|||
#define COPY_WSTRLIST(LEN, LIST) \ |
|||
do { \ |
|||
if (config2->LIST != NULL) { \ |
|||
config->LIST = _Py_wstrlist_copy(config2->LEN, config2->LIST); \ |
|||
if (config->LIST == NULL) { \ |
|||
return -1; \ |
|||
} \ |
|||
} \ |
|||
config->LEN = config2->LEN; \ |
|||
} while (0) |
|||
|
|||
COPY_ATTR(install_signal_handlers); |
|||
COPY_ATTR(use_environment); |
|||
COPY_ATTR(use_hash_seed); |
|||
COPY_ATTR(hash_seed); |
|||
COPY_ATTR(_install_importlib); |
|||
COPY_ATTR(allocator); |
|||
COPY_ATTR(dev_mode); |
|||
COPY_ATTR(faulthandler); |
|||
COPY_ATTR(tracemalloc); |
|||
COPY_ATTR(import_time); |
|||
COPY_ATTR(show_ref_count); |
|||
COPY_ATTR(show_alloc_count); |
|||
COPY_ATTR(dump_refs); |
|||
COPY_ATTR(malloc_stats); |
|||
|
|||
COPY_ATTR(coerce_c_locale); |
|||
COPY_ATTR(coerce_c_locale_warn); |
|||
COPY_ATTR(utf8_mode); |
|||
|
|||
COPY_STR_ATTR(pycache_prefix); |
|||
COPY_STR_ATTR(module_search_path_env); |
|||
COPY_STR_ATTR(home); |
|||
COPY_STR_ATTR(program_name); |
|||
COPY_STR_ATTR(program); |
|||
|
|||
COPY_WSTRLIST(argc, argv); |
|||
COPY_WSTRLIST(nwarnoption, warnoptions); |
|||
COPY_WSTRLIST(nxoption, xoptions); |
|||
COPY_WSTRLIST(nmodule_search_path, module_search_paths); |
|||
|
|||
COPY_STR_ATTR(executable); |
|||
COPY_STR_ATTR(prefix); |
|||
COPY_STR_ATTR(base_prefix); |
|||
COPY_STR_ATTR(exec_prefix); |
|||
#ifdef MS_WINDOWS |
|||
COPY_STR_ATTR(dll_path); |
|||
#endif |
|||
COPY_STR_ATTR(base_exec_prefix); |
|||
|
|||
COPY_ATTR(isolated); |
|||
COPY_ATTR(site_import); |
|||
COPY_ATTR(bytes_warning); |
|||
COPY_ATTR(inspect); |
|||
COPY_ATTR(interactive); |
|||
COPY_ATTR(optimization_level); |
|||
COPY_ATTR(parser_debug); |
|||
COPY_ATTR(write_bytecode); |
|||
COPY_ATTR(verbose); |
|||
COPY_ATTR(quiet); |
|||
COPY_ATTR(user_site_directory); |
|||
COPY_ATTR(buffered_stdio); |
|||
#ifdef MS_WINDOWS |
|||
COPY_ATTR(legacy_windows_fs_encoding); |
|||
COPY_ATTR(legacy_windows_stdio); |
|||
#endif |
|||
COPY_ATTR(_check_hash_pycs_mode); |
|||
COPY_ATTR(_frozen); |
|||
|
|||
#undef COPY_ATTR |
|||
#undef COPY_STR_ATTR |
|||
#undef COPY_WSTRLIST |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
const char* |
|||
_PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name) |
|||
{ |
|||
assert(config->use_environment >= 0); |
|||
|
|||
if (!config->use_environment) { |
|||
return NULL; |
|||
} |
|||
|
|||
const char *var = getenv(name); |
|||
if (var && var[0] != '\0') { |
|||
return var; |
|||
} |
|||
else { |
|||
return NULL; |
|||
} |
|||
} |
|||
|
|||
|
|||
int |
|||
_PyCoreConfig_GetEnvDup(const _PyCoreConfig *config, |
|||
wchar_t **dest, |
|||
wchar_t *wname, char *name) |
|||
{ |
|||
assert(config->use_environment >= 0); |
|||
|
|||
if (!config->use_environment) { |
|||
*dest = NULL; |
|||
return 0; |
|||
} |
|||
|
|||
#ifdef MS_WINDOWS |
|||
const wchar_t *var = _wgetenv(wname); |
|||
if (!var || var[0] == '\0') { |
|||
*dest = NULL; |
|||
return 0; |
|||
} |
|||
|
|||
wchar_t *copy = _PyMem_RawWcsdup(var); |
|||
if (copy == NULL) { |
|||
return -1; |
|||
} |
|||
|
|||
*dest = copy; |
|||
#else |
|||
const char *var = getenv(name); |
|||
if (!var || var[0] == '\0') { |
|||
*dest = NULL; |
|||
return 0; |
|||
} |
|||
|
|||
size_t len; |
|||
wchar_t *wvar = Py_DecodeLocale(var, &len); |
|||
if (!wvar) { |
|||
if (len == (size_t)-2) { |
|||
return -2; |
|||
} |
|||
else { |
|||
return -1; |
|||
} |
|||
} |
|||
*dest = wvar; |
|||
#endif |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
void |
|||
_PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config) |
|||
{ |
|||
#define COPY_FLAG(ATTR, VALUE) \ |
|||
if (config->ATTR == -1) { \ |
|||
config->ATTR = VALUE; \ |
|||
} |
|||
#define COPY_NOT_FLAG(ATTR, VALUE) \ |
|||
if (config->ATTR == -1) { \ |
|||
config->ATTR = !(VALUE); \ |
|||
} |
|||
|
|||
COPY_FLAG(utf8_mode, Py_UTF8Mode); |
|||
COPY_FLAG(isolated, Py_IsolatedFlag); |
|||
COPY_FLAG(bytes_warning, Py_BytesWarningFlag); |
|||
COPY_FLAG(inspect, Py_InspectFlag); |
|||
COPY_FLAG(interactive, Py_InteractiveFlag); |
|||
COPY_FLAG(optimization_level, Py_OptimizeFlag); |
|||
COPY_FLAG(parser_debug, Py_DebugFlag); |
|||
COPY_FLAG(verbose, Py_VerboseFlag); |
|||
COPY_FLAG(quiet, Py_QuietFlag); |
|||
#ifdef MS_WINDOWS |
|||
COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); |
|||
COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag); |
|||
#endif |
|||
COPY_FLAG(_frozen, Py_FrozenFlag); |
|||
|
|||
COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); |
|||
COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag); |
|||
COPY_NOT_FLAG(site_import, Py_NoSiteFlag); |
|||
COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag); |
|||
COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory); |
|||
|
|||
if (config->_check_hash_pycs_mode == NULL) { |
|||
config->_check_hash_pycs_mode = _Py_CheckHashBasedPycsMode; |
|||
} |
|||
|
|||
#undef COPY_FLAG |
|||
#undef COPY_NOT_FLAG |
|||
} |
|||
|
|||
|
|||
/* Set Py_xxx global configuration variables from 'config' configuration. */ |
|||
void |
|||
_PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config) |
|||
{ |
|||
#define COPY_FLAG(ATTR, VAR) \ |
|||
if (config->ATTR != -1) { \ |
|||
VAR = config->ATTR; \ |
|||
} |
|||
#define COPY_NOT_FLAG(ATTR, VAR) \ |
|||
if (config->ATTR != -1) { \ |
|||
VAR = !config->ATTR; \ |
|||
} |
|||
|
|||
COPY_FLAG(utf8_mode, Py_UTF8Mode); |
|||
COPY_FLAG(isolated, Py_IsolatedFlag); |
|||
COPY_FLAG(bytes_warning, Py_BytesWarningFlag); |
|||
COPY_FLAG(inspect, Py_InspectFlag); |
|||
COPY_FLAG(interactive, Py_InteractiveFlag); |
|||
COPY_FLAG(optimization_level, Py_OptimizeFlag); |
|||
COPY_FLAG(parser_debug, Py_DebugFlag); |
|||
COPY_FLAG(verbose, Py_VerboseFlag); |
|||
COPY_FLAG(quiet, Py_QuietFlag); |
|||
#ifdef MS_WINDOWS |
|||
COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); |
|||
COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag); |
|||
#endif |
|||
|
|||
COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); |
|||
COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag); |
|||
COPY_NOT_FLAG(site_import, Py_NoSiteFlag); |
|||
COPY_NOT_FLAG(write_bytecode, Py_DontWriteBytecodeFlag); |
|||
COPY_NOT_FLAG(user_site_directory, Py_NoUserSiteDirectory); |
|||
|
|||
if (config->_check_hash_pycs_mode != NULL) { |
|||
_Py_CheckHashBasedPycsMode = config->_check_hash_pycs_mode; |
|||
} |
|||
|
|||
/* Random or non-zero hash seed */ |
|||
Py_HashRandomizationFlag = (config->use_hash_seed == 0 || |
|||
config->hash_seed != 0); |
|||
|
|||
#undef COPY_FLAG |
|||
#undef COPY_NOT_FLAG |
|||
} |
|||
|
|||
|
|||
/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__ |
|||
environment variables on macOS if available. */ |
|||
static _PyInitError |
|||
config_init_program_name(_PyCoreConfig *config) |
|||
{ |
|||
/* If Py_SetProgramName() was called, use its value */ |
|||
const wchar_t *program_name = _Py_path_config.program_name; |
|||
if (program_name != NULL) { |
|||
config->program_name = _PyMem_RawWcsdup(program_name); |
|||
if (config->program_name == NULL) { |
|||
return _Py_INIT_NO_MEMORY(); |
|||
} |
|||
return _Py_INIT_OK(); |
|||
} |
|||
|
|||
#ifdef __APPLE__ |
|||
/* On MacOS X, when the Python interpreter is embedded in an |
|||
application bundle, it gets executed by a bootstrapping script |
|||
that does os.execve() with an argv[0] that's different from the |
|||
actual Python executable. This is needed to keep the Finder happy, |
|||
or rather, to work around Apple's overly strict requirements of |
|||
the process name. However, we still need a usable sys.executable, |
|||
so the actual executable path is passed in an environment variable. |
|||
See Lib/plat-mac/bundlebuiler.py for details about the bootstrap |
|||
script. */ |
|||
const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE"); |
|||
if (p != NULL) { |
|||
size_t len; |
|||
wchar_t* program_name = Py_DecodeLocale(p, &len); |
|||
if (program_name == NULL) { |
|||
return DECODE_LOCALE_ERR("PYTHONEXECUTABLE environment " |
|||
"variable", (Py_ssize_t)len); |
|||
} |
|||
config->program_name = program_name; |
|||
return _Py_INIT_OK(); |
|||
} |
|||
#ifdef WITH_NEXT_FRAMEWORK |
|||
else { |
|||
const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__"); |
|||
if (pyvenv_launcher && *pyvenv_launcher) { |
|||
/* Used by Mac/Tools/pythonw.c to forward |
|||
* the argv0 of the stub executable |
|||
*/ |
|||
size_t len; |
|||
wchar_t* program_name = Py_DecodeLocale(pyvenv_launcher, &len); |
|||
if (program_name == NULL) { |
|||
return DECODE_LOCALE_ERR("__PYVENV_LAUNCHER__ environment " |
|||
"variable", (Py_ssize_t)len); |
|||
} |
|||
config->program_name = program_name; |
|||
return _Py_INIT_OK(); |
|||
} |
|||
} |
|||
#endif /* WITH_NEXT_FRAMEWORK */ |
|||
#endif /* __APPLE__ */ |
|||
|
|||
/* Use argv[0] by default, if available */ |
|||
if (config->program != NULL) { |
|||
config->program_name = _PyMem_RawWcsdup(config->program); |
|||
if (config->program_name == NULL) { |
|||
return _Py_INIT_NO_MEMORY(); |
|||
} |
|||
return _Py_INIT_OK(); |
|||
} |
|||
|
|||
/* Last fall back: hardcoded string */ |
|||
#ifdef MS_WINDOWS |
|||
const wchar_t *default_program_name = L"python"; |
|||
#else |
|||
const wchar_t *default_program_name = L"python3"; |
|||
#endif |
|||
config->program_name = _PyMem_RawWcsdup(default_program_name); |
|||
if (config->program_name == NULL) { |
|||
return _Py_INIT_NO_MEMORY(); |
|||
} |
|||
return _Py_INIT_OK(); |
|||
} |
|||
|
|||
|
|||
static const wchar_t* |
|||
config_get_xoption(const _PyCoreConfig *config, wchar_t *name) |
|||
{ |
|||
int nxoption = config->nxoption; |
|||
wchar_t **xoptions = config->xoptions; |
|||
for (int i=0; i < nxoption; i++) { |
|||
wchar_t *option = xoptions[i]; |
|||
size_t len; |
|||
wchar_t *sep = wcschr(option, L'='); |
|||
if (sep != NULL) { |
|||
len = (sep - option); |
|||
} |
|||
else { |
|||
len = wcslen(option); |
|||
} |
|||
if (wcsncmp(option, name, len) == 0 && name[len] == L'\0') { |
|||
return option; |
|||
} |
|||
} |
|||
return NULL; |
|||
} |
|||
|
|||
|
|||
static _PyInitError |
|||
config_init_home(_PyCoreConfig *config) |
|||
{ |
|||
wchar_t *home; |
|||
|
|||
/* If Py_SetPythonHome() was called, use its value */ |
|||
home = _Py_path_config.home; |
|||
if (home) { |
|||
config->home = _PyMem_RawWcsdup(home); |
|||
if (config->home == NULL) { |
|||
return _Py_INIT_NO_MEMORY(); |
|||
} |
|||
return _Py_INIT_OK(); |
|||
} |
|||
|
|||
int res = _PyCoreConfig_GetEnvDup(config, &home, |
|||
L"PYTHONHOME", "PYTHONHOME"); |
|||
if (res < 0) { |
|||
return DECODE_LOCALE_ERR("PYTHONHOME", res); |
|||
} |
|||
config->home = home; |
|||
return _Py_INIT_OK(); |
|||
} |
|||
|
|||
|
|||
static _PyInitError |
|||
config_init_hash_seed(_PyCoreConfig *config) |
|||
{ |
|||
const char *seed_text = _PyCoreConfig_GetEnv(config, "PYTHONHASHSEED"); |
|||
|
|||
Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc)); |
|||
/* Convert a text seed to a numeric one */ |
|||
if (seed_text && strcmp(seed_text, "random") != 0) { |
|||
const char *endptr = seed_text; |
|||
unsigned long seed; |
|||
errno = 0; |
|||
seed = strtoul(seed_text, (char **)&endptr, 10); |
|||
if (*endptr != '\0' |
|||
|| seed > 4294967295UL |
|||
|| (errno == ERANGE && seed == ULONG_MAX)) |
|||
{ |
|||
return _Py_INIT_USER_ERR("PYTHONHASHSEED must be \"random\" " |
|||
"or an integer in range [0; 4294967295]"); |
|||
} |
|||
/* Use a specific hash */ |
|||
config->use_hash_seed = 1; |
|||
config->hash_seed = seed; |
|||
} |
|||
else { |
|||
/* Use a random hash */ |
|||
config->use_hash_seed = 0; |
|||
config->hash_seed = 0; |
|||
} |
|||
return _Py_INIT_OK(); |
|||
} |
|||
|
|||
|
|||
static _PyInitError |
|||
config_init_utf8_mode(_PyCoreConfig *config) |
|||
{ |
|||
const wchar_t *xopt = config_get_xoption(config, L"utf8"); |
|||
if (xopt) { |
|||
wchar_t *sep = wcschr(xopt, L'='); |
|||
if (sep) { |
|||
xopt = sep + 1; |
|||
if (wcscmp(xopt, L"1") == 0) { |
|||
config->utf8_mode = 1; |
|||
} |
|||
else if (wcscmp(xopt, L"0") == 0) { |
|||
config->utf8_mode = 0; |
|||
} |
|||
else { |
|||
return _Py_INIT_USER_ERR("invalid -X utf8 option value"); |
|||
} |
|||
} |
|||
else { |
|||
config->utf8_mode = 1; |
|||
} |
|||
return _Py_INIT_OK(); |
|||
} |
|||
|
|||
const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONUTF8"); |
|||
if (opt) { |
|||
if (strcmp(opt, "1") == 0) { |
|||
config->utf8_mode = 1; |
|||
} |
|||
else if (strcmp(opt, "0") == 0) { |
|||
config->utf8_mode = 0; |
|||
} |
|||
else { |
|||
return _Py_INIT_USER_ERR("invalid PYTHONUTF8 environment " |
|||
"variable value"); |
|||
} |
|||
return _Py_INIT_OK(); |
|||
} |
|||
|
|||
return _Py_INIT_OK(); |
|||
} |
|||
|
|||
|
|||
static int |
|||
config_str_to_int(const char *str, int *result) |
|||
{ |
|||
const char *endptr = str; |
|||
errno = 0; |
|||
long value = strtol(str, (char **)&endptr, 10); |
|||
if (*endptr != '\0' || errno == ERANGE) { |
|||
return -1; |
|||
} |
|||
if (value < INT_MIN || value > INT_MAX) { |
|||
return -1; |
|||
} |
|||
|
|||
*result = (int)value; |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
static int |
|||
config_wstr_to_int(const wchar_t *wstr, int *result) |
|||
{ |
|||
const wchar_t *endptr = wstr; |
|||
errno = 0; |
|||
long value = wcstol(wstr, (wchar_t **)&endptr, 10); |
|||
if (*endptr != '\0' || errno == ERANGE) { |
|||
return -1; |
|||
} |
|||
if (value < INT_MIN || value > INT_MAX) { |
|||
return -1; |
|||
} |
|||
|
|||
*result = (int)value; |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
static void |
|||
get_env_flag(_PyCoreConfig *config, int *flag, const char *name) |
|||
{ |
|||
const char *var = _PyCoreConfig_GetEnv(config, name); |
|||
if (!var) { |
|||
return; |
|||
} |
|||
int value; |
|||
if (config_str_to_int(var, &value) < 0 || value < 0) { |
|||
/* PYTHONDEBUG=text and PYTHONDEBUG=-2 behave as PYTHONDEBUG=1 */ |
|||
value = 1; |
|||
} |
|||
if (*flag < value) { |
|||
*flag = value; |
|||
} |
|||
} |
|||
|
|||
|
|||
static _PyInitError |
|||
config_read_env_vars(_PyCoreConfig *config) |
|||
{ |
|||
assert(config->use_environment > 0); |
|||
|
|||
/* Get environment variables */ |
|||
get_env_flag(config, &config->parser_debug, "PYTHONDEBUG"); |
|||
get_env_flag(config, &config->verbose, "PYTHONVERBOSE"); |
|||
get_env_flag(config, &config->optimization_level, "PYTHONOPTIMIZE"); |
|||
get_env_flag(config, &config->inspect, "PYTHONINSPECT"); |
|||
|
|||
int dont_write_bytecode = 0; |
|||
get_env_flag(config, &dont_write_bytecode, "PYTHONDONTWRITEBYTECODE"); |
|||
if (dont_write_bytecode) { |
|||
config->write_bytecode = 0; |
|||
} |
|||
|
|||
int no_user_site_directory = 0; |
|||
get_env_flag(config, &no_user_site_directory, "PYTHONNOUSERSITE"); |
|||
if (no_user_site_directory) { |
|||
config->user_site_directory = 0; |
|||
} |
|||
|
|||
int unbuffered_stdio = 0; |
|||
get_env_flag(config, &unbuffered_stdio, "PYTHONUNBUFFERED"); |
|||
if (unbuffered_stdio) { |
|||
config->buffered_stdio = 0; |
|||
} |
|||
|
|||
#ifdef MS_WINDOWS |
|||
get_env_flag(config, &config->legacy_windows_fs_encoding, |
|||
"PYTHONLEGACYWINDOWSFSENCODING"); |
|||
get_env_flag(config, &config->legacy_windows_stdio, |
|||
"PYTHONLEGACYWINDOWSSTDIO"); |
|||
#endif |
|||
|
|||
if (config->allocator == NULL) { |
|||
config->allocator = _PyCoreConfig_GetEnv(config, "PYTHONMALLOC"); |
|||
} |
|||
|
|||
if (_PyCoreConfig_GetEnv(config, "PYTHONDUMPREFS")) { |
|||
config->dump_refs = 1; |
|||
} |
|||
if (_PyCoreConfig_GetEnv(config, "PYTHONMALLOCSTATS")) { |
|||
config->malloc_stats = 1; |
|||
} |
|||
|
|||
const char *env = _PyCoreConfig_GetEnv(config, "PYTHONCOERCECLOCALE"); |
|||
if (env) { |
|||
if (strcmp(env, "0") == 0) { |
|||
config->coerce_c_locale = 0; |
|||
} |
|||
else if (strcmp(env, "warn") == 0) { |
|||
config->coerce_c_locale_warn = 1; |
|||
} |
|||
else { |
|||
config->coerce_c_locale = 1; |
|||
} |
|||
} |
|||
|
|||
wchar_t *path; |
|||
int res = _PyCoreConfig_GetEnvDup(config, &path, |
|||
L"PYTHONPATH", "PYTHONPATH"); |
|||
if (res < 0) { |
|||
return DECODE_LOCALE_ERR("PYTHONPATH", res); |
|||
} |
|||
config->module_search_path_env = path; |
|||
|
|||
if (config->use_hash_seed < 0) { |
|||
_PyInitError err = config_init_hash_seed(config); |
|||
if (_Py_INIT_FAILED(err)) { |
|||
return err; |
|||
} |
|||
} |
|||
|
|||
return _Py_INIT_OK(); |
|||
} |
|||
|
|||
|
|||
static _PyInitError |
|||
config_init_tracemalloc(_PyCoreConfig *config) |
|||
{ |
|||
int nframe; |
|||
int valid; |
|||
|
|||
const char *env = _PyCoreConfig_GetEnv(config, "PYTHONTRACEMALLOC"); |
|||
if (env) { |
|||
if (!config_str_to_int(env, &nframe)) { |
|||
valid = (nframe >= 0); |
|||
} |
|||
else { |
|||
valid = 0; |
|||
} |
|||
if (!valid) { |
|||
return _Py_INIT_USER_ERR("PYTHONTRACEMALLOC: invalid number " |
|||
"of frames"); |
|||
} |
|||
config->tracemalloc = nframe; |
|||
} |
|||
|
|||
const wchar_t *xoption = config_get_xoption(config, L"tracemalloc"); |
|||
if (xoption) { |
|||
const wchar_t *sep = wcschr(xoption, L'='); |
|||
if (sep) { |
|||
if (!config_wstr_to_int(sep + 1, &nframe)) { |
|||
valid = (nframe >= 0); |
|||
} |
|||
else { |
|||
valid = 0; |
|||
} |
|||
if (!valid) { |
|||
return _Py_INIT_USER_ERR("-X tracemalloc=NFRAME: " |
|||
"invalid number of frames"); |
|||
} |
|||
} |
|||
else { |
|||
/* -X tracemalloc behaves as -X tracemalloc=1 */ |
|||
nframe = 1; |
|||
} |
|||
config->tracemalloc = nframe; |
|||
} |
|||
return _Py_INIT_OK(); |
|||
} |
|||
|
|||
|
|||
static _PyInitError |
|||
config_init_pycache_prefix(_PyCoreConfig *config) |
|||
{ |
|||
assert(config->pycache_prefix == NULL); |
|||
|
|||
const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix"); |
|||
if (xoption) { |
|||
const wchar_t *sep = wcschr(xoption, L'='); |
|||
if (sep && wcslen(sep) > 1) { |
|||
config->pycache_prefix = _PyMem_RawWcsdup(sep + 1); |
|||
if (config->pycache_prefix == NULL) { |
|||
return _Py_INIT_NO_MEMORY(); |
|||
} |
|||
} |
|||
else { |
|||
// -X pycache_prefix= can cancel the env var |
|||
config->pycache_prefix = NULL; |
|||
} |
|||
} |
|||
else { |
|||
wchar_t *env; |
|||
int res = _PyCoreConfig_GetEnvDup(config, &env, |
|||
L"PYTHONPYCACHEPREFIX", |
|||
"PYTHONPYCACHEPREFIX"); |
|||
if (res < 0) { |
|||
return DECODE_LOCALE_ERR("PYTHONPYCACHEPREFIX", res); |
|||
} |
|||
|
|||
if (env) { |
|||
config->pycache_prefix = env; |
|||
} |
|||
} |
|||
return _Py_INIT_OK(); |
|||
} |
|||
|
|||
|
|||
static _PyInitError |
|||
config_read_complex_options(_PyCoreConfig *config) |
|||
{ |
|||
/* More complex options configured by env var and -X option */ |
|||
if (config->faulthandler < 0) { |
|||
if (_PyCoreConfig_GetEnv(config, "PYTHONFAULTHANDLER") |
|||
|| config_get_xoption(config, L"faulthandler")) { |
|||
config->faulthandler = 1; |
|||
} |
|||
} |
|||
if (_PyCoreConfig_GetEnv(config, "PYTHONPROFILEIMPORTTIME") |
|||
|| config_get_xoption(config, L"importtime")) { |
|||
config->import_time = 1; |
|||
} |
|||
if (config_get_xoption(config, L"dev" ) || |
|||
_PyCoreConfig_GetEnv(config, "PYTHONDEVMODE")) |
|||
{ |
|||
config->dev_mode = 1; |
|||
} |
|||
|
|||
_PyInitError err; |
|||
if (config->tracemalloc < 0) { |
|||
err = config_init_tracemalloc(config); |
|||
if (_Py_INIT_FAILED(err)) { |
|||
return err; |
|||
} |
|||
} |
|||
|
|||
if (config->pycache_prefix == NULL) { |
|||
err = config_init_pycache_prefix(config); |
|||
if (_Py_INIT_FAILED(err)) { |
|||
return err; |
|||
} |
|||
} |
|||
return _Py_INIT_OK(); |
|||
} |
|||
|
|||
|
|||
static void |
|||
config_init_locale(_PyCoreConfig *config) |
|||
{ |
|||
if (config->utf8_mode >= 0 && config->coerce_c_locale >= 0) { |
|||
return; |
|||
} |
|||
|
|||
if (_Py_LegacyLocaleDetected()) { |
|||
/* POSIX locale: enable C locale coercion and UTF-8 Mode */ |
|||
if (config->utf8_mode < 0) { |
|||
config->utf8_mode = 1; |
|||
} |
|||
if (config->coerce_c_locale < 0) { |
|||
config->coerce_c_locale = 1; |
|||
} |
|||
return; |
|||
} |
|||
} |
|||
|
|||
|
|||
/* Read configuration settings from standard locations |
|||
* |
|||
* This function doesn't make any changes to the interpreter state - it |
|||
* merely populates any missing configuration settings. This allows an |
|||
* embedding application to completely override a config option by |
|||
* setting it before calling this function, or else modify the default |
|||
* setting before passing the fully populated config to Py_EndInitialization. |
|||
* |
|||
* More advanced selective initialization tricks are possible by calling |
|||
* this function multiple times with various preconfigured settings. |
|||
*/ |
|||
|
|||
_PyInitError |
|||
_PyCoreConfig_Read(_PyCoreConfig *config) |
|||
{ |
|||
_PyInitError err; |
|||
|
|||
_PyCoreConfig_GetGlobalConfig(config); |
|||
|
|||
if (config->isolated > 0) { |
|||
config->use_environment = 0; |
|||
config->user_site_directory = 0; |
|||
} |
|||
|
|||
#ifdef MS_WINDOWS |
|||
if (config->legacy_windows_fs_encoding) { |
|||
config->utf8_mode = 0; |
|||
} |
|||
#endif |
|||
|
|||
assert(config->use_environment >= 0); |
|||
if (config->use_environment) { |
|||
err = config_read_env_vars(config); |
|||
if (_Py_INIT_FAILED(err)) { |
|||
return err; |
|||
} |
|||
} |
|||
|
|||
/* -X options */ |
|||
if (config_get_xoption(config, L"showrefcount")) { |
|||
config->show_ref_count = 1; |
|||
} |
|||
if (config_get_xoption(config, L"showalloccount")) { |
|||
config->show_alloc_count = 1; |
|||
} |
|||
|
|||
err = config_read_complex_options(config); |
|||
if (_Py_INIT_FAILED(err)) { |
|||
return err; |
|||
} |
|||
|
|||
if (config->utf8_mode < 0) { |
|||
err = config_init_utf8_mode(config); |
|||
if (_Py_INIT_FAILED(err)) { |
|||
return err; |
|||
} |
|||
} |
|||
|
|||
if (config->home == NULL) { |
|||
err = config_init_home(config); |
|||
if (_Py_INIT_FAILED(err)) { |
|||
return err; |
|||
} |
|||
} |
|||
|
|||
if (config->program_name == NULL) { |
|||
err = config_init_program_name(config); |
|||
if (_Py_INIT_FAILED(err)) { |
|||
return err; |
|||
} |
|||
} |
|||
|
|||
config_init_locale(config); |
|||
|
|||
if (config->_install_importlib) { |
|||
err = _PyCoreConfig_InitPathConfig(config); |
|||
if (_Py_INIT_FAILED(err)) { |
|||
return err; |
|||
} |
|||
} |
|||
|
|||
/* default values */ |
|||
if (config->dev_mode) { |
|||
if (config->faulthandler < 0) { |
|||
config->faulthandler = 1; |
|||
} |
|||
if (config->allocator == NULL) { |
|||
config->allocator = "debug"; |
|||
} |
|||
} |
|||
if (config->use_hash_seed < 0) { |
|||
config->use_hash_seed = 0; |
|||
config->hash_seed = 0; |
|||
} |
|||
if (config->faulthandler < 0) { |
|||
config->faulthandler = 0; |
|||
} |
|||
if (config->tracemalloc < 0) { |
|||
config->tracemalloc = 0; |
|||
} |
|||
if (config->coerce_c_locale < 0) { |
|||
config->coerce_c_locale = 0; |
|||
} |
|||
if (config->utf8_mode < 0) { |
|||
config->utf8_mode = 0; |
|||
} |
|||
if (config->_frozen < 0) { |
|||
config->_frozen = 0; |
|||
} |
|||
if (config->argc < 0) { |
|||
config->argc = 0; |
|||
} |
|||
|
|||
return _Py_INIT_OK(); |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue