From fe064f44079fa01da16c4b8d3382e02b558b6afc Mon Sep 17 00:00:00 2001 From: Christopher Marchfelder Date: Fri, 23 Oct 2020 12:08:24 +0200 Subject: [PATCH 1/2] bpo-40592: shutil.which will not return None anymore if ; is the last char in PATHEXT (GH-20088) shutil.which will not return None anymore for empty str in PATHEXT Empty PATHEXT will now be defaulted to _WIN_DEFAULT_PATHEXT (cherry picked from commit da6f098188c9825f10ae60db8987056b3a54c2e8) Co-authored-by: Christopher Marchfelder --- Lib/shutil.py | 7 ++++++- Lib/test/test_shutil.py | 17 +++++++++++++++++ .../2020-05-14-16-01-34.bpo-40592.Cmk855.rst | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2020-05-14-16-01-34.bpo-40592.Cmk855.rst diff --git a/Lib/shutil.py b/Lib/shutil.py index 1f05d80f32a8fc..9d151493e76675 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", @@ -1400,7 +1403,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 bcb7e498e198e2..e45bab2ca04b9d 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1830,6 +1830,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. From 52e09a2be61951a69db79b6d5e9293d77fd0569f Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Fri, 23 Oct 2020 14:06:14 +0100 Subject: [PATCH 2/2] Update test_shutil.py --- Lib/test/test_shutil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index e45bab2ca04b9d..77306170d9fc18 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1842,7 +1842,7 @@ def test_pathext_with_empty_str(self): program = os.path.basename(temp_filexyz.name) program = os.path.splitext(program)[0] - with os_helper.EnvironmentVarGuard() as env: + with support.EnvironmentVarGuard() as env: env['PATHEXT'] = f"{ext};" # note the ; rv = shutil.which(program, path=self.temp_dir) self.assertEqual(rv, temp_filexyz.name) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy