diff options
author | Thomas Grainger <tagrain@gmail.com> | 2024-12-28 14:59:49 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-28 14:59:49 (GMT) |
commit | aab51c3414bc815c4c31e8ef2a9003f4a546faa9 (patch) | |
tree | 65dde154dbc0c7a6765904d25bd3c70db5368c04 /Lib | |
parent | aeb9b65aa26444529e4adc7d6e5b0d3dd9889ec2 (diff) | |
download | cpython-aab51c3414bc815c4c31e8ef2a9003f4a546faa9.zip cpython-aab51c3414bc815c4c31e8ef2a9003f4a546faa9.tar.gz cpython-aab51c3414bc815c4c31e8ef2a9003f4a546faa9.tar.bz2 |
gh-128265: Support WASI/Emscripten on PDB tests, by removing asyncio from pdb tests (#128264)
A part of `Lib/test/test_pdb.py` was previously unable to run on WASI/Emscripten
platforms because it lacked support for `asyncio`.
In fact, these tests could be rewritten without the `asyncio` framework because
`test_pdb` tests the behavior of coroutines, which are not part of `asyncio`.
Now reliance on the availability of `asyncio` has been removed and
part of `test_pdb` that deals with coroutines working on WASI/Emscripten platforms.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/support/__init__.py | 29 | ||||
-rw-r--r-- | Lib/test/test_contextlib_async.py | 15 | ||||
-rw-r--r-- | Lib/test/test_inspect/test_inspect.py | 15 | ||||
-rw-r--r-- | Lib/test/test_pdb.py | 71 |
4 files changed, 70 insertions, 60 deletions
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 5c738ff..cf3077f 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -62,6 +62,7 @@ __all__ = [ "force_not_colorized", "BrokenIter", "in_systemd_nspawn_sync_suppressed", + "run_no_yield_async_fn", "run_yielding_async_fn", "async_yield", ] @@ -2940,3 +2941,31 @@ def in_systemd_nspawn_sync_suppressed() -> bool: os.close(fd) return False + +def run_no_yield_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_yielding_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 d496aa6..7750186 100644 --- a/Lib/test/test_contextlib_async.py +++ b/Lib/test/test_contextlib_async.py @@ -3,24 +3,13 @@ from contextlib import ( asynccontextmanager, AbstractAsyncContextManager, AsyncExitStack, nullcontext, aclosing, contextmanager) from test import support +from test.support import run_no_yield_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 @@ class TestAsyncExitStack(TestBaseExitStack, unittest.TestCase): exit_stack = SyncAsyncExitStack callback_error_internal_frames = [ ('__exit__', 'return _run_async_fn(self.__aexit__, *exc_details)'), - ('_run_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 d536d04..345a57a 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -36,6 +36,7 @@ except ImportError: from test.support import cpython_only, import_helper from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ +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 @@ -1161,19 +1162,11 @@ class TestBuggyCases(GetSourceBase): 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() + run = run_no_yield_async_fn - 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 9b0806d..c5ee8c5 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -20,8 +20,7 @@ from test.support.import_helper import import_module 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): @@ -1987,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 @@ -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 + """Testing skip unwinding stack on yield for coroutines for "next" command - >>> import asyncio + >>> from test.support import run_yielding_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_yielding_async_fn(test_main) ... print("finished") >>> with PdbTestInput(['step', @@ -2088,13 +2087,13 @@ if not SKIP_ASYNCIO_TESTS: -> async def test_coro(): (Pdb) step > <doctest test.test_pdb.test_pdb_next_command_for_coroutine[1]>(2)test_coro() - -> await asyncio.sleep(0) + -> await async_yield(0) (Pdb) next > <doctest test.test_pdb.test_pdb_next_command_for_coroutine[1]>(3)test_coro() - -> await asyncio.sleep(0) + -> await async_yield(0) (Pdb) next > <doctest test.test_pdb.test_pdb_next_command_for_coroutine[1]>(4)test_coro() - -> await asyncio.sleep(0) + -> await async_yield(0) (Pdb) next Internal StopIteration > <doctest test.test_pdb.test_pdb_next_command_for_coroutine[2]>(3)test_main() @@ -2108,13 +2107,13 @@ if not SKIP_ASYNCIO_TESTS: """ 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 - >>> import asyncio + >>> from test.support import run_yielding_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 @@ if not SKIP_ASYNCIO_TESTS: ... await test_coro() >>> def test_function(): - ... asyncio.run(test_main()) + ... run_yielding_async_fn(test_main) ... print("finished") >>> with PdbTestInput(['step', @@ -2163,14 +2162,14 @@ if not SKIP_ASYNCIO_TESTS: -> yield 1 (Pdb) next > <doctest test.test_pdb.test_pdb_next_command_for_asyncgen[1]>(3)agen() - -> await asyncio.sleep(0) + -> await async_yield(0) (Pdb) continue 2 finished """ 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(): @@ -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 + """Testing no unwinding stack on yield for coroutines for "return" command - >>> import asyncio + >>> from test.support import run_yielding_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_yielding_async_fn(test_main) ... print("finished") >>> with PdbTestInput(['step', @@ -2264,16 +2263,16 @@ if not SKIP_ASYNCIO_TESTS: -> async def test_coro(): (Pdb) step > <doctest test.test_pdb.test_pdb_return_command_for_coroutine[1]>(2)test_coro() - -> await asyncio.sleep(0) + -> await async_yield(0) (Pdb) next > <doctest test.test_pdb.test_pdb_return_command_for_coroutine[1]>(3)test_coro() - -> await asyncio.sleep(0) + -> await async_yield(0) (Pdb) continue finished """ 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(): @@ -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 + """Testing no unwinding stack for coroutines for "until" command if target breakpoint is not reached - >>> import asyncio + >>> from test.support import run_yielding_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 @@ if not SKIP_ASYNCIO_TESTS: ... await test_coro() >>> def test_function(): - ... asyncio.run(test_main()) + ... run_yielding_async_fn(test_main) ... print("finished") >>> with PdbTestInput(['step', |