7
7
8
8
threading_helper .requires_working_threading (module = True )
9
9
10
+
11
+ class MyException (Exception ):
12
+ pass
13
+
14
+
10
15
def tearDownModule ():
11
16
asyncio ._set_event_loop_policy (None )
12
17
@@ -53,6 +58,55 @@ def runner():
53
58
with threading_helper .start_threads (threads ):
54
59
pass
55
60
61
+ def test_run_coroutine_threadsafe (self ) -> None :
62
+ results = []
63
+
64
+ def in_thread (loop : asyncio .AbstractEventLoop ):
65
+ coro = asyncio .sleep (0.1 , result = 42 )
66
+ fut = asyncio .run_coroutine_threadsafe (coro , loop )
67
+ result = fut .result ()
68
+ self .assertEqual (result , 42 )
69
+ results .append (result )
70
+
71
+ async def main ():
72
+ loop = asyncio .get_running_loop ()
73
+ async with asyncio .TaskGroup () as tg :
74
+ for _ in range (10 ):
75
+ tg .create_task (asyncio .to_thread (in_thread , loop ))
76
+ self .assertEqual (results , [42 ] * 10 )
77
+
78
+ with asyncio .Runner () as r :
79
+ loop = r .get_loop ()
80
+ loop .set_task_factory (self .factory )
81
+ r .run (main ())
82
+
83
+ def test_run_coroutine_threadsafe_exception (self ) -> None :
84
+ async def coro ():
85
+ await asyncio .sleep (0 )
86
+ raise MyException ("test" )
87
+
88
+ def in_thread (loop : asyncio .AbstractEventLoop ):
89
+ fut = asyncio .run_coroutine_threadsafe (coro (), loop )
90
+ return fut .result ()
91
+
92
+ async def main ():
93
+ loop = asyncio .get_running_loop ()
94
+ tasks = []
95
+ for _ in range (10 ):
96
+ task = loop .create_task (asyncio .to_thread (in_thread , loop ))
97
+ tasks .append (task )
98
+ results = await asyncio .gather (* tasks , return_exceptions = True )
99
+
100
+ self .assertEqual (len (results ), 10 )
101
+ for result in results :
102
+ self .assertIsInstance (result , MyException )
103
+ self .assertEqual (str (result ), "test" )
104
+
105
+ with asyncio .Runner () as r :
106
+ loop = r .get_loop ()
107
+ loop .set_task_factory (self .factory )
108
+ r .run (main ())
109
+
56
110
57
111
class TestPyFreeThreading (TestFreeThreading , TestCase ):
58
112
all_tasks = staticmethod (asyncio .tasks ._py_all_tasks )
0 commit comments