|
1 | 1 | import asyncio |
| 2 | +import collections.abc |
2 | 3 | import unittest |
3 | 4 | import os |
4 | 5 | import textwrap |
@@ -614,6 +615,54 @@ async def main(): |
614 | 615 | stacks = self._extract_coroutine_funcnames(asyncio.run(main())) |
615 | 616 | self.assertEqual(stacks["consumer"], ["consumer"]) |
616 | 617 |
|
| 618 | + @skip_if_not_supported |
| 619 | + def test_running_task_stack_between_steps(self): |
| 620 | + # gh-159645 |
| 621 | + traces = [] |
| 622 | + |
| 623 | + class Loop(asyncio.SelectorEventLoop): |
| 624 | + def call_soon(self, *args, **kwargs): |
| 625 | + if asyncio.current_task(self) is not None: |
| 626 | + unwinder = RemoteUnwinder(os.getpid()) |
| 627 | + traces.append(unwinder.get_async_stack_trace()) |
| 628 | + return super().call_soon(*args, **kwargs) |
| 629 | + |
| 630 | + async def child(): |
| 631 | + await asyncio.sleep(0) |
| 632 | + |
| 633 | + async def main(): |
| 634 | + await asyncio.create_task(child(), name="child") |
| 635 | + |
| 636 | + asyncio.run(main(), loop_factory=Loop) |
| 637 | + stacks = [list(self._extract_coroutine_funcnames(trace).values()) |
| 638 | + for trace in traces] |
| 639 | + self.assertIn([["sleep", "child"], ["main"]], stacks) |
| 640 | + self.assertIn([[], ["main"]], stacks) |
| 641 | + |
| 642 | + @skip_if_not_supported |
| 643 | + def test_running_task_with_non_native_coroutine(self): |
| 644 | + # gh-159645 |
| 645 | + class Wrapper(collections.abc.Coroutine): |
| 646 | + def __init__(self, coro): |
| 647 | + self._coro = coro |
| 648 | + def send(self, value): |
| 649 | + return self._coro.send(value) |
| 650 | + def throw(self, *args): |
| 651 | + return self._coro.throw(*args) |
| 652 | + def close(self): |
| 653 | + return self._coro.close() |
| 654 | + def __await__(self): |
| 655 | + return self._coro.__await__() |
| 656 | + |
| 657 | + async def inner(): |
| 658 | + return RemoteUnwinder(os.getpid()).get_async_stack_trace() |
| 659 | + |
| 660 | + async def main(): |
| 661 | + return await asyncio.create_task(Wrapper(inner()), name="wrapper") |
| 662 | + |
| 663 | + stacks = self._extract_coroutine_funcnames(asyncio.run(main())) |
| 664 | + self.assertEqual(stacks["wrapper"], []) |
| 665 | + |
617 | 666 | @skip_if_not_supported |
618 | 667 | @unittest.skipIf( |
619 | 668 | sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED, |
|
0 commit comments