static void pathconfig_global_init(void) { if (_Py_path_config.module_search_path != NULL) { /* Already initialized */ return; } _PyInitError err; _PyCoreConfig config = _PyCoreConfig_INIT; err = _PyCoreConfig_Read(&config); if (_Py_INIT_FAILED(err)) { goto error; } err = _PyCoreConfig_SetPathConfig(&config); if (_Py_INIT_FAILED(err)) { goto error; } _PyCoreConfig_Clear(&config); return; error: _PyCoreConfig_Clear(&config); _Py_FatalInitError(err); }
static _PyInitError calculate_path_impl(const _PyCoreConfig *core_config, PyCalculatePath *calculate, _PyPathConfig *config) { _PyInitError err; err = calculate_program_full_path(core_config, calculate, config); if (_Py_INIT_FAILED(err)) { return err; } err = calculate_argv0_path(calculate, config->program_full_path); if (_Py_INIT_FAILED(err)) { return err; } calculate_read_pyenv(calculate); wchar_t prefix[MAXPATHLEN+1]; memset(prefix, 0, sizeof(prefix)); calculate_prefix(core_config, calculate, prefix); calculate_zip_path(calculate, prefix); wchar_t exec_prefix[MAXPATHLEN+1]; memset(exec_prefix, 0, sizeof(exec_prefix)); calculate_exec_prefix(core_config, calculate, exec_prefix); if ((!calculate->prefix_found || !calculate->exec_prefix_found) && !core_config->_frozen) { fprintf(stderr, "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n"); } err = calculate_module_search_path(core_config, calculate, prefix, exec_prefix, config); if (_Py_INIT_FAILED(err)) { return err; } calculate_reduce_prefix(calculate, prefix); config->prefix = _PyMem_RawWcsdup(prefix); if (config->prefix == NULL) { return _Py_INIT_NO_MEMORY(); } calculate_reduce_exec_prefix(calculate, exec_prefix); config->exec_prefix = _PyMem_RawWcsdup(exec_prefix); if (config->exec_prefix == NULL) { return _Py_INIT_NO_MEMORY(); } return _Py_INIT_OK(); }
static _PyInitError calculate_path_impl(const _PyCoreConfig *core_config, PyCalculatePath *calculate, _PyPathConfig *config) { _PyInitError err; err = get_dll_path(calculate, config); if (_Py_INIT_FAILED(err)) { return err; } err = get_program_full_path(core_config, calculate, config); if (_Py_INIT_FAILED(err)) { return err; } /* program_full_path guaranteed \0 terminated in MAXPATH+1 bytes. */ wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, config->program_full_path); reduce(calculate->argv0_path); wchar_t prefix[MAXPATHLEN+1]; memset(prefix, 0, sizeof(prefix)); /* Search for a sys.path file */ if (calculate_pth_file(config, prefix)) { goto done; } calculate_pyvenv_file(calculate); /* Calculate zip archive path from DLL or exe path */ change_ext(calculate->zip_path, config->dll_path[0] ? config->dll_path : config->program_full_path, L".zip"); calculate_home_prefix(calculate, prefix); err = calculate_module_search_path(core_config, calculate, config, prefix); if (_Py_INIT_FAILED(err)) { return err; } done: config->prefix = _PyMem_RawWcsdup(prefix); if (config->prefix == NULL) { return _Py_INIT_NO_MEMORY(); } return _Py_INIT_OK(); }
/* Set the global path configuration from core_config. */ _PyInitError _PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config) { PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); _PyInitError err; _PyPathConfig path_config = _PyPathConfig_INIT; path_config.module_search_path = wstrlist_join(DELIM, core_config->nmodule_search_path, core_config->module_search_paths); if (path_config.module_search_path == NULL) { goto no_memory; } if (copy_wstr(&path_config.program_full_path, core_config->executable) < 0) { goto no_memory; } if (copy_wstr(&path_config.prefix, core_config->prefix) < 0) { goto no_memory; } #ifdef MS_WINDOWS if (copy_wstr(&path_config.dll_path, core_config->dll_path) < 0) { goto no_memory; } #else if (copy_wstr(&path_config.exec_prefix, core_config->exec_prefix) < 0) { goto no_memory; } #endif if (copy_wstr(&path_config.program_name, core_config->program_name) < 0) { goto no_memory; } if (copy_wstr(&path_config.home, core_config->home) < 0) { goto no_memory; } err = _PyPathConfig_SetGlobal(&path_config); if (_Py_INIT_FAILED(err)) { goto done; } err = _Py_INIT_OK(); goto done; no_memory: err = _Py_INIT_NO_MEMORY(); done: _PyPathConfig_Clear(&path_config); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); return err; }
_PyInitError _PyPathConfig_Calculate_impl(_PyPathConfig *config, const _PyCoreConfig *core_config) { PyCalculatePath calculate; memset(&calculate, 0, sizeof(calculate)); _PyInitError err = calculate_init(&calculate, core_config); if (_Py_INIT_FAILED(err)) { goto done; } err = calculate_path_impl(core_config, &calculate, config); if (_Py_INIT_FAILED(err)) { goto done; } err = _Py_INIT_OK(); done: calculate_free(&calculate); return err; }
static int test_init_dev_mode(void) { _PyCoreConfig config = _PyCoreConfig_INIT; putenv("PYTHONFAULTHANDLER="); putenv("PYTHONMALLOC="); config.dev_mode = 1; config.program_name = L"./_testembed"; _PyInitError err = _Py_InitializeFromConfig(&config); if (_Py_INIT_FAILED(err)) { _Py_FatalInitError(err); } dump_config(); Py_Finalize(); return 0; }
static _PyInitError core_config_init_module_search_paths(_PyCoreConfig *config, _PyPathConfig *path_config) { assert(config->module_search_paths == NULL); assert(config->nmodule_search_path < 0); config->nmodule_search_path = 0; const wchar_t *sys_path = path_config->module_search_path; const wchar_t delim = DELIM; const wchar_t *p = sys_path; while (1) { p = wcschr(sys_path, delim); if (p == NULL) { p = sys_path + wcslen(sys_path); /* End of string */ } size_t path_len = (p - sys_path); wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t)); if (path == NULL) { return _Py_INIT_NO_MEMORY(); } memcpy(path, sys_path, path_len * sizeof(wchar_t)); path[path_len] = L'\0'; _PyInitError err = _Py_wstrlist_append(&config->nmodule_search_path, &config->module_search_paths, path); PyMem_RawFree(path); if (_Py_INIT_FAILED(err)) { return err; } if (*p == '\0') { break; } sys_path = p + 1; } return _Py_INIT_OK(); }
/* Calculate the path configuration: initialize path_config from core_config */ static _PyInitError _PyPathConfig_Calculate(_PyPathConfig *path_config, const _PyCoreConfig *core_config) { _PyInitError err; _PyPathConfig new_config = _PyPathConfig_INIT; PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); /* Calculate program_full_path, prefix, exec_prefix (Unix) or dll_path (Windows), and module_search_path */ err = _PyPathConfig_Calculate_impl(&new_config, core_config); if (_Py_INIT_FAILED(err)) { goto err; } /* Copy home and program_name from core_config */ if (copy_wstr(&new_config.home, core_config->home) < 0) { err = _Py_INIT_NO_MEMORY(); goto err; } if (copy_wstr(&new_config.program_name, core_config->program_name) < 0) { err = _Py_INIT_NO_MEMORY(); goto err; } _PyPathConfig_Clear(path_config); *path_config = new_config; err = _Py_INIT_OK(); goto done; err: _PyPathConfig_Clear(&new_config); done: PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); return err; }
static int test_init_isolated(void) { /* Test _PyCoreConfig.isolated=1 */ _PyCoreConfig config = _PyCoreConfig_INIT; /* Set coerce_c_locale and utf8_mode to not depend on the locale */ config.coerce_c_locale = 0; config.utf8_mode = 0; /* Use path starting with "./" avoids a search along the PATH */ config.program_name = L"./_testembed"; Py_IsolatedFlag = 0; config.isolated = 1; test_init_env_putenvs(); _PyInitError err = _Py_InitializeFromConfig(&config); if (_Py_INIT_FAILED(err)) { _Py_FatalInitError(err); } dump_config(); Py_Finalize(); return 0; }
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); } const char *p; int i, n, sts = 1; int inspect = 0; int unbuffered = 0; char *oldloc = NULL; wchar_t **argv_copy = NULL; /* We need a second copies, as Python might modify the first one. */ wchar_t **argv_copy2 = NULL; if (argc > 0) { argv_copy = PyMem_RawMalloc(sizeof(wchar_t*) * argc); argv_copy2 = PyMem_RawMalloc(sizeof(wchar_t*) * argc); if (!argv_copy || !argv_copy2) { fprintf(stderr, "out of memory\n"); goto error; } } _PyCoreConfig config = _PyCoreConfig_INIT; config._frozen = 1; /* Suppress errors from getpath.c */ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') inspect = 1; if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; if (unbuffered) { setbuf(stdin, (char *)NULL); setbuf(stdout, (char *)NULL); setbuf(stderr, (char *)NULL); } oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); if (!oldloc) { fprintf(stderr, "out of memory\n"); goto error; } setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { argv_copy[i] = Py_DecodeLocale(argv[i], NULL); argv_copy2[i] = argv_copy[i]; if (!argv_copy[i]) { fprintf(stderr, "Unable to decode the command line argument #%i\n", i + 1); argc = i; goto error; } } setlocale(LC_ALL, oldloc); PyMem_RawFree(oldloc); oldloc = NULL; #ifdef MS_WINDOWS PyInitFrozenExtensions(); #endif /* MS_WINDOWS */ if (argc >= 1) Py_SetProgramName(argv_copy[0]); err = _Py_InitializeFromConfig(&config); /* No need to call _PyCoreConfig_Clear() since we didn't allocate any memory: program_name is a constant string. */ if (_Py_INIT_FAILED(err)) { _Py_FatalInitError(err); } #ifdef MS_WINDOWS PyWinFreeze_ExeInit(); #endif if (Py_VerboseFlag) fprintf(stderr, "Python %s\n%s\n", Py_GetVersion(), Py_GetCopyright()); PySys_SetArgv(argc, argv_copy); n = PyImport_ImportFrozenModule("__main__"); if (n == 0) Py_FatalError("__main__ not frozen"); if (n < 0) { PyErr_Print(); sts = 1; } else sts = 0; if (inspect && isatty((int)fileno(stdin))) sts = PyRun_AnyFile(stdin, "<stdin>") != 0; #ifdef MS_WINDOWS PyWinFreeze_ExeTerm(); #endif if (Py_FinalizeEx() < 0) { sts = 120; } error: PyMem_RawFree(argv_copy); if (argv_copy2) { for (i = 0; i < argc; i++) PyMem_RawFree(argv_copy2[i]); PyMem_RawFree(argv_copy2); } PyMem_RawFree(oldloc); return sts; }
_PyInitError _PyCoreConfig_InitPathConfig(_PyCoreConfig *config) { _PyPathConfig path_config = _PyPathConfig_INIT; _PyInitError err; err = _PyPathConfig_Calculate(&path_config, config); if (_Py_INIT_FAILED(err)) { goto error; } if (config->nmodule_search_path < 0) { err = core_config_init_module_search_paths(config, &path_config); if (_Py_INIT_FAILED(err)) { goto error; } } if (config->executable == NULL) { if (copy_wstr(&config->executable, path_config.program_full_path) < 0) { goto no_memory; } } if (config->prefix == NULL) { if (copy_wstr(&config->prefix, path_config.prefix) < 0) { goto no_memory; } } if (config->exec_prefix == NULL) { #ifdef MS_WINDOWS wchar_t *exec_prefix = path_config.prefix; #else wchar_t *exec_prefix = path_config.exec_prefix; #endif if (copy_wstr(&config->exec_prefix, exec_prefix) < 0) { goto no_memory; } } #ifdef MS_WINDOWS if (config->dll_path == NULL) { if (copy_wstr(&config->dll_path, path_config.dll_path) < 0) { goto no_memory; } } #endif if (config->base_prefix == NULL) { if (copy_wstr(&config->base_prefix, config->prefix) < 0) { goto no_memory; } } if (config->base_exec_prefix == NULL) { if (copy_wstr(&config->base_exec_prefix, config->exec_prefix) < 0) { goto no_memory; } } if (path_config.isolated != -1) { config->isolated = path_config.isolated; } if (path_config.site_import != -1) { config->site_import = path_config.site_import; } _PyPathConfig_Clear(&path_config); return _Py_INIT_OK(); no_memory: err = _Py_INIT_NO_MEMORY(); error: _PyPathConfig_Clear(&path_config); return err; }
static int test_init_from_config(void) { /* Test _Py_InitializeFromConfig() */ _PyCoreConfig config = _PyCoreConfig_INIT; config.install_signal_handlers = 0; /* FIXME: test use_environment */ putenv("PYTHONHASHSEED=42"); config.use_hash_seed = 1; config.hash_seed = 123; putenv("PYTHONMALLOC=malloc"); config.allocator = "malloc_debug"; /* dev_mode=1 is tested in test_init_dev_mode() */ putenv("PYTHONFAULTHANDLER="); config.faulthandler = 1; putenv("PYTHONTRACEMALLOC=0"); config.tracemalloc = 2; putenv("PYTHONPROFILEIMPORTTIME=0"); config.import_time = 1; config.show_ref_count = 1; config.show_alloc_count = 1; /* FIXME: test dump_refs: bpo-34223 */ putenv("PYTHONMALLOCSTATS=0"); config.malloc_stats = 1; /* FIXME: test coerce_c_locale and coerce_c_locale_warn */ putenv("PYTHONUTF8=0"); Py_UTF8Mode = 0; config.utf8_mode = 1; putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix"); config.pycache_prefix = L"conf_pycache_prefix"; Py_SetProgramName(L"./globalvar"); config.program_name = L"./conf_program_name"; static wchar_t* argv[2] = { L"-c", L"pass", }; config.argc = Py_ARRAY_LENGTH(argv); config.argv = argv; config.program = L"conf_program"; static wchar_t* xoptions[3] = { L"core_xoption1=3", L"core_xoption2=", L"core_xoption3", }; config.nxoption = Py_ARRAY_LENGTH(xoptions); config.xoptions = xoptions; static wchar_t* warnoptions[2] = { L"default", L"error::ResourceWarning", }; config.nwarnoption = Py_ARRAY_LENGTH(warnoptions); config.warnoptions = warnoptions; /* FIXME: test module_search_path_env */ /* FIXME: test home */ /* FIXME: test path config: module_search_path .. dll_path */ putenv("PYTHONVERBOSE=0"); Py_VerboseFlag = 0; config.verbose = 1; Py_NoSiteFlag = 0; config.site_import = 0; Py_BytesWarningFlag = 0; config.bytes_warning = 1; putenv("PYTHONINSPECT="); Py_InspectFlag = 0; config.inspect = 1; Py_InteractiveFlag = 0; config.interactive = 1; putenv("PYTHONOPTIMIZE=0"); Py_OptimizeFlag = 1; config.optimization_level = 2; /* FIXME: test parser_debug */ putenv("PYTHONDONTWRITEBYTECODE="); Py_DontWriteBytecodeFlag = 0; config.write_bytecode = 0; Py_QuietFlag = 0; config.quiet = 1; putenv("PYTHONUNBUFFERED="); Py_UnbufferedStdioFlag = 0; config.buffered_stdio = 0; putenv("PYTHONIOENCODING=cp424"); Py_SetStandardStreamEncoding("ascii", "ignore"); #ifdef MS_WINDOWS /* Py_SetStandardStreamEncoding() sets Py_LegacyWindowsStdioFlag to 1. Force it to 0 through the config. */ config.legacy_windows_stdio = 0; #endif config.stdio_encoding = "iso8859-1"; config.stdio_errors = "replace"; putenv("PYTHONNOUSERSITE="); Py_NoUserSiteDirectory = 0; config.user_site_directory = 0; config._check_hash_pycs_mode = "always"; Py_FrozenFlag = 0; config._frozen = 1; _PyInitError err = _Py_InitializeFromConfig(&config); /* Don't call _PyCoreConfig_Clear() since all strings are static */ if (_Py_INIT_FAILED(err)) { _Py_FatalInitError(err); } dump_config(); Py_Finalize(); return 0; }