mirror of
https://github.com/python/cpython.git
synced 2024-11-27 03:45:08 +08:00
Issue #16993: shutil.which() now preserves the case of the path and extension
on Windows.
This commit is contained in:
parent
85da624ebe
commit
014791f848
@ -335,7 +335,7 @@ Directory and files operations
|
||||
directories. For example, on Windows::
|
||||
|
||||
>>> shutil.which("python")
|
||||
'c:\\python33\\python.exe'
|
||||
'C:\\Python33\\python.exe'
|
||||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
|
@ -1093,10 +1093,12 @@ def which(cmd, mode=os.F_OK | os.X_OK, path=None):
|
||||
pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
|
||||
# See if the given file matches any of the expected path extensions.
|
||||
# This will allow us to short circuit when given "python.exe".
|
||||
matches = [cmd for ext in pathext if cmd.lower().endswith(ext.lower())]
|
||||
# If it does match, only test that one, otherwise we have to try
|
||||
# others.
|
||||
files = [cmd] if matches else [cmd + ext.lower() for ext in pathext]
|
||||
if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
|
||||
files = [cmd]
|
||||
else:
|
||||
files = [cmd + ext for ext in pathext]
|
||||
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.
|
||||
@ -1104,9 +1106,9 @@ def which(cmd, mode=os.F_OK | os.X_OK, path=None):
|
||||
|
||||
seen = set()
|
||||
for dir in path:
|
||||
dir = os.path.normcase(dir)
|
||||
if not dir in seen:
|
||||
seen.add(dir)
|
||||
normdir = os.path.normcase(dir)
|
||||
if not normdir in seen:
|
||||
seen.add(normdir)
|
||||
for thefile in files:
|
||||
name = os.path.join(dir, thefile)
|
||||
if _access_check(name, mode):
|
||||
|
@ -1269,12 +1269,13 @@ class TestShutil(unittest.TestCase):
|
||||
class TestWhich(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.temp_dir = tempfile.mkdtemp(prefix="Tmp")
|
||||
self.addCleanup(shutil.rmtree, self.temp_dir, True)
|
||||
# Give the temp_file an ".exe" suffix for all.
|
||||
# It's needed on Windows and not harmful on other platforms.
|
||||
self.temp_file = tempfile.NamedTemporaryFile(dir=self.temp_dir,
|
||||
suffix=".exe")
|
||||
prefix="Tmp",
|
||||
suffix=".Exe")
|
||||
os.chmod(self.temp_file.name, stat.S_IXUSR)
|
||||
self.addCleanup(self.temp_file.close)
|
||||
self.dir, self.file = os.path.split(self.temp_file.name)
|
||||
@ -1317,7 +1318,7 @@ class TestWhich(unittest.TestCase):
|
||||
# Ask for the file without the ".exe" extension, then ensure that
|
||||
# it gets found properly with the extension.
|
||||
rv = shutil.which(self.temp_file.name[:-4], path=self.dir)
|
||||
self.assertEqual(self.temp_file.name, rv)
|
||||
self.assertEqual(rv, self.temp_file.name[:-4] + ".exe")
|
||||
|
||||
|
||||
class TestMove(unittest.TestCase):
|
||||
|
Loading…
Reference in New Issue
Block a user