2
2
from contextlib import (
3
3
asynccontextmanager , AbstractAsyncContextManager ,
4
4
AsyncExitStack , nullcontext , aclosing , contextmanager )
5
- import functools
6
5
from test import support
7
6
import unittest
8
7
import traceback
11
10
12
11
support .requires_working_socket (module = True )
13
12
14
- def _async_test (func ):
15
- """Decorator to turn an async function into a test case."""
16
- @functools .wraps (func )
17
- def wrapper (* args , ** kwargs ):
18
- coro = func (* args , ** kwargs )
19
- asyncio .run (coro )
20
- return wrapper
21
-
22
13
def tearDownModule ():
23
14
asyncio .set_event_loop_policy (None )
24
15
25
16
26
- class TestAbstractAsyncContextManager (unittest .TestCase ):
17
+ class TestAbstractAsyncContextManager (unittest .IsolatedAsyncioTestCase ):
27
18
28
- @_async_test
29
19
async def test_enter (self ):
30
20
class DefaultEnter (AbstractAsyncContextManager ):
31
21
async def __aexit__ (self , * args ):
@@ -37,7 +27,6 @@ async def __aexit__(self, *args):
37
27
async with manager as context :
38
28
self .assertIs (manager , context )
39
29
40
- @_async_test
41
30
async def test_slots (self ):
42
31
class DefaultAsyncContextManager (AbstractAsyncContextManager ):
43
32
__slots__ = ()
@@ -49,7 +38,6 @@ async def __aexit__(self, *args):
49
38
manager = DefaultAsyncContextManager ()
50
39
manager .var = 42
51
40
52
- @_async_test
53
41
async def test_async_gen_propagates_generator_exit (self ):
54
42
# A regression test for https://bugs.python.org/issue33786.
55
43
@@ -104,9 +92,8 @@ class NoneAexit(ManagerFromScratch):
104
92
self .assertFalse (issubclass (NoneAexit , AbstractAsyncContextManager ))
105
93
106
94
107
- class AsyncContextManagerTestCase (unittest .TestCase ):
95
+ class AsyncContextManagerTestCase (unittest .IsolatedAsyncioTestCase ):
108
96
109
- @_async_test
110
97
async def test_contextmanager_plain (self ):
111
98
state = []
112
99
@asynccontextmanager
@@ -120,7 +107,6 @@ async def woohoo():
120
107
state .append (x )
121
108
self .assertEqual (state , [1 , 42 , 999 ])
122
109
123
- @_async_test
124
110
async def test_contextmanager_finally (self ):
125
111
state = []
126
112
@asynccontextmanager
@@ -138,7 +124,6 @@ async def woohoo():
138
124
raise ZeroDivisionError ()
139
125
self .assertEqual (state , [1 , 42 , 999 ])
140
126
141
- @_async_test
142
127
async def test_contextmanager_traceback (self ):
143
128
@asynccontextmanager
144
129
async def f ():
@@ -194,7 +179,6 @@ class StopAsyncIterationSubclass(StopAsyncIteration):
194
179
self .assertEqual (frames [0 ].name , 'test_contextmanager_traceback' )
195
180
self .assertEqual (frames [0 ].line , 'raise stop_exc' )
196
181
197
- @_async_test
198
182
async def test_contextmanager_no_reraise (self ):
199
183
@asynccontextmanager
200
184
async def whee ():
@@ -204,7 +188,6 @@ async def whee():
204
188
# Calling __aexit__ should not result in an exception
205
189
self .assertFalse (await ctx .__aexit__ (TypeError , TypeError ("foo" ), None ))
206
190
207
- @_async_test
208
191
async def test_contextmanager_trap_yield_after_throw (self ):
209
192
@asynccontextmanager
210
193
async def whoo ():
@@ -217,7 +200,6 @@ async def whoo():
217
200
with self .assertRaises (RuntimeError ):
218
201
await ctx .__aexit__ (TypeError , TypeError ('foo' ), None )
219
202
220
- @_async_test
221
203
async def test_contextmanager_trap_no_yield (self ):
222
204
@asynccontextmanager
223
205
async def whoo ():
@@ -227,7 +209,6 @@ async def whoo():
227
209
with self .assertRaises (RuntimeError ):
228
210
await ctx .__aenter__ ()
229
211
230
- @_async_test
231
212
async def test_contextmanager_trap_second_yield (self ):
232
213
@asynccontextmanager
233
214
async def whoo ():
@@ -238,7 +219,6 @@ async def whoo():
238
219
with self .assertRaises (RuntimeError ):
239
220
await ctx .__aexit__ (None , None , None )
240
221
241
- @_async_test
242
222
async def test_contextmanager_non_normalised (self ):
243
223
@asynccontextmanager
244
224
async def whoo ():
@@ -252,7 +232,6 @@ async def whoo():
252
232
with self .assertRaises (SyntaxError ):
253
233
await ctx .__aexit__ (RuntimeError , None , None )
254
234
255
- @_async_test
256
235
async def test_contextmanager_except (self ):
257
236
state = []
258
237
@asynccontextmanager
@@ -270,7 +249,6 @@ async def woohoo():
270
249
raise ZeroDivisionError (999 )
271
250
self .assertEqual (state , [1 , 42 , 999 ])
272
251
273
- @_async_test
274
252
async def test_contextmanager_except_stopiter (self ):
275
253
@asynccontextmanager
276
254
async def woohoo ():
@@ -297,7 +275,6 @@ class StopAsyncIterationSubclass(StopAsyncIteration):
297
275
else :
298
276
self .fail (f'{ stop_exc } was suppressed' )
299
277
300
- @_async_test
301
278
async def test_contextmanager_wrap_runtimeerror (self ):
302
279
@asynccontextmanager
303
280
async def woohoo ():
@@ -342,14 +319,12 @@ def test_contextmanager_doc_attrib(self):
342
319
self .assertEqual (baz .__doc__ , "Whee!" )
343
320
344
321
@support .requires_docstrings
345
- @_async_test
346
322
async def test_instance_docstring_given_cm_docstring (self ):
347
323
baz = self ._create_contextmanager_attribs ()(None )
348
324
self .assertEqual (baz .__doc__ , "Whee!" )
349
325
async with baz :
350
326
pass # suppress warning
351
327
352
- @_async_test
353
328
async def test_keywords (self ):
354
329
# Ensure no keyword arguments are inhibited
355
330
@asynccontextmanager
@@ -358,7 +333,6 @@ async def woohoo(self, func, args, kwds):
358
333
async with woohoo (self = 11 , func = 22 , args = 33 , kwds = 44 ) as target :
359
334
self .assertEqual (target , (11 , 22 , 33 , 44 ))
360
335
361
- @_async_test
362
336
async def test_recursive (self ):
363
337
depth = 0
364
338
ncols = 0
@@ -385,7 +359,6 @@ async def recursive():
385
359
self .assertEqual (ncols , 10 )
386
360
self .assertEqual (depth , 0 )
387
361
388
- @_async_test
389
362
async def test_decorator (self ):
390
363
entered = False
391
364
@@ -404,7 +377,6 @@ async def test():
404
377
await test ()
405
378
self .assertFalse (entered )
406
379
407
- @_async_test
408
380
async def test_decorator_with_exception (self ):
409
381
entered = False
410
382
@@ -427,7 +399,6 @@ async def test():
427
399
await test ()
428
400
self .assertFalse (entered )
429
401
430
- @_async_test
431
402
async def test_decorating_method (self ):
432
403
433
404
@asynccontextmanager
@@ -462,15 +433,14 @@ async def method(self, a, b, c=None):
462
433
self .assertEqual (test .b , 2 )
463
434
464
435
465
- class AclosingTestCase (unittest .TestCase ):
436
+ class AclosingTestCase (unittest .IsolatedAsyncioTestCase ):
466
437
467
438
@support .requires_docstrings
468
439
def test_instance_docs (self ):
469
440
cm_docstring = aclosing .__doc__
470
441
obj = aclosing (None )
471
442
self .assertEqual (obj .__doc__ , cm_docstring )
472
443
473
- @_async_test
474
444
async def test_aclosing (self ):
475
445
state = []
476
446
class C :
@@ -482,7 +452,6 @@ async def aclose(self):
482
452
self .assertEqual (x , y )
483
453
self .assertEqual (state , [1 ])
484
454
485
- @_async_test
486
455
async def test_aclosing_error (self ):
487
456
state = []
488
457
class C :
@@ -496,7 +465,6 @@ async def aclose(self):
496
465
1 / 0
497
466
self .assertEqual (state , [1 ])
498
467
499
- @_async_test
500
468
async def test_aclosing_bpo41229 (self ):
501
469
state = []
502
470
@@ -522,7 +490,7 @@ async def agenfunc():
522
490
self .assertEqual (state , [1 ])
523
491
524
492
525
- class TestAsyncExitStack (TestBaseExitStack , unittest .TestCase ):
493
+ class TestAsyncExitStack (TestBaseExitStack , unittest .IsolatedAsyncioTestCase ):
526
494
class SyncAsyncExitStack (AsyncExitStack ):
527
495
@staticmethod
528
496
def run_coroutine (coro ):
@@ -561,13 +529,6 @@ def __exit__(self, *exc_details):
561
529
('__aexit__' , 'cb_suppress = cb(*exc_details)' ),
562
530
]
563
531
564
- def setUp (self ):
565
- self .loop = asyncio .new_event_loop ()
566
- asyncio .set_event_loop (self .loop )
567
- self .addCleanup (self .loop .close )
568
- self .addCleanup (asyncio .set_event_loop_policy , None )
569
-
570
- @_async_test
571
532
async def test_async_callback (self ):
572
533
expected = [
573
534
((), {}),
@@ -610,7 +571,6 @@ async def _exit(*args, **kwds):
610
571
stack .push_async_callback (callback = _exit , arg = 3 )
611
572
self .assertEqual (result , [])
612
573
613
- @_async_test
614
574
async def test_async_push (self ):
615
575
exc_raised = ZeroDivisionError
616
576
async def _expect_exc (exc_type , exc , exc_tb ):
@@ -646,7 +606,6 @@ async def __aexit__(self, *exc_details):
646
606
self .assertIs (stack ._exit_callbacks [- 1 ][1 ], _expect_exc )
647
607
1 / 0
648
608
649
- @_async_test
650
609
async def test_enter_async_context (self ):
651
610
class TestCM (object ):
652
611
async def __aenter__ (self ):
@@ -668,7 +627,6 @@ async def _exit():
668
627
669
628
self .assertEqual (result , [1 , 2 , 3 , 4 ])
670
629
671
- @_async_test
672
630
async def test_enter_async_context_errors (self ):
673
631
class LacksEnterAndExit :
674
632
pass
@@ -688,7 +646,6 @@ async def __aenter__(self):
688
646
await stack .enter_async_context (LacksExit ())
689
647
self .assertFalse (stack ._exit_callbacks )
690
648
691
- @_async_test
692
649
async def test_async_exit_exception_chaining (self ):
693
650
# Ensure exception chaining matches the reference behaviour
694
651
async def raise_exc (exc ):
@@ -720,7 +677,6 @@ async def suppress_exc(*exc_details):
720
677
self .assertIsInstance (inner_exc , ValueError )
721
678
self .assertIsInstance (inner_exc .__context__ , ZeroDivisionError )
722
679
723
- @_async_test
724
680
async def test_async_exit_exception_explicit_none_context (self ):
725
681
# Ensure AsyncExitStack chaining matches actual nested `with` statements
726
682
# regarding explicit __context__ = None.
@@ -755,7 +711,6 @@ async def my_cm_with_exit_stack():
755
711
else :
756
712
self .fail ("Expected IndexError, but no exception was raised" )
757
713
758
- @_async_test
759
714
async def test_instance_bypass_async (self ):
760
715
class Example (object ): pass
761
716
cm = Example ()
@@ -768,8 +723,7 @@ class Example(object): pass
768
723
self .assertIs (stack ._exit_callbacks [- 1 ][1 ], cm )
769
724
770
725
771
- class TestAsyncNullcontext (unittest .TestCase ):
772
- @_async_test
726
+ class TestAsyncNullcontext (unittest .IsolatedAsyncioTestCase ):
773
727
async def test_async_nullcontext (self ):
774
728
class C :
775
729
pass
0 commit comments