bpo-38234: Remove _PyPathConfig.dll_path (GH-16307)

The DLL path is not computed from any user configuration and cannot
be configured by PyConfig. Instead, add a new _Py_dll_path global variable.

Remove _PyConfig_SetPathConfig(): replaced with _PyPathConfig_Init().

Py_Initialize() now longer sets the "global path configuration",
but only initialize _Py_dll_path.
This commit is contained in:
Victor Stinner 2019-09-21 01:02:56 +02:00 committed by GitHub
parent b1542583be
commit c422167749
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 95 deletions

View File

@ -149,8 +149,6 @@ extern PyStatus _PyConfig_Copy(
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(

View File

@ -13,10 +13,7 @@ typedef struct _PyPathConfig {
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;
@ -38,6 +35,9 @@ typedef struct _PyPathConfig {
/* 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(
@ -59,6 +59,8 @@ extern int _Py_FindEnvConfigValue(
extern wchar_t* _Py_GetDLLPath(void);
#endif
extern PyStatus _PyPathConfig_Init(void);
#ifdef __cplusplus
}
#endif

View File

@ -128,6 +128,8 @@ typedef struct {
wchar_t argv0_path[MAXPATHLEN+1];
wchar_t zip_path[MAXPATHLEN+1];
wchar_t *dll_path;
} PyCalculatePath;
@ -666,28 +668,36 @@ error:
}
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;
}
@ -697,15 +707,16 @@ get_pth_filename(wchar_t *spbuffer, _PyPathConfig *pathconfig)
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);
}
@ -966,13 +977,6 @@ calculate_path_impl(const PyConfig *config,
{
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;
@ -986,7 +990,7 @@ calculate_path_impl(const PyConfig *config,
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;
}
@ -994,7 +998,7 @@ calculate_path_impl(const PyConfig *config,
/* 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);
@ -1023,23 +1027,23 @@ calculate_free(PyCalculatePath *calculate)
{
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);
@ -1067,7 +1071,12 @@ _Py_CheckPython3(void)
/* 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;

View File

@ -15,6 +15,9 @@ extern "C" {
_PyPathConfig _Py_path_config = _PyPathConfig_INIT;
#ifdef MS_WINDOWS
wchar_t *_Py_dll_path = NULL;
#endif
static int
@ -51,9 +54,6 @@ pathconfig_clear(_PyPathConfig *config)
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);
@ -114,47 +114,6 @@ done:
}
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)
{
@ -162,6 +121,10 @@ _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);
}
@ -200,12 +163,36 @@ _PyWideStringList_Join(const PyWideStringList *list, wchar_t sep)
/* 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);
@ -222,12 +209,6 @@ _PyConfig_SetPathConfig(const PyConfig *config)
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;
}
@ -238,19 +219,18 @@ _PyConfig_SetPathConfig(const PyConfig *config)
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;
}
@ -402,12 +382,17 @@ _PyConfig_InitPathConfig(PyConfig *config)
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);
@ -416,7 +401,7 @@ pathconfig_global_init(void)
goto error;
}
status = _PyConfig_SetPathConfig(&config);
status = pathconfig_global_init_from_config(&config);
if (_PyStatus_EXCEPTION(status)) {
goto error;
}
@ -450,10 +435,6 @@ Py_SetPath(const wchar_t *path)
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);

View File

@ -475,7 +475,7 @@ pyinit_core_reconfigure(_PyRuntimeState *runtime,
config = &interp->config;
if (config->_install_importlib) {
status = _PyConfig_SetPathConfig(config);
status = _PyPathConfig_Init();
if (_PyStatus_EXCEPTION(status)) {
return status;
}
@ -646,7 +646,7 @@ pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod)
}
if (config->_install_importlib) {
status = _PyConfig_SetPathConfig(config);
status = _PyPathConfig_Init();
if (_PyStatus_EXCEPTION(status)) {
return status;
}