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.
This commit is contained in:
Kumar Aditya 2022-10-17 20:57:02 +05:30 • committed by GitHub
parent 6da1a2e993
commit 72c10d3f1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 32 deletions

View 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 = events.get_child_watcher()
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
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

View 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(