2
2
3
3
import asyncio
4
4
import contextlib
5
- import contextvars
6
5
import queue
7
6
import signal
8
7
import socket
11
10
import time
12
11
import traceback
13
12
import warnings
13
+ import weakref
14
14
from collections .abc import AsyncGenerator , Awaitable , Callable , Sequence
15
15
from functools import partial
16
16
from math import inf
22
22
)
23
23
24
24
import pytest
25
+ import sniffio
25
26
from outcome import Outcome
26
27
27
28
import trio
@@ -234,7 +235,8 @@ async def trio_main(in_host: InHost) -> str:
234
235
235
236
236
237
def test_guest_mode_sniffio_integration () -> None :
237
- from sniffio import current_async_library , thread_local as sniffio_library
238
+ current_async_library = sniffio .current_async_library
239
+ sniffio_library = sniffio .thread_local
238
240
239
241
async def trio_main (in_host : InHost ) -> str :
240
242
async def synchronize () -> None :
@@ -458,9 +460,9 @@ def aiotrio_run(
458
460
459
461
async def aio_main () -> T :
460
462
nonlocal run_sync_soon_not_threadsafe
461
- trio_done_fut = loop .create_future ()
463
+ trio_done_fut : asyncio . Future [ Outcome [ T ]] = loop .create_future ()
462
464
463
- def trio_done_callback (main_outcome : Outcome [object ]) -> None :
465
+ def trio_done_callback (main_outcome : Outcome [T ]) -> None :
464
466
print (f"trio_fn finished: { main_outcome !r} " )
465
467
trio_done_fut .set_result (main_outcome )
466
468
@@ -479,9 +481,11 @@ def trio_done_callback(main_outcome: Outcome[object]) -> None:
479
481
strict_exception_groups = strict_exception_groups ,
480
482
)
481
483
482
- return (await trio_done_fut ).unwrap () # type: ignore[no-any-return]
484
+ return (await trio_done_fut ).unwrap ()
483
485
484
486
try :
487
+ # can't use asyncio.run because that fails on Windows (3.8, x64, with
488
+ # Komodia LSP) and segfaults on Windows (3.9, x64, with Komodia LSP)
485
489
return loop .run_until_complete (aio_main ())
486
490
finally :
487
491
loop .close ()
@@ -655,8 +659,6 @@ async def trio_main(in_host: InHost) -> None:
655
659
656
660
@restore_unraisablehook ()
657
661
def test_guest_mode_asyncgens () -> None :
658
- import sniffio
659
-
660
662
record = set ()
661
663
662
664
async def agen (label : str ) -> AsyncGenerator [int , None ]:
@@ -683,9 +685,49 @@ async def trio_main() -> None:
683
685
684
686
gc_collect_harder ()
685
687
686
- # Ensure we don't pollute the thread-level context if run under
687
- # an asyncio without contextvars support (3.6)
688
- context = contextvars .copy_context ()
689
- context .run (aiotrio_run , trio_main , host_uses_signal_set_wakeup_fd = True )
688
+ aiotrio_run (trio_main , host_uses_signal_set_wakeup_fd = True )
690
689
691
690
assert record == {("asyncio" , "asyncio" ), ("trio" , "trio" )}
691
+
692
+
693
+ @restore_unraisablehook ()
694
+ def test_guest_mode_asyncgens_garbage_collection () -> None :
695
+ record : set [tuple [str , str , bool ]] = set ()
696
+
697
+ async def agen (label : str ) -> AsyncGenerator [int , None ]:
698
+ class A :
699
+ pass
700
+
701
+ a = A ()
702
+ a_wr = weakref .ref (a )
703
+ assert sniffio .current_async_library () == label
704
+ try :
705
+ yield 1
706
+ finally :
707
+ library = sniffio .current_async_library ()
708
+ with contextlib .suppress (trio .Cancelled ):
709
+ await sys .modules [library ].sleep (0 )
710
+
711
+ del a
712
+ if sys .implementation .name == "pypy" :
713
+ gc_collect_harder ()
714
+
715
+ record .add ((label , library , a_wr () is None ))
716
+
717
+ async def iterate_in_aio () -> None :
718
+ await agen ("asyncio" ).asend (None )
719
+
720
+ async def trio_main () -> None :
721
+ task = asyncio .ensure_future (iterate_in_aio ())
722
+ done_evt = trio .Event ()
723
+ task .add_done_callback (lambda _ : done_evt .set ())
724
+ with trio .fail_after (1 ):
725
+ await done_evt .wait ()
726
+
727
+ await agen ("trio" ).asend (None )
728
+
729
+ gc_collect_harder ()
730
+
731
+ aiotrio_run (trio_main , host_uses_signal_set_wakeup_fd = True )
732
+
733
+ assert record == {("asyncio" , "asyncio" , True ), ("trio" , "trio" , True )}
0 commit comments