Skip to content

Commit cb0cffb

Browse files
authored
Update test_contextlib_async.py to 3.14.4 (#7816)
1 parent cc829b2 commit cb0cffb

1 file changed

Lines changed: 55 additions & 39 deletions

File tree

Lib/test/test_contextlib_async.py

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
1-
import asyncio
1+
import functools
22
from contextlib import (
33
asynccontextmanager, AbstractAsyncContextManager,
44
AsyncExitStack, nullcontext, aclosing, contextmanager)
55
from test import support
6+
from test.support import run_no_yield_async_fn as _run_async_fn
67
import unittest
78
import traceback
89

910
from test.test_contextlib import TestBaseExitStack
1011

11-
support.requires_working_socket(module=True)
1212

13-
def tearDownModule():
14-
asyncio.set_event_loop_policy(None)
13+
def _async_test(async_fn):
14+
"""Decorator to turn an async function into a synchronous function"""
15+
@functools.wraps(async_fn)
16+
def wrapper(*args, **kwargs):
17+
return _run_async_fn(async_fn, *args, **kwargs)
1518

19+
return wrapper
1620

17-
class TestAbstractAsyncContextManager(unittest.IsolatedAsyncioTestCase):
1821

22+
class TestAbstractAsyncContextManager(unittest.TestCase):
23+
24+
@_async_test
1925
async def test_enter(self):
2026
class DefaultEnter(AbstractAsyncContextManager):
2127
async def __aexit__(self, *args):
@@ -27,6 +33,7 @@ async def __aexit__(self, *args):
2733
async with manager as context:
2834
self.assertIs(manager, context)
2935

36+
@_async_test
3037
async def test_slots(self):
3138
class DefaultAsyncContextManager(AbstractAsyncContextManager):
3239
__slots__ = ()
@@ -38,6 +45,7 @@ async def __aexit__(self, *args):
3845
manager = DefaultAsyncContextManager()
3946
manager.var = 42
4047

48+
@_async_test
4149
async def test_async_gen_propagates_generator_exit(self):
4250
# A regression test for https://bugs.python.org/issue33786.
4351

@@ -69,27 +77,28 @@ async def __aenter__(self):
6977
async def __aexit__(self, exc_type, exc_value, traceback):
7078
return None
7179

72-
self.assertTrue(issubclass(ManagerFromScratch, AbstractAsyncContextManager))
80+
self.assertIsSubclass(ManagerFromScratch, AbstractAsyncContextManager)
7381

7482
class DefaultEnter(AbstractAsyncContextManager):
7583
async def __aexit__(self, *args):
7684
await super().__aexit__(*args)
7785

78-
self.assertTrue(issubclass(DefaultEnter, AbstractAsyncContextManager))
86+
self.assertIsSubclass(DefaultEnter, AbstractAsyncContextManager)
7987

8088
class NoneAenter(ManagerFromScratch):
8189
__aenter__ = None
8290

83-
self.assertFalse(issubclass(NoneAenter, AbstractAsyncContextManager))
91+
self.assertNotIsSubclass(NoneAenter, AbstractAsyncContextManager)
8492

8593
class NoneAexit(ManagerFromScratch):
8694
__aexit__ = None
8795

88-
self.assertFalse(issubclass(NoneAexit, AbstractAsyncContextManager))
96+
self.assertNotIsSubclass(NoneAexit, AbstractAsyncContextManager)
8997

9098

91-
class AsyncContextManagerTestCase(unittest.IsolatedAsyncioTestCase):
99+
class AsyncContextManagerTestCase(unittest.TestCase):
92100

101+
@_async_test
93102
async def test_contextmanager_plain(self):
94103
state = []
95104
@asynccontextmanager
@@ -103,6 +112,7 @@ async def woohoo():
103112
state.append(x)
104113
self.assertEqual(state, [1, 42, 999])
105114

115+
@_async_test
106116
async def test_contextmanager_finally(self):
107117
state = []
108118
@asynccontextmanager
@@ -120,7 +130,8 @@ async def woohoo():
120130
raise ZeroDivisionError()
121131
self.assertEqual(state, [1, 42, 999])
122132

123-
@unittest.expectedFailure # TODO: RUSTPYTHON
133+
@unittest.expectedFailure # TODO: RUSTPYTHON
134+
@_async_test
124135
async def test_contextmanager_traceback(self):
125136
@asynccontextmanager
126137
async def f():
@@ -176,6 +187,7 @@ class StopAsyncIterationSubclass(StopAsyncIteration):
176187
self.assertEqual(frames[0].name, 'test_contextmanager_traceback')
177188
self.assertEqual(frames[0].line, 'raise stop_exc')
178189

190+
@_async_test
179191
async def test_contextmanager_no_reraise(self):
180192
@asynccontextmanager
181193
async def whee():
@@ -185,6 +197,7 @@ async def whee():
185197
# Calling __aexit__ should not result in an exception
186198
self.assertFalse(await ctx.__aexit__(TypeError, TypeError("foo"), None))
187199

200+
@_async_test
188201
async def test_contextmanager_trap_yield_after_throw(self):
189202
@asynccontextmanager
190203
async def whoo():
@@ -200,6 +213,7 @@ async def whoo():
200213
# The "gen" attribute is an implementation detail.
201214
self.assertFalse(ctx.gen.ag_suspended)
202215

216+
@_async_test
203217
async def test_contextmanager_trap_no_yield(self):
204218
@asynccontextmanager
205219
async def whoo():
@@ -209,6 +223,7 @@ async def whoo():
209223
with self.assertRaises(RuntimeError):
210224
await ctx.__aenter__()
211225

226+
@_async_test
212227
async def test_contextmanager_trap_second_yield(self):
213228
@asynccontextmanager
214229
async def whoo():
@@ -222,6 +237,7 @@ async def whoo():
222237
# The "gen" attribute is an implementation detail.
223238
self.assertFalse(ctx.gen.ag_suspended)
224239

240+
@_async_test
225241
async def test_contextmanager_non_normalised(self):
226242
@asynccontextmanager
227243
async def whoo():
@@ -235,6 +251,7 @@ async def whoo():
235251
with self.assertRaises(SyntaxError):
236252
await ctx.__aexit__(RuntimeError, None, None)
237253

254+
@_async_test
238255
async def test_contextmanager_except(self):
239256
state = []
240257
@asynccontextmanager
@@ -252,6 +269,7 @@ async def woohoo():
252269
raise ZeroDivisionError(999)
253270
self.assertEqual(state, [1, 42, 999])
254271

272+
@_async_test
255273
async def test_contextmanager_except_stopiter(self):
256274
@asynccontextmanager
257275
async def woohoo():
@@ -278,6 +296,7 @@ class StopAsyncIterationSubclass(StopAsyncIteration):
278296
else:
279297
self.fail(f'{stop_exc} was suppressed')
280298

299+
@_async_test
281300
async def test_contextmanager_wrap_runtimeerror(self):
282301
@asynccontextmanager
283302
async def woohoo():
@@ -322,12 +341,14 @@ def test_contextmanager_doc_attrib(self):
322341
self.assertEqual(baz.__doc__, "Whee!")
323342

324343
@support.requires_docstrings
344+
@_async_test
325345
async def test_instance_docstring_given_cm_docstring(self):
326346
baz = self._create_contextmanager_attribs()(None)
327347
self.assertEqual(baz.__doc__, "Whee!")
328348
async with baz:
329349
pass # suppress warning
330350

351+
@_async_test
331352
async def test_keywords(self):
332353
# Ensure no keyword arguments are inhibited
333354
@asynccontextmanager
@@ -336,6 +357,7 @@ async def woohoo(self, func, args, kwds):
336357
async with woohoo(self=11, func=22, args=33, kwds=44) as target:
337358
self.assertEqual(target, (11, 22, 33, 44))
338359

360+
@_async_test
339361
async def test_recursive(self):
340362
depth = 0
341363
ncols = 0
@@ -362,6 +384,7 @@ async def recursive():
362384
self.assertEqual(ncols, 10)
363385
self.assertEqual(depth, 0)
364386

387+
@_async_test
365388
async def test_decorator(self):
366389
entered = False
367390

@@ -380,6 +403,7 @@ async def test():
380403
await test()
381404
self.assertFalse(entered)
382405

406+
@_async_test
383407
async def test_decorator_with_exception(self):
384408
entered = False
385409

@@ -402,6 +426,7 @@ async def test():
402426
await test()
403427
self.assertFalse(entered)
404428

429+
@_async_test
405430
async def test_decorating_method(self):
406431

407432
@asynccontextmanager
@@ -436,14 +461,15 @@ async def method(self, a, b, c=None):
436461
self.assertEqual(test.b, 2)
437462

438463

439-
class AclosingTestCase(unittest.IsolatedAsyncioTestCase):
464+
class AclosingTestCase(unittest.TestCase):
440465

441466
@support.requires_docstrings
442467
def test_instance_docs(self):
443468
cm_docstring = aclosing.__doc__
444469
obj = aclosing(None)
445470
self.assertEqual(obj.__doc__, cm_docstring)
446471

472+
@_async_test
447473
async def test_aclosing(self):
448474
state = []
449475
class C:
@@ -455,6 +481,7 @@ async def aclose(self):
455481
self.assertEqual(x, y)
456482
self.assertEqual(state, [1])
457483

484+
@_async_test
458485
async def test_aclosing_error(self):
459486
state = []
460487
class C:
@@ -468,6 +495,7 @@ async def aclose(self):
468495
1 / 0
469496
self.assertEqual(state, [1])
470497

498+
@_async_test
471499
async def test_aclosing_bpo41229(self):
472500
state = []
473501

@@ -493,45 +521,27 @@ async def agenfunc():
493521
self.assertEqual(state, [1])
494522

495523

496-
class TestAsyncExitStack(TestBaseExitStack, unittest.IsolatedAsyncioTestCase):
524+
class TestAsyncExitStack(TestBaseExitStack, unittest.TestCase):
497525
class SyncAsyncExitStack(AsyncExitStack):
498-
@staticmethod
499-
def run_coroutine(coro):
500-
loop = asyncio.get_event_loop_policy().get_event_loop()
501-
t = loop.create_task(coro)
502-
t.add_done_callback(lambda f: loop.stop())
503-
loop.run_forever()
504-
505-
exc = t.exception()
506-
if not exc:
507-
return t.result()
508-
else:
509-
context = exc.__context__
510-
511-
try:
512-
raise exc
513-
except:
514-
exc.__context__ = context
515-
raise exc
516526

517527
def close(self):
518-
return self.run_coroutine(self.aclose())
528+
return _run_async_fn(self.aclose)
519529

520530
def __enter__(self):
521-
return self.run_coroutine(self.__aenter__())
531+
return _run_async_fn(self.__aenter__)
522532

523533
def __exit__(self, *exc_details):
524-
return self.run_coroutine(self.__aexit__(*exc_details))
534+
return _run_async_fn(self.__aexit__, *exc_details)
525535

526536
exit_stack = SyncAsyncExitStack
527537
callback_error_internal_frames = [
528-
('__exit__', 'return self.run_coroutine(self.__aexit__(*exc_details))'),
529-
('run_coroutine', 'raise exc'),
530-
('run_coroutine', 'raise exc'),
538+
('__exit__', 'return _run_async_fn(self.__aexit__, *exc_details)'),
539+
('run_no_yield_async_fn', 'coro.send(None)'),
531540
('__aexit__', 'raise exc'),
532541
('__aexit__', 'cb_suppress = cb(*exc_details)'),
533542
]
534543

544+
@_async_test
535545
async def test_async_callback(self):
536546
expected = [
537547
((), {}),
@@ -574,6 +584,7 @@ async def _exit(*args, **kwds):
574584
stack.push_async_callback(callback=_exit, arg=3)
575585
self.assertEqual(result, [])
576586

587+
@_async_test
577588
async def test_async_push(self):
578589
exc_raised = ZeroDivisionError
579590
async def _expect_exc(exc_type, exc, exc_tb):
@@ -609,6 +620,7 @@ async def __aexit__(self, *exc_details):
609620
self.assertIs(stack._exit_callbacks[-1][1], _expect_exc)
610621
1/0
611622

623+
@_async_test
612624
async def test_enter_async_context(self):
613625
class TestCM(object):
614626
async def __aenter__(self):
@@ -630,6 +642,7 @@ async def _exit():
630642

631643
self.assertEqual(result, [1, 2, 3, 4])
632644

645+
@_async_test
633646
async def test_enter_async_context_errors(self):
634647
class LacksEnterAndExit:
635648
pass
@@ -649,6 +662,7 @@ async def __aenter__(self):
649662
await stack.enter_async_context(LacksExit())
650663
self.assertFalse(stack._exit_callbacks)
651664

665+
@_async_test
652666
async def test_async_exit_exception_chaining(self):
653667
# Ensure exception chaining matches the reference behaviour
654668
async def raise_exc(exc):
@@ -680,6 +694,7 @@ async def suppress_exc(*exc_details):
680694
self.assertIsInstance(inner_exc, ValueError)
681695
self.assertIsInstance(inner_exc.__context__, ZeroDivisionError)
682696

697+
@_async_test
683698
async def test_async_exit_exception_explicit_none_context(self):
684699
# Ensure AsyncExitStack chaining matches actual nested `with` statements
685700
# regarding explicit __context__ = None.
@@ -714,6 +729,7 @@ async def my_cm_with_exit_stack():
714729
else:
715730
self.fail("Expected IndexError, but no exception was raised")
716731

732+
@_async_test
717733
async def test_instance_bypass_async(self):
718734
class Example(object): pass
719735
cm = Example()
@@ -726,8 +742,8 @@ class Example(object): pass
726742
self.assertIs(stack._exit_callbacks[-1][1], cm)
727743

728744

729-
730-
class TestAsyncNullcontext(unittest.IsolatedAsyncioTestCase):
745+
class TestAsyncNullcontext(unittest.TestCase):
746+
@_async_test
731747
async def test_async_nullcontext(self):
732748
class C:
733749
pass

0 commit comments

Comments
 (0)