From d7dc43568a71ccda5079441b7829cfe3de36c9dc Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Tue, 28 May 2019 23:07:11 +0800 Subject: [PATCH 1/3] bpo-35246: fix support for path-like args in asyncio subprocess drop isinstance checks from create_subprocess_exec function and let subprocess module do them. --- Lib/asyncio/base_events.py | 5 ----- Lib/test/test_asyncio/test_subprocess.py | 12 ++++++++++++ .../Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst | 1 + 3 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 68105eec8132e7..e0025397fa8a85 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -1605,11 +1605,6 @@ async def subprocess_exec(self, protocol_factory, program, *args, raise ValueError("errors must be None") popen_args = (program,) + args - for arg in popen_args: - if not isinstance(arg, (str, bytes)): - raise TypeError( - f"program arguments must be a bytes or text string, " - f"not {type(arg).__name__}") protocol = protocol_factory() debug_log = None if self._debug: diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index f1ab039ad6639b..e1a427a5edd1af 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -622,6 +622,18 @@ async def execute(): self.loop.run_until_complete(execute()) + def test_create_subprocess_exec_with_path(self): + async def execute(): + from pathlib import Path + p = await subprocess.create_subprocess_exec( + Path(sys.executable), '-c', 'pass') + await p.wait() + p = await subprocess.create_subprocess_exec( + sys.executable, '-c', 'pass', Path('.')) + await p.wait() + + self.loop.run_until_complete(execute()) + if sys.platform != 'win32': # Unix class SubprocessWatcherMixin(SubprocessMixin): diff --git a/Misc/NEWS.d/next/Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst b/Misc/NEWS.d/next/Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst new file mode 100644 index 00000000000000..39d4469cd10177 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst @@ -0,0 +1 @@ +Make :func:`asyncio.create_subprocess_exec` accept path-like arguments. From b69e1168798adbccf774dbc58c8fba0a54532938 Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Wed, 29 May 2019 00:00:55 +0800 Subject: [PATCH 2/3] improve test_subprocess --- Lib/test/test_asyncio/test_subprocess.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index e1a427a5edd1af..21e70e220700ac 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -7,6 +7,7 @@ import asyncio from asyncio import base_subprocess from asyncio import subprocess +import pathlib from test.test_asyncio import utils as test_utils from test import support @@ -624,15 +625,14 @@ async def execute(): def test_create_subprocess_exec_with_path(self): async def execute(): - from pathlib import Path p = await subprocess.create_subprocess_exec( - Path(sys.executable), '-c', 'pass') + pathlib.Path(sys.executable), '-c', 'pass') await p.wait() p = await subprocess.create_subprocess_exec( - sys.executable, '-c', 'pass', Path('.')) + sys.executable, '-c', 'pass', pathlib.Path('.')) await p.wait() - self.loop.run_until_complete(execute()) + self.assertIsNone(self.loop.run_until_complete(execute())) if sys.platform != 'win32': # Unix From e337a713665aed46630d487ccf957e9bb3de3142 Mon Sep 17 00:00:00 2001 From: lilydjwg Date: Wed, 29 May 2019 14:06:19 +0800 Subject: [PATCH 3/3] use test.support.FakePath instead of pathlib.Path --- Lib/test/test_asyncio/test_subprocess.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index 21e70e220700ac..7d72e6cde4e7a8 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -7,7 +7,6 @@ import asyncio from asyncio import base_subprocess from asyncio import subprocess -import pathlib from test.test_asyncio import utils as test_utils from test import support @@ -626,10 +625,10 @@ async def execute(): def test_create_subprocess_exec_with_path(self): async def execute(): p = await subprocess.create_subprocess_exec( - pathlib.Path(sys.executable), '-c', 'pass') + support.FakePath(sys.executable), '-c', 'pass') await p.wait() p = await subprocess.create_subprocess_exec( - sys.executable, '-c', 'pass', pathlib.Path('.')) + sys.executable, '-c', 'pass', support.FakePath('.')) await p.wait() self.assertIsNone(self.loop.run_until_complete(execute()))