]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-98327: Reduce scope of catch_warnings() in _make_subprocess_transport (#98333)
authorKumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Mon, 17 Oct 2022 15:27:02 +0000 (20:57 +0530)
committerGitHub <noreply@github.com>
Mon, 17 Oct 2022 15:27:02 +0000 (08:27 -0700)
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.

Lib/asyncio/unix_events.py
Lib/test/test_asyncio/test_subprocess.py

index ea7010ee10732206dbaa2b410919e48b432570be..2de7a1bfd681553644ff4851b93ad3d8d3b64520 100644 (file)
@@ -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
 
index 8e55115590617e7f6064ea398840c85bfd27a89f..fe1d060c77d4c745bea72d8d536feba55c470fe8 100644 (file)
@@ -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(