From be50a7b627d0aa37e08fa8e2d5568891f19903ce Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 28 Feb 2018 01:03:46 +0200 Subject: [PATCH] Revert "bpo-31961: subprocess now accepts path-like args (GH-4329)" (#5912) * Revert "bpo-31961: subprocess now accepts path-like args (GH-4329)" This reverts commit dd42cb71f2cb02f3a32f016137b12a146bc0d0e2. --- Doc/library/subprocess.rst | 16 ++++++---------- Lib/subprocess.py | 12 ++---------- Lib/test/test_subprocess.py | 31 ------------------------------- Misc/NEWS.d/3.7.0b1.rst | 1 + 4 files changed, 9 insertions(+), 51 deletions(-) diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index a22afe041850bb..db7a88af6bea08 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -339,12 +339,12 @@ functions. the class uses the Windows ``CreateProcess()`` function. The arguments to :class:`Popen` are as follows. - *args* should be a sequence of program arguments or else a single string or - :term:`path-like object`. By default, the program to execute is the first - item in *args* if *args* is a sequence. If *args* is a string, the - interpretation is platform-dependent and described below. See the *shell* - and *executable* arguments for additional differences from the default - behavior. Unless otherwise stated, it is recommended to pass *args* as a sequence. + *args* should be a sequence of program arguments or else a single string. + By default, the program to execute is the first item in *args* if *args* is + a sequence. If *args* is a string, the interpretation is + platform-dependent and described below. See the *shell* and *executable* + arguments for additional differences from the default behavior. Unless + otherwise stated, it is recommended to pass *args* as a sequence. On POSIX, if *args* is a string, the string is interpreted as the name or path of the program to execute. However, this can only be done if not @@ -558,10 +558,6 @@ functions. Popen destructor now emits a :exc:`ResourceWarning` warning if the child process is still running. - .. versionchanged:: 3.7 - *args*, or the first element of *args* if *args* is a sequence, can now - be a :term:`path-like object`. - Exceptions ^^^^^^^^^^ diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 2723bc9e4274c3..93635ee61f7e9f 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1097,12 +1097,7 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, assert not pass_fds, "pass_fds not supported on Windows." if not isinstance(args, str): - try: - args = os.fsdecode(args) # os.PathLike -> str - except TypeError: # not an os.PathLike, must be a sequence. - args = list(args) - args[0] = os.fsdecode(args[0]) # os.PathLike -> str - args = list2cmdline(args) + args = list2cmdline(args) # Process startup details if startupinfo is None: @@ -1374,10 +1369,7 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, if isinstance(args, (str, bytes)): args = [args] else: - try: - args = list(args) - except TypeError: # os.PathLike instead of a sequence? - args = [os.fsencode(args)] # os.PathLike -> [str] + args = list(args) if shell: # On Android the default shell is at '/system/bin/sh'. diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index b3ccb0de63a84c..46cb5f117e84f4 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -1475,37 +1475,6 @@ def test_run_kwargs(self): env=newenv) self.assertEqual(cp.returncode, 33) - def test_run_with_pathlike_path(self): - # bpo-31961: test run(pathlike_object) - class Path: - def __fspath__(self): - # the name of a command that can be run without - # any argumenets that exit fast - return 'dir' if mswindows else 'ls' - - path = Path() - if mswindows: - res = subprocess.run(path, stdout=subprocess.DEVNULL, shell=True) - else: - res = subprocess.run(path, stdout=subprocess.DEVNULL) - - self.assertEqual(res.returncode, 0) - - def test_run_with_pathlike_path_and_arguments(self): - # bpo-31961: test run([pathlike_object, 'additional arguments']) - class Path: - def __fspath__(self): - # the name of a command that can be run without - # any argumenets that exits fast - return sys.executable - - path = Path() - - args = [path, '-c', 'import sys; sys.exit(57)'] - res = subprocess.run(args) - - self.assertEqual(res.returncode, 57) - def test_capture_output(self): cp = self.run_python(("import sys;" "sys.stdout.write('BDFL'); " diff --git a/Misc/NEWS.d/3.7.0b1.rst b/Misc/NEWS.d/3.7.0b1.rst index bd3a6111df0b75..ec7b3c8ecf78c4 100644 --- a/Misc/NEWS.d/3.7.0b1.rst +++ b/Misc/NEWS.d/3.7.0b1.rst @@ -630,6 +630,7 @@ Add contextlib.AsyncExitStack. Patch by Alexander Mohr and Ilya Kulakov. .. nonce: x5Sv0R .. section: Library +*Removed in Python 3.7.0b2.* The *args* argument of subprocess.Popen can now be a :term:`path-like object`. If *args* is given as a sequence, it's first element can now be a :term:`path-like object` as well.