From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Date: Mon, 17 Oct 2022 15:27:02 +0000 (+0530) Subject: GH-98327: Reduce scope of catch_warnings() in _make_subprocess_transport (#98333) X-Git-Tag: v3.12.0a1~83 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=72c10d3f1a6d42b70cc4b843295361db17cc0964;p=thirdparty%2FPython%2Fcpython.git GH-98327: Reduce scope of catch_warnings() in _make_subprocess_transport (#98333) Alas, warnings.catch_warnings() has global scope, not thread scope, so this is still not perfect, but it reduces the time during which warnings are ignored. Better solution welcome. --- diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index ea7010ee1073..2de7a1bfd681 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -197,30 +197,31 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): extra=None, **kwargs): with warnings.catch_warnings(): warnings.simplefilter('ignore', DeprecationWarning) - with events.get_child_watcher() as watcher: - if not watcher.is_active(): - # Check early. - # Raising exception before process creation - # prevents subprocess execution if the watcher - # is not ready to handle it. - raise RuntimeError("asyncio.get_child_watcher() is not activated, " - "subprocess support is not installed.") - waiter = self.create_future() - transp = _UnixSubprocessTransport(self, protocol, args, shell, - stdin, stdout, stderr, bufsize, - waiter=waiter, extra=extra, - **kwargs) - - watcher.add_child_handler(transp.get_pid(), - self._child_watcher_callback, transp) - try: - await waiter - except (SystemExit, KeyboardInterrupt): - raise - except BaseException: - transp.close() - await transp._wait() - raise + watcher = events.get_child_watcher() + + with watcher: + if not watcher.is_active(): + # Check early. + # Raising exception before process creation + # prevents subprocess execution if the watcher + # is not ready to handle it. + raise RuntimeError("asyncio.get_child_watcher() is not activated, " + "subprocess support is not installed.") + waiter = self.create_future() + transp = _UnixSubprocessTransport(self, protocol, args, shell, + stdin, stdout, stderr, bufsize, + waiter=waiter, extra=extra, + **kwargs) + watcher.add_child_handler(transp.get_pid(), + self._child_watcher_callback, transp) + try: + await waiter + except (SystemExit, KeyboardInterrupt): + raise + except BaseException: + transp.close() + await transp._wait() + raise return transp diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index 8e5511559061..fe1d060c77d4 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -752,15 +752,11 @@ if sys.platform != 'win32': class GenericWatcherTests(test_utils.TestCase): def test_create_subprocess_fails_with_inactive_watcher(self): - watcher = mock.create_autospec( - asyncio.AbstractChildWatcher, - **{"__enter__.return_value.is_active.return_value": False} - ) + watcher = mock.create_autospec(asyncio.AbstractChildWatcher) + watcher.is_active.return_value = False async def execute(): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - asyncio.set_child_watcher(watcher) + asyncio.set_child_watcher(watcher) with self.assertRaises(RuntimeError): await subprocess.create_subprocess_exec( @@ -774,9 +770,9 @@ if sys.platform != 'win32': self.assertIsNone(runner.run(execute())) self.assertListEqual(watcher.mock_calls, [ mock.call.__enter__(), - mock.call.__enter__().is_active(), + mock.call.is_active(), mock.call.__exit__(RuntimeError, mock.ANY, mock.ANY), - ]) + ], watcher.mock_calls) @unittest.skipUnless(