New submission from Christian Ullrich: I'm trying to do something that may be slightly tricky, and I think I just found a vintage 1997 bug. Please correct me if I'm wrong.
This is PC/getpathp.c from current master: 430: static void 431: get_progpath(void) 432: { 433: extern wchar_t *Py_GetProgramName(void); 434: wchar_t *path = _wgetenv(L"PATH"); 435: wchar_t *prog = Py_GetProgramName(); 436: 437: #ifdef Py_ENABLE_SHARED 438: extern HANDLE PyWin_DLLhModule; 439: /* static init of progpath ensures final char remains \0 */ 440: if (PyWin_DLLhModule) 441: if (!GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN)) 442: dllpath[0] = 0; 443: #else 444: dllpath[0] = 0; 445: #endif 446: if (GetModuleFileNameW(NULL, progpath, MAXPATHLEN)) 447: return; 448: if (prog == NULL || *prog == '\0') 449: prog = L"python"; Lines 446-447 have been like this ever since Guido wrote them twenty years ago. I think the logic is the wrong way around. As it is now, the function always returns on line 447 because GetModuleFileNameW() *always* succeeds (returns nonzero). Hence, everything below line 447 is dead code. GetModuleFileNameW(NULL, ...) fills the buffer with the path to the executable the current process was created from. It returns the number of characters put into the buffer, or zero on error. However, the only way *this* call could fail is if the code was being executed outside of any process, something that clearly cannot happen. Prior to August 1997, the relevant bit of code looked like this: 156: if (!GetModuleFileName(NULL, progpath, MAXPATHLEN)) 157: progpath[0] = '\0'; /* failure */ This bug, if it is one, would only manifest when initializing an embedded interpreter using a different argv[0] than that of the actual host process, because if the host process is a python.exe, it very likely runs inside a standard installation or venv anyway. What I am trying is to make an interpreter running in a third-party host process take site-packages from a venv. Doing this (argv[0] different from actual host process) may not be entirely proper itself, but then again, why would Py_SetProgramName() even exist otherwise? Suggested fix: diff --git a/PC/getpathp.c b/PC/getpathp.c index 8380e1bcfa..abb5e54c9f 100644 --- a/PC/getpathp.c +++ b/PC/getpathp.c @@ -443,8 +443,7 @@ get_progpath(void) #else dllpath[0] = 0; #endif - if (!GetModuleFileNameW(NULL, progpath, MAXPATHLEN)) - return; + GetModuleFileNameW(NULL, progpath, MAXPATHLEN); if (prog == NULL || *prog == '\0') prog = L"python"; Since the call to GetModuleFileNameW() cannot possibly fail, there is no real point in checking its return value. ---------- components: Windows messages: 301306 nosy: Christian.Ullrich, paul.moore, steve.dower, tim.golden, zach.ware priority: normal severity: normal status: open title: Embedded initialization ignores Py_SetProgramName() type: behavior versions: Python 3.6, Python 3.7 _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue31349> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com