diff --git a/Lib/shutil.py b/Lib/shutil.py index a4ce2c0290bc93..223e9a8a705064 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -53,6 +53,9 @@ _USE_CP_SENDFILE = hasattr(os, "sendfile") and sys.platform.startswith("linux") _HAS_FCOPYFILE = posix and hasattr(posix, "_fcopyfile") # macOS +# CMD defaults in Windows 10 +_WIN_DEFAULT_PATHEXT = ".COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC" + __all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", "copytree", "move", "rmtree", "Error", "SpecialFileError", "ExecError", "make_archive", "get_archive_formats", @@ -1415,7 +1418,9 @@ def which(cmd, mode=os.F_OK | os.X_OK, path=None): path.insert(0, curdir) # PATHEXT is necessary to check on Windows. - pathext = os.environ.get("PATHEXT", "").split(os.pathsep) + pathext_source = os.getenv("PATHEXT") or _WIN_DEFAULT_PATHEXT + pathext = [ext for ext in pathext_source.split(os.pathsep) if ext] + if use_bytes: pathext = [os.fsencode(ext) for ext in pathext] # See if the given file matches any of the expected path extensions. diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 06ca50af143379..890f2c7d406c24 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1849,6 +1849,23 @@ def test_pathext(self): rv = shutil.which(program, path=self.temp_dir) self.assertEqual(rv, temp_filexyz.name) + # Issue 40592: See https://bugs.python.org/issue40592 + @unittest.skipUnless(sys.platform == "win32", 'test specific to Windows') + def test_pathext_with_empty_str(self): + ext = ".xyz" + temp_filexyz = tempfile.NamedTemporaryFile(dir=self.temp_dir, + prefix="Tmp2", suffix=ext) + self.addCleanup(temp_filexyz.close) + + # strip path and extension + program = os.path.basename(temp_filexyz.name) + program = os.path.splitext(program)[0] + + with os_helper.EnvironmentVarGuard() as env: + env['PATHEXT'] = f"{ext};" # note the ; + rv = shutil.which(program, path=self.temp_dir) + self.assertEqual(rv, temp_filexyz.name) + class TestWhichBytes(TestWhich): def setUp(self): diff --git a/Misc/NEWS.d/next/Library/2020-05-14-16-01-34.bpo-40592.Cmk855.rst b/Misc/NEWS.d/next/Library/2020-05-14-16-01-34.bpo-40592.Cmk855.rst new file mode 100644 index 00000000000000..3211a1bc345fa5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-14-16-01-34.bpo-40592.Cmk855.rst @@ -0,0 +1 @@ +:func:`shutil.which` now ignores empty entries in :envvar:`PATHEXT` instead of treating them as a match.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: