[Python-checkins] bpo-38234: Py_SetPath() uses the program full path (GH-16357)
Victor Stinner
webhook-mailer at python.org
Tue Sep 24 11:44:31 EDT 2019
https://github.com/python/cpython/commit/1ce152a42eaa917d7763bce93f1e1ca72530d7ca
commit: 1ce152a42eaa917d7763bce93f1e1ca72530d7ca
branch: master
author: Victor Stinner <vstinner at redhat.com>
committer: GitHub <noreply at github.com>
date: 2019-09-24T17:44:15+02:00
summary:
bpo-38234: Py_SetPath() uses the program full path (GH-16357)
Py_SetPath() now sets sys.executable to the program full path
(Py_GetProgramFullPath()), rather than to the program name
(Py_GetProgramName()).
Fix also memory leaks in pathconfig_set_from_config().
files:
A Misc/NEWS.d/next/C API/2019-09-24-17-09-48.bpo-38234.d0bhEA.rst
M Doc/c-api/init.rst
M Doc/whatsnew/3.8.rst
M Python/pathconfig.c
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index 0f8ff3b0dde8..0b7a84d03153 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -472,8 +472,8 @@ Process-wide parameters
dependent delimiter character, which is ``':'`` on Unix and Mac OS X, ``';'``
on Windows.
- This also causes :data:`sys.executable` to be set only to the raw program
- name (see :c:func:`Py_SetProgramName`) and for :data:`sys.prefix` and
+ This also causes :data:`sys.executable` to be set to the program
+ full path (see :c:func:`Py_GetProgramFullPath`) and for :data:`sys.prefix` and
:data:`sys.exec_prefix` to be empty. It is up to the caller to modify these
if required after calling :c:func:`Py_Initialize`.
@@ -483,6 +483,10 @@ Process-wide parameters
The path argument is copied internally, so the caller may free it after the
call completes.
+ .. versionchanged:: 3.8
+ The program full path is now used for :data:`sys.executable`, instead
+ of the program name.
+
.. c:function:: const char* Py_GetVersion()
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index c2455f487b14..0995cb3b9119 100755
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -1347,6 +1347,11 @@ Build and C API Changes
parameter for indicating the number of positional-only arguments.
(Contributed by Pablo Galindo in :issue:`37221`.)
+* :c:func:`Py_SetPath` now sets :data:`sys.executable` to the program full
+ path (:c:func:`Py_GetProgramFullPath`) rather than to the program name
+ (:c:func:`Py_GetProgramName`).
+ (Contributed by Victor Stinner in :issue:`38234`.)
+
Deprecated
==========
diff --git a/Misc/NEWS.d/next/C API/2019-09-24-17-09-48.bpo-38234.d0bhEA.rst b/Misc/NEWS.d/next/C API/2019-09-24-17-09-48.bpo-38234.d0bhEA.rst
new file mode 100644
index 000000000000..ba4cc312e692
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2019-09-24-17-09-48.bpo-38234.d0bhEA.rst
@@ -0,0 +1,3 @@
+:c:func:`Py_SetPath` now sets :data:`sys.executable` to the program full
+path (:c:func:`Py_GetProgramFullPath`) rather than to the program name
+(:c:func:`Py_GetProgramName`).
diff --git a/Python/pathconfig.c b/Python/pathconfig.c
index 7677a155797e..8f76fa50c971 100644
--- a/Python/pathconfig.c
+++ b/Python/pathconfig.c
@@ -23,6 +23,7 @@ wchar_t *_Py_dll_path = NULL;
static int
copy_wstr(wchar_t **dst, const wchar_t *src)
{
+ assert(*dst == NULL);
if (src != NULL) {
*dst = _PyMem_RawWcsdup(src);
if (*dst == NULL) {
@@ -172,6 +173,7 @@ pathconfig_set_from_config(_PyPathConfig *pathconfig, const PyConfig *config)
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
if (config->module_search_paths_set) {
+ PyMem_RawFree(pathconfig->module_search_path);
pathconfig->module_search_path = _PyWideStringList_Join(&config->module_search_paths, DELIM);
if (pathconfig->module_search_path == NULL) {
goto no_memory;
@@ -180,6 +182,8 @@ pathconfig_set_from_config(_PyPathConfig *pathconfig, const PyConfig *config)
#define COPY_CONFIG(PATH_ATTR, CONFIG_ATTR) \
if (config->CONFIG_ATTR) { \
+ PyMem_RawFree(pathconfig->PATH_ATTR); \
+ pathconfig->PATH_ATTR = NULL; \
if (copy_wstr(&pathconfig->PATH_ATTR, config->CONFIG_ATTR) < 0) { \
goto no_memory; \
} \
@@ -455,16 +459,15 @@ Py_SetPath(const wchar_t *path)
PyMemAllocatorEx old_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
- /* Getting the program name calls pathconfig_global_init() */
- wchar_t *program_name = _PyMem_RawWcsdup(Py_GetProgramName());
+ /* Getting the program full path calls pathconfig_global_init() */
+ wchar_t *program_full_path = _PyMem_RawWcsdup(Py_GetProgramFullPath());
PyMem_RawFree(_Py_path_config.program_full_path);
PyMem_RawFree(_Py_path_config.prefix);
PyMem_RawFree(_Py_path_config.exec_prefix);
PyMem_RawFree(_Py_path_config.module_search_path);
- /* Copy program_name to program_full_path */
- _Py_path_config.program_full_path = program_name;
+ _Py_path_config.program_full_path = program_full_path;
_Py_path_config.prefix = _PyMem_RawWcsdup(L"");
_Py_path_config.exec_prefix = _PyMem_RawWcsdup(L"");
_Py_path_config.module_search_path = _PyMem_RawWcsdup(path);
More information about the Python-checkins
mailing list