summaryrefslogtreecommitdiffstats
path: root/Lib/shutil.py
diff options
context:
space:
mode:
authorCharles Machalow <csm10495@gmail.com>2023-10-02 08:27:30 (GMT)
committerGitHub <noreply@github.com>2023-10-02 08:27:30 (GMT)
commit29b875bb93099171aeb7a60cd18d4e1f4ea3c1db (patch)
tree4125892f44bd5a1a0a6dd733909ffcfcb9ec284a /Lib/shutil.py
parent29c3a445d99f7e29086f6fdc4612e200cbbdc0ff (diff)
downloadcpython-29b875bb93099171aeb7a60cd18d4e1f4ea3c1db.zip
cpython-29b875bb93099171aeb7a60cd18d4e1f4ea3c1db.tar.gz
cpython-29b875bb93099171aeb7a60cd18d4e1f4ea3c1db.tar.bz2
gh-109590: Update shutil.which on Windows to prefer a PATHEXT extension on executable files (GH-109995)
The default arguments for shutil.which() request an executable file, but extensionless files are not executable on Windows and should be ignored.
Diffstat (limited to 'Lib/shutil.py')
-rw-r--r--Lib/shutil.py12
1 files changed, 10 insertions, 2 deletions
diff --git a/Lib/shutil.py b/Lib/shutil.py
index b903f13..a278b74 100644
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -1554,8 +1554,16 @@ def which(cmd, mode=os.F_OK | os.X_OK, path=None):
if use_bytes:
pathext = [os.fsencode(ext) for ext in pathext]
- # Always try checking the originally given cmd, if it doesn't match, try pathext
- files = [cmd] + [cmd + ext for ext in pathext]
+ files = ([cmd] + [cmd + ext for ext in pathext])
+
+ # gh-109590. If we are looking for an executable, we need to look
+ # for a PATHEXT match. The first cmd is the direct match
+ # (e.g. python.exe instead of python)
+ # Check that direct match first if and only if the extension is in PATHEXT
+ # Otherwise check it last
+ suffix = os.path.splitext(files[0])[1].upper()
+ if mode & os.X_OK and not any(suffix == ext.upper() for ext in pathext):
+ files.append(files.pop(0))
else:
# On other platforms you don't have things like PATHEXT to tell you
# what file suffixes are executable, so just pass on cmd as-is.