From 2981e84f66e06e758a0eac2620a87ff85318722c Mon Sep 17 00:00:00 2001 From: Christopher Marchfelder Date: Thu, 14 May 2020 17:30:03 +0200 Subject: [PATCH 01/12] shutil.which will not return None anymore for empty str in PATHEXT --- Lib/shutil.py | 2 +- Lib/test/test_shutil.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Lib/shutil.py b/Lib/shutil.py index a4ce2c0290bc93..71b39d39a82912 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -1415,7 +1415,7 @@ 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 = [ext for ext in os.environ.get("PATHEXT", "").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 b9fdfd1350a096..f525d67047af4c 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1848,6 +1848,23 @@ def test_pathext(self): rv = shutil.which(program, path=self.temp_dir) self.assertEqual(rv, temp_filexyz.name) + @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) + os.chmod(temp_filexyz.name, stat.S_IXUSR) + self.addCleanup(temp_filexyz.close) + + # strip path and extension + program = os.path.basename(temp_filexyz.name) + program = os.path.splitext(program)[0] + + 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) + class TestWhichBytes(TestWhich): def setUp(self): From 9df7b99bcf203e5cbd82e52419121887e1079860 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 14 May 2020 16:01:35 +0000 Subject: [PATCH 02/12] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2020-05-14-16-01-34.bpo-40592.Cmk855.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2020-05-14-16-01-34.bpo-40592.Cmk855.rst 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..44dd5e2b38ed01 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-14-16-01-34.bpo-40592.Cmk855.rst @@ -0,0 +1 @@ +shutil.which returns not None anymore with ; at the end of PATHEXT \ No newline at end of file From 6dd95748ea478555614c5028e1ed8e1b52e2f553 Mon Sep 17 00:00:00 2001 From: Christopher Marchfelder Date: Thu, 14 May 2020 19:35:44 +0200 Subject: [PATCH 03/12] Defaulted missing PATHEX env to cmd defaults --- Lib/shutil.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/shutil.py b/Lib/shutil.py index 71b39d39a82912..f8f8e1a3cb3b3d 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -52,6 +52,7 @@ COPY_BUFSIZE = 1024 * 1024 if _WINDOWS else 64 * 1024 _USE_CP_SENDFILE = hasattr(os, "sendfile") and sys.platform.startswith("linux") _HAS_FCOPYFILE = posix and hasattr(posix, "_fcopyfile") # macOS +_WIN_DEFAULT_PATHEXT = ".COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC" __all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", "copytree", "move", "rmtree", "Error", "SpecialFileError", @@ -1415,7 +1416,7 @@ def which(cmd, mode=os.F_OK | os.X_OK, path=None): path.insert(0, curdir) # PATHEXT is necessary to check on Windows. - pathext = [ext for ext in os.environ.get("PATHEXT", "").split(os.pathsep) if ext] + pathext = [ext for ext in os.environ.get("PATHEXT", _WIN_DEFAULT_PATHEXT).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. From 9eb17bb4aef95cde503e22c3fc79830d485d92dc Mon Sep 17 00:00:00 2001 From: Christopher Marchfelder Date: Fri, 15 May 2020 08:38:02 +0200 Subject: [PATCH 04/12] Changed os.chmod from 'S_IXUSR' to 'S_IXUSR | S_IWUSR' --- Lib/test/test_shutil.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index f525d67047af4c..8a59b80d97c37b 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1848,12 +1848,13 @@ 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) - os.chmod(temp_filexyz.name, stat.S_IXUSR) + os.chmod(temp_filexyz.name, stat.S_IXUSR | stat.S_IWUSR) self.addCleanup(temp_filexyz.close) # strip path and extension From e6a9c2c78e154878cf0b722a12737e8a60569772 Mon Sep 17 00:00:00 2001 From: Christopher Marchfelder Date: Fri, 15 May 2020 17:20:03 +0200 Subject: [PATCH 05/12] Added comment to explain the _WIN_DEFAULT_PATHEXT properly --- Lib/shutil.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/shutil.py b/Lib/shutil.py index f8f8e1a3cb3b3d..07eb8bf921b11b 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -52,6 +52,8 @@ COPY_BUFSIZE = 1024 * 1024 if _WINDOWS else 64 * 1024 _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", From 496695670b5ac2cfbfc46845f96d541991be40dd Mon Sep 17 00:00:00 2001 From: Christopher Marchfelder Date: Tue, 19 May 2020 21:47:23 +0200 Subject: [PATCH 06/12] Updated change description Co-authored-by: Steve Dower --- .../next/Library/2020-05-14-16-01-34.bpo-40592.Cmk855.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 44dd5e2b38ed01..3211a1bc345fa5 100644 --- 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 @@ -1 +1 @@ -shutil.which returns not None anymore with ; at the end of PATHEXT \ No newline at end of file +:func:`shutil.which` now ignores empty entries in :envvar:`PATHEXT` instead of treating them as a match. From cdb179e68243580064a41500b79e005840a23ec5 Mon Sep 17 00:00:00 2001 From: Christopher Marchfelder Date: Tue, 19 May 2020 21:56:12 +0200 Subject: [PATCH 07/12] Adjusted list comprehension to adhere line length --- Lib/shutil.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/shutil.py b/Lib/shutil.py index 07eb8bf921b11b..c9c8c0733907ac 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -1418,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 = [ext for ext in os.environ.get("PATHEXT", _WIN_DEFAULT_PATHEXT).split(os.pathsep) if ext] + pathext = [ext for ext in + os.environ.get("PATHEXT", _WIN_DEFAULT_PATHEXT).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. From 01efb429a2b550fa0895f2f6b8e1ee07b501734b Mon Sep 17 00:00:00 2001 From: Christopher Marchfelder Date: Tue, 19 May 2020 21:57:34 +0200 Subject: [PATCH 08/12] Removed chown from unittest --- Lib/test/test_shutil.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 8a59b80d97c37b..27997671a4331b 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1854,7 +1854,6 @@ def test_pathext_with_empty_str(self): ext = ".xyz" temp_filexyz = tempfile.NamedTemporaryFile(dir=self.temp_dir, prefix="Tmp2", suffix=ext) - os.chmod(temp_filexyz.name, stat.S_IXUSR | stat.S_IWUSR) self.addCleanup(temp_filexyz.close) # strip path and extension From fc87309eae7b72ba19341f5b7b8d08a8546f21a1 Mon Sep 17 00:00:00 2001 From: Christopher Marchfelder Date: Wed, 21 Oct 2020 18:21:39 +0200 Subject: [PATCH 09/12] Empty PATHEXT () will now also be defaulted to _WIN_DEFAULT_PATHEXT --- Lib/shutil.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/shutil.py b/Lib/shutil.py index c9c8c0733907ac..223e9a8a705064 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -1418,9 +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 = [ext for ext in - os.environ.get("PATHEXT", _WIN_DEFAULT_PATHEXT).split( - os.pathsep) if ext] + 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. From 6af00e791c256045d8d31a93acaf83079b52e124 Mon Sep 17 00:00:00 2001 From: Christopher Marchfelder Date: Wed, 21 Oct 2020 18:23:31 +0200 Subject: [PATCH 10/12] When no extension is found, we return a list with the command --- Lib/shutil.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/shutil.py b/Lib/shutil.py index 223e9a8a705064..18627ae22b236f 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -1427,7 +1427,8 @@ def which(cmd, mode=os.F_OK | os.X_OK, path=None): # This will allow us to short circuit when given "python.exe". # If it does match, only test that one, otherwise we have to try # others. - if any(cmd.lower().endswith(ext.lower()) for ext in pathext): + if not pathext or any( + cmd.lower().endswith(ext.lower()) for ext in pathext): files = [cmd] else: files = [cmd + ext for ext in pathext] From ee618eb819d1c984cc79b1fa1a1a8a05a26bda79 Mon Sep 17 00:00:00 2001 From: Christopher Marchfelder Date: Wed, 21 Oct 2020 19:00:29 +0200 Subject: [PATCH 11/12] Revert "When no extension is found, we return a list with the command" This reverts commit 6af00e791c256045d8d31a93acaf83079b52e124. --- Lib/shutil.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/shutil.py b/Lib/shutil.py index 18627ae22b236f..223e9a8a705064 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -1427,8 +1427,7 @@ def which(cmd, mode=os.F_OK | os.X_OK, path=None): # This will allow us to short circuit when given "python.exe". # If it does match, only test that one, otherwise we have to try # others. - if not pathext or any( - cmd.lower().endswith(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] From 6c66dfc024d080c7ba3d2482b1652382df232f9e Mon Sep 17 00:00:00 2001 From: Christopher Marchfelder Date: Thu, 22 Oct 2020 22:32:02 +0200 Subject: [PATCH 12/12] Switched to from support to os_helper in unittest --- 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 460135893d29f3..890f2c7d406c24 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1861,7 +1861,7 @@ def test_pathext_with_empty_str(self): program = os.path.basename(temp_filexyz.name) program = os.path.splitext(program)[0] - with support.EnvironmentVarGuard() as env: + 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) 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