PyConfig *config,
const PyConfig *config2);
extern PyStatus _PyConfig_InitPathConfig(PyConfig *config);
-extern PyStatus _PyConfig_SetPathConfig(
- const PyConfig *config);
extern void _PyConfig_Write(const PyConfig *config,
_PyRuntimeState *runtime);
extern PyStatus _PyConfig_SetPyArgv(
wchar_t *program_full_path;
wchar_t *prefix;
wchar_t *exec_prefix;
-#ifdef MS_WINDOWS
- wchar_t *dll_path;
-#endif
- /* Set by Py_SetPath(), or computed by _PyPathConfig_Init() */
+ /* Set by Py_SetPath(), or computed by _PyConfig_InitPathConfig() */
wchar_t *module_search_path;
/* Python program name */
wchar_t *program_name;
/* Note: _PyPathConfig_INIT sets other fields to 0/NULL */
PyAPI_DATA(_PyPathConfig) _Py_path_config;
+#ifdef MS_WINDOWS
+PyAPI_DATA(wchar_t*) _Py_dll_path;
+#endif
extern void _PyPathConfig_ClearGlobal(void);
extern PyStatus _PyPathConfig_SetGlobal(
extern wchar_t* _Py_GetDLLPath(void);
#endif
+extern PyStatus _PyPathConfig_Init(void);
+
#ifdef __cplusplus
}
#endif
--- /dev/null
+Python ignored path passed to :c:func:`Py_SetPath`, fix Python
+initialization to use the specified path.
"Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
}
- status = calculate_module_search_path(config, calculate,
- prefix, exec_prefix, pathconfig);
- if (_PyStatus_EXCEPTION(status)) {
- return status;
+ if (pathconfig->module_search_path == NULL) {
+ status = calculate_module_search_path(config, calculate,
+ prefix, exec_prefix, pathconfig);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
}
status = calculate_reduce_prefix(calculate, prefix, Py_ARRAY_LENGTH(prefix));
wchar_t argv0_path[MAXPATHLEN+1];
wchar_t zip_path[MAXPATHLEN+1];
+
+ wchar_t *dll_path;
} PyCalculatePath;
}
-static void
+static PyStatus
calculate_init(PyCalculatePath *calculate,
const PyConfig *config)
{
calculate->home = config->home;
calculate->path_env = _wgetenv(L"PATH");
+
+ calculate->dll_path = _Py_GetDLLPath();
+ if (calculate->dll_path == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+
+ return _PyStatus_OK();
}
static int
-get_pth_filename(wchar_t *spbuffer, _PyPathConfig *pathconfig)
+get_pth_filename(PyCalculatePath *calculate, wchar_t *filename,
+ const _PyPathConfig *pathconfig)
{
- if (pathconfig->dll_path[0]) {
- if (!change_ext(spbuffer, pathconfig->dll_path, L"._pth") &&
- exists(spbuffer))
+ if (calculate->dll_path[0]) {
+ if (!change_ext(filename, calculate->dll_path, L"._pth") &&
+ exists(filename))
{
return 1;
}
}
if (pathconfig->program_full_path[0]) {
- if (!change_ext(spbuffer, pathconfig->program_full_path, L"._pth") &&
- exists(spbuffer))
+ if (!change_ext(filename, pathconfig->program_full_path, L"._pth") &&
+ exists(filename))
{
return 1;
}
static int
-calculate_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix)
+calculate_pth_file(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
+ wchar_t *prefix)
{
- wchar_t spbuffer[MAXPATHLEN+1];
+ wchar_t filename[MAXPATHLEN+1];
- if (!get_pth_filename(spbuffer, pathconfig)) {
+ if (!get_pth_filename(calculate, filename, pathconfig)) {
return 0;
}
- return read_pth_file(pathconfig, prefix, spbuffer);
+ return read_pth_file(pathconfig, prefix, filename);
}
{
PyStatus status;
- assert(pathconfig->dll_path == NULL);
-
- pathconfig->dll_path = _Py_GetDLLPath();
- if (pathconfig->dll_path == NULL) {
- return _PyStatus_NO_MEMORY();
- }
-
status = get_program_full_path(config, calculate, pathconfig);
if (_PyStatus_EXCEPTION(status)) {
return status;
memset(prefix, 0, sizeof(prefix));
/* Search for a sys.path file */
- if (calculate_pth_file(pathconfig, prefix)) {
+ if (calculate_pth_file(calculate, pathconfig, prefix)) {
goto done;
}
/* Calculate zip archive path from DLL or exe path */
change_ext(calculate->zip_path,
- pathconfig->dll_path[0] ? pathconfig->dll_path : pathconfig->program_full_path,
+ calculate->dll_path[0] ? calculate->dll_path : pathconfig->program_full_path,
L".zip");
calculate_home_prefix(calculate, prefix);
- status = calculate_module_search_path(config, calculate, pathconfig, prefix);
- if (_PyStatus_EXCEPTION(status)) {
- return status;
+ if (pathconfig->module_search_path == NULL) {
+ status = calculate_module_search_path(config, calculate,
+ pathconfig, prefix);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
}
done:
{
PyMem_RawFree(calculate->machine_path);
PyMem_RawFree(calculate->user_path);
+ PyMem_RawFree(calculate->dll_path);
}
PyStatus
_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config)
{
+ PyStatus status;
PyCalculatePath calculate;
memset(&calculate, 0, sizeof(calculate));
- calculate_init(&calculate, config);
-
- PyStatus status = calculate_path_impl(config, &calculate, pathconfig);
+ status = calculate_init(&calculate, config);
if (_PyStatus_EXCEPTION(status)) {
goto done;
}
- status = _PyStatus_OK();
+ status = calculate_path_impl(config, &calculate, pathconfig);
done:
calculate_free(&calculate);
/* If there is a python3.dll next to the python3y.dll,
assume this is a build tree; use that DLL */
- wcscpy(py3path, _Py_path_config.dll_path);
+ if (_Py_dll_path != NULL) {
+ wcscpy(py3path, _Py_dll_path);
+ }
+ else {
+ wcscpy(py3path, L"");
+ }
s = wcsrchr(py3path, L'\\');
if (!s) {
s = py3path;
_PyPathConfig _Py_path_config = _PyPathConfig_INIT;
+#ifdef MS_WINDOWS
+wchar_t *_Py_dll_path = NULL;
+#endif
static int
CLEAR(config->prefix);
CLEAR(config->program_full_path);
CLEAR(config->exec_prefix);
-#ifdef MS_WINDOWS
- CLEAR(config->dll_path);
-#endif
CLEAR(config->module_search_path);
CLEAR(config->home);
CLEAR(config->program_name);
PyMemAllocatorEx old_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+ if (copy_wstr(&new_config.module_search_path,
+ _Py_path_config.module_search_path) < 0)
+ {
+ status = _PyStatus_NO_MEMORY();
+ goto error;
+ }
+
/* Calculate program_full_path, prefix, exec_prefix,
dll_path (Windows), and module_search_path */
status = _PyPathConfig_Calculate(&new_config, config);
}
-PyStatus
-_PyPathConfig_SetGlobal(const _PyPathConfig *config)
-{
- PyStatus status;
- _PyPathConfig new_config = _PyPathConfig_INIT;
-
- PyMemAllocatorEx old_alloc;
- _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
-
-#define COPY_ATTR(ATTR) \
- do { \
- if (copy_wstr(&new_config.ATTR, config->ATTR) < 0) { \
- pathconfig_clear(&new_config); \
- status = _PyStatus_NO_MEMORY(); \
- goto done; \
- } \
- } while (0)
-
- COPY_ATTR(program_full_path);
- COPY_ATTR(prefix);
- COPY_ATTR(exec_prefix);
-#ifdef MS_WINDOWS
- COPY_ATTR(dll_path);
-#endif
- COPY_ATTR(module_search_path);
- COPY_ATTR(program_name);
- COPY_ATTR(home);
- COPY_ATTR(base_executable);
-
- pathconfig_clear(&_Py_path_config);
- /* Steal new_config strings; don't clear new_config */
- _Py_path_config = new_config;
-
- status = _PyStatus_OK();
-
-done:
- PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
- return status;
-}
-
-
void
_PyPathConfig_ClearGlobal(void)
{
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
pathconfig_clear(&_Py_path_config);
+#ifdef MS_WINDOWS
+ PyMem_RawFree(_Py_dll_path);
+ _Py_dll_path = NULL;
+#endif
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
}
/* Set the global path configuration from config. */
PyStatus
-_PyConfig_SetPathConfig(const PyConfig *config)
+_PyPathConfig_Init(void)
{
+#ifdef MS_WINDOWS
+ if (_Py_dll_path == NULL) {
+ /* Already set: nothing to do */
+ return _PyStatus_OK();
+ }
+
PyMemAllocatorEx old_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+ _Py_dll_path = _Py_GetDLLPath();
+
+ PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
+ if (_Py_dll_path == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+#endif
+ return _PyStatus_OK();
+}
+
+
+static PyStatus
+pathconfig_global_init_from_config(const PyConfig *config)
+{
PyStatus status;
+ PyMemAllocatorEx old_alloc;
+ _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
+
_PyPathConfig pathconfig = _PyPathConfig_INIT;
pathconfig.module_search_path = _PyWideStringList_Join(&config->module_search_paths, DELIM);
if (copy_wstr(&pathconfig.exec_prefix, config->exec_prefix) < 0) {
goto no_memory;
}
-#ifdef MS_WINDOWS
- pathconfig.dll_path = _Py_GetDLLPath();
- if (pathconfig.dll_path == NULL) {
- goto no_memory;
- }
-#endif
if (copy_wstr(&pathconfig.program_name, config->program_name) < 0) {
goto no_memory;
}
goto no_memory;
}
- status = _PyPathConfig_SetGlobal(&pathconfig);
- if (_PyStatus_EXCEPTION(status)) {
- goto done;
- }
+ pathconfig_clear(&_Py_path_config);
+ /* Steal new_config strings; don't clear new_config */
+ _Py_path_config = pathconfig;
status = _PyStatus_OK();
goto done;
no_memory:
+ pathconfig_clear(&pathconfig);
status = _PyStatus_NO_MEMORY();
done:
- pathconfig_clear(&pathconfig);
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
return status;
}
static void
pathconfig_global_init(void)
{
+ /* Initialize _Py_dll_path if needed */
+ PyStatus status = _PyPathConfig_Init();
+ if (_PyStatus_EXCEPTION(status)) {
+ Py_ExitStatusException(status);
+ }
+
if (_Py_path_config.module_search_path != NULL) {
/* Already initialized */
return;
}
- PyStatus status;
PyConfig config;
_PyConfig_InitCompatConfig(&config);
goto error;
}
- status = _PyConfig_SetPathConfig(&config);
+ status = pathconfig_global_init_from_config(&config);
if (_PyStatus_EXCEPTION(status)) {
goto error;
}
alloc_error |= (new_config.prefix == NULL);
new_config.exec_prefix = _PyMem_RawWcsdup(L"");
alloc_error |= (new_config.exec_prefix == NULL);
-#ifdef MS_WINDOWS
- new_config.dll_path = _Py_GetDLLPath();
- alloc_error |= (new_config.dll_path == NULL);
-#endif
new_config.module_search_path = _PyMem_RawWcsdup(path);
alloc_error |= (new_config.module_search_path == NULL);
config = &interp->config;
if (config->_install_importlib) {
- status = _PyConfig_SetPathConfig(config);
+ status = _PyPathConfig_Init();
if (_PyStatus_EXCEPTION(status)) {
return status;
}
static PyStatus
pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod)
{
+ const PyConfig *config = &interp->config;
+
PyStatus status = _PyImport_Init(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
return _PyStatus_ERR("can't initialize warnings");
}
- if (interp->config._install_importlib) {
- status = _PyConfig_SetPathConfig(&interp->config);
+ if (config->_install_importlib) {
+ status = _PyPathConfig_Init();
if (_PyStatus_EXCEPTION(status)) {
return status;
}
}
/* This call sets up builtin and frozen import support */
- if (interp->config._install_importlib) {
+ if (config->_install_importlib) {
status = init_importlib(interp, sysmod);
if (_PyStatus_EXCEPTION(status)) {
return status;