From 2cb82679cf431b06317bd6be389809e63cb671e6 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Wed, 25 Dec 2024 21:30:46 +0000 Subject: [PATCH 1/5] support wasi/emscripten on pdb tests --- Lib/test/support/__init__.py | 28 +++++++++++++ Lib/test/test_contextlib_async.py | 15 +------ Lib/test/test_inspect/test_inspect.py | 14 ++----- Lib/test/test_pdb.py | 57 +++++++++++++-------------- 4 files changed, 61 insertions(+), 53 deletions(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 5c738ffaa27713..4fe62b1848bda6 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2940,3 +2940,31 @@ def in_systemd_nspawn_sync_suppressed() -> bool: os.close(fd) return False + +def run_simple_async_fn(async_fn, /, *args, **kwargs): + coro = async_fn(*args, **kwargs) + try: + coro.send(None) + except StopIteration as e: + return e.value + else: + raise AssertionError("coroutine did not complete") + finally: + coro.close() + + +@types.coroutine +def async_yield(v): + return (yield v) + + +def run_async_fn(async_fn, /, *args, **kwargs): + coro = async_fn(*args, **kwargs) + try: + while True: + try: + coro.send(None) + except StopIteration as e: + return e.value + finally: + coro.close() diff --git a/Lib/test/test_contextlib_async.py b/Lib/test/test_contextlib_async.py index d496aa611d1068..c6c5e59d65eff8 100644 --- a/Lib/test/test_contextlib_async.py +++ b/Lib/test/test_contextlib_async.py @@ -3,24 +3,13 @@ asynccontextmanager, AbstractAsyncContextManager, AsyncExitStack, nullcontext, aclosing, contextmanager) from test import support +from test.support import run_simple_async_fn as _run_async_fn import unittest import traceback from test.test_contextlib import TestBaseExitStack -def _run_async_fn(async_fn, /, *args, **kwargs): - coro = async_fn(*args, **kwargs) - try: - coro.send(None) - except StopIteration as e: - return e.value - else: - raise AssertionError("coroutine did not complete") - finally: - coro.close() - - def _async_test(async_fn): """Decorator to turn an async function into a synchronous function""" @functools.wraps(async_fn) @@ -546,7 +535,7 @@ def __exit__(self, *exc_details): exit_stack = SyncAsyncExitStack callback_error_internal_frames = [ ('__exit__', 'return _run_async_fn(self.__aexit__, *exc_details)'), - ('_run_async_fn', 'coro.send(None)'), + ('run_simple_async_fn', 'coro.send(None)'), ('__aexit__', 'raise exc'), ('__aexit__', 'cb_suppress = cb(*exc_details)'), ] diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index d536d04d2e7d88..49c9586e553083 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -1161,19 +1161,11 @@ def f(self): sys.modules.pop("inspect_actual") def test_nested_class_definition_inside_async_function(self): - def run(coro): - try: - coro.send(None) - except StopIteration as e: - return e.value - else: - raise RuntimeError("coroutine did not complete synchronously!") - finally: - coro.close() + from test.support import run_simple_async_fn as run - self.assertSourceEqual(run(mod2.func225()), 226, 227) + self.assertSourceEqual(run(mod2.func225), 226, 227) self.assertSourceEqual(mod2.cls226, 231, 235) - self.assertSourceEqual(run(mod2.cls226().func232()), 233, 234) + self.assertSourceEqual(run(mod2.cls226().func232), 233, 234) def test_class_definition_same_name_diff_methods(self): self.assertSourceEqual(mod2.cls296, 296, 298) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 9b0806d8b2a9bd..1f94c9018a8968 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -20,8 +20,7 @@ from test.support.pty_helper import run_pty, FakeInput from unittest.mock import patch -# gh-114275: WASI fails to run asyncio tests, similar skip than test_asyncio. -SKIP_ASYNCIO_TESTS = (not support.has_socket_support) +SKIP_CORO_TESTS = False class PdbTestInput(object): @@ -2049,23 +2048,23 @@ def test_pdb_next_command_for_generator(): finished """ -if not SKIP_ASYNCIO_TESTS: +if not SKIP_CORO_TESTS: def test_pdb_next_command_for_coroutine(): """Testing skip unwindng stack on yield for coroutines for "next" command - >>> import asyncio + >>> from test.support import run_async_fn, async_yield >>> async def test_coro(): - ... await asyncio.sleep(0) - ... await asyncio.sleep(0) - ... await asyncio.sleep(0) + ... await async_yield(0) + ... await async_yield(0) + ... await async_yield(0) >>> async def test_main(): ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() ... await test_coro() >>> def test_function(): - ... asyncio.run(test_main()) + ... run_async_fn(test_main) ... print("finished") >>> with PdbTestInput(['step', @@ -2088,13 +2087,13 @@ def test_pdb_next_command_for_coroutine(): -> async def test_coro(): (Pdb) step > (2)test_coro() - -> await asyncio.sleep(0) + -> await async_yield(0) (Pdb) next > (3)test_coro() - -> await asyncio.sleep(0) + -> await async_yield(0) (Pdb) next > (4)test_coro() - -> await asyncio.sleep(0) + -> await async_yield(0) (Pdb) next Internal StopIteration > (3)test_main() @@ -2110,11 +2109,11 @@ def test_pdb_next_command_for_coroutine(): def test_pdb_next_command_for_asyncgen(): """Testing skip unwindng stack on yield for coroutines for "next" command - >>> import asyncio + >>> from test.support import run_async_fn, async_yield >>> async def agen(): ... yield 1 - ... await asyncio.sleep(0) + ... await async_yield(0) ... yield 2 >>> async def test_coro(): @@ -2126,7 +2125,7 @@ def test_pdb_next_command_for_asyncgen(): ... await test_coro() >>> def test_function(): - ... asyncio.run(test_main()) + ... run_async_fn(test_main) ... print("finished") >>> with PdbTestInput(['step', @@ -2163,7 +2162,7 @@ def test_pdb_next_command_for_asyncgen(): -> yield 1 (Pdb) next > (3)agen() - -> await asyncio.sleep(0) + -> await async_yield(0) (Pdb) continue 2 finished @@ -2228,23 +2227,23 @@ def test_pdb_return_command_for_generator(): finished """ -if not SKIP_ASYNCIO_TESTS: +if not SKIP_CORO_TESTS: def test_pdb_return_command_for_coroutine(): """Testing no unwindng stack on yield for coroutines for "return" command - >>> import asyncio + >>> from test.support import run_async_fn, async_yield >>> async def test_coro(): - ... await asyncio.sleep(0) - ... await asyncio.sleep(0) - ... await asyncio.sleep(0) + ... await async_yield(0) + ... await async_yield(0) + ... await async_yield(0) >>> async def test_main(): ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() ... await test_coro() >>> def test_function(): - ... asyncio.run(test_main()) + ... run_async_fn(test_main) ... print("finished") >>> with PdbTestInput(['step', @@ -2264,10 +2263,10 @@ def test_pdb_return_command_for_coroutine(): -> async def test_coro(): (Pdb) step > (2)test_coro() - -> await asyncio.sleep(0) + -> await async_yield(0) (Pdb) next > (3)test_coro() - -> await asyncio.sleep(0) + -> await async_yield(0) (Pdb) continue finished """ @@ -2320,20 +2319,20 @@ def test_pdb_until_command_for_generator(): finished """ -if not SKIP_ASYNCIO_TESTS: +if not SKIP_CORO_TESTS: def test_pdb_until_command_for_coroutine(): """Testing no unwindng stack for coroutines for "until" command if target breakpoint is not reached - >>> import asyncio + >>> from test.support import run_async_fn, async_yield >>> async def test_coro(): ... print(0) - ... await asyncio.sleep(0) + ... await async_yield(0) ... print(1) - ... await asyncio.sleep(0) + ... await async_yield(0) ... print(2) - ... await asyncio.sleep(0) + ... await async_yield(0) ... print(3) >>> async def test_main(): @@ -2341,7 +2340,7 @@ def test_pdb_until_command_for_coroutine(): ... await test_coro() >>> def test_function(): - ... asyncio.run(test_main()) + ... run_async_fn(test_main) ... print("finished") >>> with PdbTestInput(['step', From 1a5f91026adea50778b13adfc50f190b748896a2 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Sat, 28 Dec 2024 09:48:47 +0000 Subject: [PATCH 2/5] move test.support import to the top of the file --- Lib/test/test_inspect/test_inspect.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index 49c9586e553083..240ef369c68713 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -36,6 +36,7 @@ from test.support import cpython_only, import_helper from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ +from test.support import run_simple_async_fn from test.support.import_helper import DirsOnSysPath, ready_to_import from test.support.os_helper import TESTFN, temp_cwd from test.support.script_helper import assert_python_ok, assert_python_failure, kill_python @@ -1161,7 +1162,7 @@ def f(self): sys.modules.pop("inspect_actual") def test_nested_class_definition_inside_async_function(self): - from test.support import run_simple_async_fn as run + run = run_simple_async_fn self.assertSourceEqual(run(mod2.func225), 226, 227) self.assertSourceEqual(mod2.cls226, 231, 235) From 9287e9338b8124bebb318ed0dd65a7a00e67e695 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Sat, 28 Dec 2024 09:51:25 +0000 Subject: [PATCH 3/5] add async utils to test.support.__all__ --- Lib/test/support/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 4fe62b1848bda6..e5dc28f3aa8afe 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -62,6 +62,7 @@ "force_not_colorized", "BrokenIter", "in_systemd_nspawn_sync_suppressed", + "run_simple_async_fn", "run_async_fn", "async_yield", ] From 7e05d502c8202254d895aa7dad3b2570a20e58bb Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Sat, 28 Dec 2024 10:01:40 +0000 Subject: [PATCH 4/5] update names --- Lib/test/support/__init__.py | 6 +++--- Lib/test/test_contextlib_async.py | 4 ++-- Lib/test/test_inspect/test_inspect.py | 4 ++-- Lib/test/test_pdb.py | 16 ++++++++-------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index e5dc28f3aa8afe..cf3077f2a4a409 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -62,7 +62,7 @@ "force_not_colorized", "BrokenIter", "in_systemd_nspawn_sync_suppressed", - "run_simple_async_fn", "run_async_fn", "async_yield", + "run_no_yield_async_fn", "run_yielding_async_fn", "async_yield", ] @@ -2942,7 +2942,7 @@ def in_systemd_nspawn_sync_suppressed() -> bool: return False -def run_simple_async_fn(async_fn, /, *args, **kwargs): +def run_no_yield_async_fn(async_fn, /, *args, **kwargs): coro = async_fn(*args, **kwargs) try: coro.send(None) @@ -2959,7 +2959,7 @@ def async_yield(v): return (yield v) -def run_async_fn(async_fn, /, *args, **kwargs): +def run_yielding_async_fn(async_fn, /, *args, **kwargs): coro = async_fn(*args, **kwargs) try: while True: diff --git a/Lib/test/test_contextlib_async.py b/Lib/test/test_contextlib_async.py index c6c5e59d65eff8..7750186e56a5cc 100644 --- a/Lib/test/test_contextlib_async.py +++ b/Lib/test/test_contextlib_async.py @@ -3,7 +3,7 @@ asynccontextmanager, AbstractAsyncContextManager, AsyncExitStack, nullcontext, aclosing, contextmanager) from test import support -from test.support import run_simple_async_fn as _run_async_fn +from test.support import run_no_yield_async_fn as _run_async_fn import unittest import traceback @@ -535,7 +535,7 @@ def __exit__(self, *exc_details): exit_stack = SyncAsyncExitStack callback_error_internal_frames = [ ('__exit__', 'return _run_async_fn(self.__aexit__, *exc_details)'), - ('run_simple_async_fn', 'coro.send(None)'), + ('run_no_yield_async_fn', 'coro.send(None)'), ('__aexit__', 'raise exc'), ('__aexit__', 'cb_suppress = cb(*exc_details)'), ] diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index 240ef369c68713..345a57a5cfee2d 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -36,7 +36,7 @@ from test.support import cpython_only, import_helper from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ -from test.support import run_simple_async_fn +from test.support import run_no_yield_async_fn from test.support.import_helper import DirsOnSysPath, ready_to_import from test.support.os_helper import TESTFN, temp_cwd from test.support.script_helper import assert_python_ok, assert_python_failure, kill_python @@ -1162,7 +1162,7 @@ def f(self): sys.modules.pop("inspect_actual") def test_nested_class_definition_inside_async_function(self): - run = run_simple_async_fn + run = run_no_yield_async_fn self.assertSourceEqual(run(mod2.func225), 226, 227) self.assertSourceEqual(mod2.cls226, 231, 235) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 1f94c9018a8968..91352af06b985a 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -2052,7 +2052,7 @@ def test_pdb_next_command_for_generator(): def test_pdb_next_command_for_coroutine(): """Testing skip unwindng stack on yield for coroutines for "next" command - >>> from test.support import run_async_fn, async_yield + >>> from test.support import run_yielding_async_fn, async_yield >>> async def test_coro(): ... await async_yield(0) @@ -2064,7 +2064,7 @@ def test_pdb_next_command_for_coroutine(): ... await test_coro() >>> def test_function(): - ... run_async_fn(test_main) + ... run_yielding_async_fn(test_main) ... print("finished") >>> with PdbTestInput(['step', @@ -2109,7 +2109,7 @@ def test_pdb_next_command_for_coroutine(): def test_pdb_next_command_for_asyncgen(): """Testing skip unwindng stack on yield for coroutines for "next" command - >>> from test.support import run_async_fn, async_yield + >>> from test.support import run_yielding_async_fn, async_yield >>> async def agen(): ... yield 1 @@ -2125,7 +2125,7 @@ def test_pdb_next_command_for_asyncgen(): ... await test_coro() >>> def test_function(): - ... run_async_fn(test_main) + ... run_yielding_async_fn(test_main) ... print("finished") >>> with PdbTestInput(['step', @@ -2231,7 +2231,7 @@ def test_pdb_return_command_for_generator(): def test_pdb_return_command_for_coroutine(): """Testing no unwindng stack on yield for coroutines for "return" command - >>> from test.support import run_async_fn, async_yield + >>> from test.support import run_yielding_async_fn, async_yield >>> async def test_coro(): ... await async_yield(0) @@ -2243,7 +2243,7 @@ def test_pdb_return_command_for_coroutine(): ... await test_coro() >>> def test_function(): - ... run_async_fn(test_main) + ... run_yielding_async_fn(test_main) ... print("finished") >>> with PdbTestInput(['step', @@ -2324,7 +2324,7 @@ def test_pdb_until_command_for_coroutine(): """Testing no unwindng stack for coroutines for "until" command if target breakpoint is not reached - >>> from test.support import run_async_fn, async_yield + >>> from test.support import run_yielding_async_fn, async_yield >>> async def test_coro(): ... print(0) @@ -2340,7 +2340,7 @@ def test_pdb_until_command_for_coroutine(): ... await test_coro() >>> def test_function(): - ... run_async_fn(test_main) + ... run_yielding_async_fn(test_main) ... print("finished") >>> with PdbTestInput(['step', From 64e5315c27614ac322d40fccb3b8fd2c5369be9d Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Sat, 28 Dec 2024 12:05:19 +0000 Subject: [PATCH 5/5] fix unwindng/unwinding typo --- Lib/test/test_pdb.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 91352af06b985a..c5ee8c5fb25350 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1986,7 +1986,7 @@ def test_next_until_return_at_return_event(): """ def test_pdb_next_command_for_generator(): - """Testing skip unwindng stack on yield for generators for "next" command + """Testing skip unwinding stack on yield for generators for "next" command >>> def test_gen(): ... yield 0 @@ -2050,7 +2050,7 @@ def test_pdb_next_command_for_generator(): if not SKIP_CORO_TESTS: def test_pdb_next_command_for_coroutine(): - """Testing skip unwindng stack on yield for coroutines for "next" command + """Testing skip unwinding stack on yield for coroutines for "next" command >>> from test.support import run_yielding_async_fn, async_yield @@ -2107,7 +2107,7 @@ def test_pdb_next_command_for_coroutine(): """ def test_pdb_next_command_for_asyncgen(): - """Testing skip unwindng stack on yield for coroutines for "next" command + """Testing skip unwinding stack on yield for coroutines for "next" command >>> from test.support import run_yielding_async_fn, async_yield @@ -2169,7 +2169,7 @@ def test_pdb_next_command_for_asyncgen(): """ def test_pdb_return_command_for_generator(): - """Testing no unwindng stack on yield for generators + """Testing no unwinding stack on yield for generators for "return" command >>> def test_gen(): @@ -2229,7 +2229,7 @@ def test_pdb_return_command_for_generator(): if not SKIP_CORO_TESTS: def test_pdb_return_command_for_coroutine(): - """Testing no unwindng stack on yield for coroutines for "return" command + """Testing no unwinding stack on yield for coroutines for "return" command >>> from test.support import run_yielding_async_fn, async_yield @@ -2272,7 +2272,7 @@ def test_pdb_return_command_for_coroutine(): """ def test_pdb_until_command_for_generator(): - """Testing no unwindng stack on yield for generators + """Testing no unwinding stack on yield for generators for "until" command if target breakpoint is not reached >>> def test_gen(): @@ -2321,7 +2321,7 @@ def test_pdb_until_command_for_generator(): if not SKIP_CORO_TESTS: def test_pdb_until_command_for_coroutine(): - """Testing no unwindng stack for coroutines + """Testing no unwinding stack for coroutines for "until" command if target breakpoint is not reached >>> from test.support import run_yielding_async_fn, async_yield