mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
gh-83180: Made launcher treat shebang 'python' tags as low priority so that active virtual environments are preferred (GH-108101)
This commit is contained in:
parent
6139bf5e0c
commit
1b3bc610fd
4 changed files with 71 additions and 12 deletions
|
|
@ -195,6 +195,13 @@ join(wchar_t *buffer, size_t bufferLength, const wchar_t *fragment)
|
|||
}
|
||||
|
||||
|
||||
bool
|
||||
split_parent(wchar_t *buffer, size_t bufferLength)
|
||||
{
|
||||
return SUCCEEDED(PathCchRemoveFileSpec(buffer, bufferLength));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_compare(const wchar_t *x, int xLen, const wchar_t *y, int yLen)
|
||||
{
|
||||
|
|
@ -414,8 +421,8 @@ typedef struct {
|
|||
// if true, treats 'tag' as a non-PEP 514 filter
|
||||
bool oldStyleTag;
|
||||
// if true, ignores 'tag' when a high priority environment is found
|
||||
// gh-92817: This is currently set when a tag is read from configuration or
|
||||
// the environment, rather than the command line or a shebang line, and the
|
||||
// gh-92817: This is currently set when a tag is read from configuration,
|
||||
// the environment, or a shebang, rather than the command line, and the
|
||||
// only currently possible high priority environment is an active virtual
|
||||
// environment
|
||||
bool lowPriorityTag;
|
||||
|
|
@ -794,6 +801,8 @@ searchPath(SearchInfo *search, const wchar_t *shebang, int shebangLength)
|
|||
}
|
||||
}
|
||||
|
||||
debug(L"# Search PATH for %s\n", filename);
|
||||
|
||||
wchar_t pathVariable[MAXLEN];
|
||||
int n = GetEnvironmentVariableW(L"PATH", pathVariable, MAXLEN);
|
||||
if (!n) {
|
||||
|
|
@ -1031,8 +1040,11 @@ checkShebang(SearchInfo *search)
|
|||
debug(L"Shebang: %s\n", shebang);
|
||||
|
||||
// Handle shebangs that we should search PATH for
|
||||
int executablePathWasSetByUsrBinEnv = 0;
|
||||
exitCode = searchPath(search, shebang, shebangLength);
|
||||
if (exitCode != RC_NO_SHEBANG) {
|
||||
if (exitCode == 0) {
|
||||
executablePathWasSetByUsrBinEnv = 1;
|
||||
} else if (exitCode != RC_NO_SHEBANG) {
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
|
|
@ -1067,7 +1079,7 @@ checkShebang(SearchInfo *search)
|
|||
search->tagLength = commandLength;
|
||||
// If we had 'python3.12.exe' then we want to strip the suffix
|
||||
// off of the tag
|
||||
if (search->tagLength > 4) {
|
||||
if (search->tagLength >= 4) {
|
||||
const wchar_t *suffix = &search->tag[search->tagLength - 4];
|
||||
if (0 == _comparePath(suffix, 4, L".exe", -1)) {
|
||||
search->tagLength -= 4;
|
||||
|
|
@ -1075,13 +1087,14 @@ checkShebang(SearchInfo *search)
|
|||
}
|
||||
// If we had 'python3_d' then we want to strip the '_d' (any
|
||||
// '.exe' is already gone)
|
||||
if (search->tagLength > 2) {
|
||||
if (search->tagLength >= 2) {
|
||||
const wchar_t *suffix = &search->tag[search->tagLength - 2];
|
||||
if (0 == _comparePath(suffix, 2, L"_d", -1)) {
|
||||
search->tagLength -= 2;
|
||||
}
|
||||
}
|
||||
search->oldStyleTag = true;
|
||||
search->lowPriorityTag = true;
|
||||
search->executableArgs = &command[commandLength];
|
||||
search->executableArgsLength = shebangLength - commandLength;
|
||||
if (search->tag && search->tagLength) {
|
||||
|
|
@ -1095,6 +1108,11 @@ checkShebang(SearchInfo *search)
|
|||
}
|
||||
}
|
||||
|
||||
// Didn't match a template, but we found it on PATH
|
||||
if (executablePathWasSetByUsrBinEnv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Unrecognised executables are first tried as command aliases
|
||||
commandLength = 0;
|
||||
while (commandLength < shebangLength && !isspace(shebang[commandLength])) {
|
||||
|
|
@ -1765,7 +1783,15 @@ virtualenvSearch(const SearchInfo *search, EnvironmentInfo **result)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(buffer)) {
|
||||
DWORD attr = GetFileAttributesW(buffer);
|
||||
if (INVALID_FILE_ATTRIBUTES == attr && search->lowPriorityTag) {
|
||||
if (!split_parent(buffer, MAXLEN) || !join(buffer, MAXLEN, L"python.exe")) {
|
||||
return 0;
|
||||
}
|
||||
attr = GetFileAttributesW(buffer);
|
||||
}
|
||||
|
||||
if (INVALID_FILE_ATTRIBUTES == attr) {
|
||||
debug(L"Python executable %s missing from virtual env\n", buffer);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue