summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_asyncio/test_subprocess.py
diff options
context:
space:
mode:
authorThomas Grainger <tagrain@gmail.com>2022-10-08 00:24:01 (GMT)
committerGitHub <noreply@github.com>2022-10-08 00:24:01 (GMT)
commit3d8b22454728b6d54cc476cfb59e47ab40f3f527 (patch)
tree32f85c6b66f858a5235408a1b2b3b4de98b6a7f1 /Lib/test/test_asyncio/test_subprocess.py
parent27ce45d8e105d0c9f9286c3cab830590d4c7cea3 (diff)
downloadcpython-3d8b22454728b6d54cc476cfb59e47ab40f3f527.zip
cpython-3d8b22454728b6d54cc476cfb59e47ab40f3f527.tar.gz
cpython-3d8b22454728b6d54cc476cfb59e47ab40f3f527.tar.bz2
GH-94182: Run the PidfdChildWatcher on the running loop (#94184)
There is no reason for this watcher to be attached to any particular loop. This should make it safe to use regardless of the lifetime of the event loop running in the main thread (relative to other loops). Co-authored-by: Yury Selivanov <yury@edgedb.com> Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Diffstat (limited to 'Lib/test/test_asyncio/test_subprocess.py')
-rw-r--r--Lib/test/test_asyncio/test_subprocess.py54
1 files changed, 44 insertions, 10 deletions
diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py
index 9bc60b9..6ba8894 100644
--- a/Lib/test/test_asyncio/test_subprocess.py
+++ b/Lib/test/test_asyncio/test_subprocess.py
@@ -4,6 +4,7 @@ import signal
import sys
import unittest
import warnings
+import functools
from unittest import mock
import asyncio
@@ -30,6 +31,19 @@ PROGRAM_CAT = [
'sys.stdout.buffer.write(data)'))]
+@functools.cache
+def _has_pidfd_support():
+ if not hasattr(os, 'pidfd_open'):
+ return False
+
+ try:
+ os.close(os.pidfd_open(os.getpid()))
+ except OSError:
+ return False
+
+ return True
+
+
def tearDownModule():
asyncio.set_event_loop_policy(None)
@@ -708,17 +722,8 @@ if sys.platform != 'win32':
Watcher = unix_events.FastChildWatcher
- def has_pidfd_support():
- if not hasattr(os, 'pidfd_open'):
- return False
- try:
- os.close(os.pidfd_open(os.getpid()))
- except OSError:
- return False
- return True
-
@unittest.skipUnless(
- has_pidfd_support(),
+ _has_pidfd_support(),
"operating system does not support pidfds",
)
class SubprocessPidfdWatcherTests(SubprocessWatcherMixin,
@@ -751,6 +756,35 @@ if sys.platform != 'win32':
mock.call.__exit__(RuntimeError, mock.ANY, mock.ANY),
])
+
+ @unittest.skipUnless(
+ _has_pidfd_support(),
+ "operating system does not support pidfds",
+ )
+ def test_create_subprocess_with_pidfd(self):
+ async def in_thread():
+ proc = await asyncio.create_subprocess_exec(
+ *PROGRAM_CAT,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ )
+ stdout, stderr = await proc.communicate(b"some data")
+ return proc.returncode, stdout
+
+ async def main():
+ # asyncio.Runner did not call asyncio.set_event_loop()
+ with self.assertRaises(RuntimeError):
+ asyncio.get_event_loop_policy().get_event_loop()
+ return await asyncio.to_thread(asyncio.run, in_thread())
+
+ asyncio.set_child_watcher(asyncio.PidfdChildWatcher())
+ try:
+ with asyncio.Runner(loop_factory=asyncio.new_event_loop) as runner:
+ returncode, stdout = runner.run(main())
+ self.assertEqual(returncode, 0)
+ self.assertEqual(stdout, b'some data')
+ finally:
+ asyncio.set_child_watcher(None)
else:
# Windows
class SubprocessProactorTests(SubprocessMixin, test_utils.TestCase):