-
-
Notifications
You must be signed in to change notification settings - Fork 30.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gh-127001: Fix PATHEXT issues in shutil.which() on Windows #127035
Conversation
…h() on Windows Name without a PATHEXT extension is only searched if the mode does not include X_OK.
Ah, nice. I approve of this logic. I have a vague feeling it was discussed at some point, but I think it makes sense to require an extension from |
I'll rewrite tests tomorrow. |
Some of existing tests did not make sense because they are grounded on wrong model. I replaced them. Also I refactored other tests to make them more uniform and reuse the same files and directories. Fixed also cases when PATHEXT contains a multicomponent extension (e.g. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One comment I'd like to see added, but otherwise looks good
Lib/shutil.py
Outdated
@@ -1550,21 +1550,21 @@ def which(cmd, mode=os.F_OK | os.X_OK, path=None): | |||
if sys.platform == "win32": | |||
# PATHEXT is necessary to check on Windows. | |||
pathext_source = os.getenv("PATHEXT") or _WIN_DEFAULT_PATHEXT | |||
pathext = [ext for ext in pathext_source.split(os.pathsep) if ext] | |||
pathext = pathext_source.split(os.pathsep) | |||
pathext = [ext.rstrip('.') and ext for ext in pathext if ext] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really dislike using and
for value selection. I trust that you've got it right here, but I can't read it easily. Can we maybe comment?
# Replace ext of '.' with empty string, but keep trailing dots on '.ext.'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I think that it is better to remove dots in all cases. The behavior of cmd.exe if PATHEXT
contains .BAT.
and there is a.bat
in the path:
a
-- hangsa.bat
-- founda.
-- not founda.bat.
-- not found
which()
will now return the same result, except for the first case. I think this is the best option for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me
Thanks @serhiy-storchaka for the PR 🌮🎉.. I'm working now to backport this PR to: 3.12, 3.13. |
…honGH-127035) * Name without a PATHEXT extension is only searched if the mode does not include X_OK. * Support multi-component PATHEXT extensions (e.g. ".foo.bar"). * Support files without extensions in PATHEXT contains dot-only extension (".", "..", etc). * Support PATHEXT extensions that end with a dot (e.g. ".foo."). (cherry picked from commit 8899e85) Co-authored-by: Serhiy Storchaka <[email protected]>
Sorry, @serhiy-storchaka, I could not cleanly backport this to
|
GH-127156 is a backport of this pull request to the 3.13 branch. |
…ws (pythonGH-127035) * Name without a PATHEXT extension is only searched if the mode does not include X_OK. * Support multi-component PATHEXT extensions (e.g. ".foo.bar"). * Support files without extensions in PATHEXT contains dot-only extension (".", "..", etc). * Support PATHEXT extensions that end with a dot (e.g. ".foo."). (cherry picked from commit 8899e85) Co-authored-by: Serhiy Storchaka <[email protected]>
GH-127158 is a backport of this pull request to the 3.12 branch. |
…-127035) (GH-127156) * Name without a PATHEXT extension is only searched if the mode does not include X_OK. * Support multi-component PATHEXT extensions (e.g. ".foo.bar"). * Support files without extensions in PATHEXT contains dot-only extension (".", "..", etc). * Support PATHEXT extensions that end with a dot (e.g. ".foo."). (cherry picked from commit 8899e85) Co-authored-by: Serhiy Storchaka <[email protected]>
…-127035) (GH-127158) * Name without a PATHEXT extension is only searched if the mode does not include X_OK. * Support multi-component PATHEXT extensions (e.g. ".foo.bar"). * Support files without extensions in PATHEXT contains dot-only extension (".", "..", etc). * Support PATHEXT extensions that end with a dot (e.g. ".foo."). (cherry picked from commit 8899e85)
include X_OK.
(".", "..", etc).