Skip to content

gh-110378: Move to IsolatedAsyncTestCase in test_contextlib_async.py #110379

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 8, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 5 additions & 51 deletions Lib/test/test_contextlib_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from contextlib import (
asynccontextmanager, AbstractAsyncContextManager,
AsyncExitStack, nullcontext, aclosing, contextmanager)
import functools
from test import support
import unittest
import traceback
Expand All @@ -11,21 +10,12 @@

support.requires_working_socket(module=True)

def _async_test(func):
"""Decorator to turn an async function into a test case."""
@functools.wraps(func)
def wrapper(*args, **kwargs):
coro = func(*args, **kwargs)
asyncio.run(coro)
return wrapper

def tearDownModule():
asyncio.set_event_loop_policy(None)


class TestAbstractAsyncContextManager(unittest.TestCase):
class TestAbstractAsyncContextManager(unittest.IsolatedAsyncioTestCase):

@_async_test
async def test_enter(self):
class DefaultEnter(AbstractAsyncContextManager):
async def __aexit__(self, *args):
Expand All @@ -37,7 +27,6 @@ async def __aexit__(self, *args):
async with manager as context:
self.assertIs(manager, context)

@_async_test
async def test_slots(self):
class DefaultAsyncContextManager(AbstractAsyncContextManager):
__slots__ = ()
Expand All @@ -49,7 +38,6 @@ async def __aexit__(self, *args):
manager = DefaultAsyncContextManager()
manager.var = 42

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

Expand Down Expand Up @@ -104,9 +92,8 @@ class NoneAexit(ManagerFromScratch):
self.assertFalse(issubclass(NoneAexit, AbstractAsyncContextManager))


class AsyncContextManagerTestCase(unittest.TestCase):
class AsyncContextManagerTestCase(unittest.IsolatedAsyncioTestCase):

@_async_test
async def test_contextmanager_plain(self):
state = []
@asynccontextmanager
Expand All @@ -120,7 +107,6 @@ async def woohoo():
state.append(x)
self.assertEqual(state, [1, 42, 999])

@_async_test
async def test_contextmanager_finally(self):
state = []
@asynccontextmanager
Expand All @@ -138,7 +124,6 @@ async def woohoo():
raise ZeroDivisionError()
self.assertEqual(state, [1, 42, 999])

@_async_test
async def test_contextmanager_traceback(self):
@asynccontextmanager
async def f():
Expand Down Expand Up @@ -194,7 +179,6 @@ class StopAsyncIterationSubclass(StopAsyncIteration):
self.assertEqual(frames[0].name, 'test_contextmanager_traceback')
self.assertEqual(frames[0].line, 'raise stop_exc')

@_async_test
async def test_contextmanager_no_reraise(self):
@asynccontextmanager
async def whee():
Expand All @@ -204,7 +188,6 @@ async def whee():
# Calling __aexit__ should not result in an exception
self.assertFalse(await ctx.__aexit__(TypeError, TypeError("foo"), None))

@_async_test
async def test_contextmanager_trap_yield_after_throw(self):
@asynccontextmanager
async def whoo():
Expand All @@ -217,7 +200,6 @@ async def whoo():
with self.assertRaises(RuntimeError):
await ctx.__aexit__(TypeError, TypeError('foo'), None)

@_async_test
async def test_contextmanager_trap_no_yield(self):
@asynccontextmanager
async def whoo():
Expand All @@ -227,7 +209,6 @@ async def whoo():
with self.assertRaises(RuntimeError):
await ctx.__aenter__()

@_async_test
async def test_contextmanager_trap_second_yield(self):
@asynccontextmanager
async def whoo():
Expand All @@ -238,7 +219,6 @@ async def whoo():
with self.assertRaises(RuntimeError):
await ctx.__aexit__(None, None, None)

@_async_test
async def test_contextmanager_non_normalised(self):
@asynccontextmanager
async def whoo():
Expand All @@ -252,7 +232,6 @@ async def whoo():
with self.assertRaises(SyntaxError):
await ctx.__aexit__(RuntimeError, None, None)

@_async_test
async def test_contextmanager_except(self):
state = []
@asynccontextmanager
Expand All @@ -270,7 +249,6 @@ async def woohoo():
raise ZeroDivisionError(999)
self.assertEqual(state, [1, 42, 999])

@_async_test
async def test_contextmanager_except_stopiter(self):
@asynccontextmanager
async def woohoo():
Expand All @@ -297,7 +275,6 @@ class StopAsyncIterationSubclass(StopAsyncIteration):
else:
self.fail(f'{stop_exc} was suppressed')

@_async_test
async def test_contextmanager_wrap_runtimeerror(self):
@asynccontextmanager
async def woohoo():
Expand Down Expand Up @@ -342,14 +319,12 @@ def test_contextmanager_doc_attrib(self):
self.assertEqual(baz.__doc__, "Whee!")

@support.requires_docstrings
@_async_test
async def test_instance_docstring_given_cm_docstring(self):
baz = self._create_contextmanager_attribs()(None)
self.assertEqual(baz.__doc__, "Whee!")
async with baz:
pass # suppress warning

@_async_test
async def test_keywords(self):
# Ensure no keyword arguments are inhibited
@asynccontextmanager
Expand All @@ -358,7 +333,6 @@ async def woohoo(self, func, args, kwds):
async with woohoo(self=11, func=22, args=33, kwds=44) as target:
self.assertEqual(target, (11, 22, 33, 44))

@_async_test
async def test_recursive(self):
depth = 0
ncols = 0
Expand All @@ -385,7 +359,6 @@ async def recursive():
self.assertEqual(ncols, 10)
self.assertEqual(depth, 0)

@_async_test
async def test_decorator(self):
entered = False

Expand All @@ -404,7 +377,6 @@ async def test():
await test()
self.assertFalse(entered)

@_async_test
async def test_decorator_with_exception(self):
entered = False

Expand All @@ -427,7 +399,6 @@ async def test():
await test()
self.assertFalse(entered)

@_async_test
async def test_decorating_method(self):

@asynccontextmanager
Expand Down Expand Up @@ -462,15 +433,14 @@ async def method(self, a, b, c=None):
self.assertEqual(test.b, 2)


class AclosingTestCase(unittest.TestCase):
class AclosingTestCase(unittest.IsolatedAsyncioTestCase):

@support.requires_docstrings
def test_instance_docs(self):
cm_docstring = aclosing.__doc__
obj = aclosing(None)
self.assertEqual(obj.__doc__, cm_docstring)

@_async_test
async def test_aclosing(self):
state = []
class C:
Expand All @@ -482,7 +452,6 @@ async def aclose(self):
self.assertEqual(x, y)
self.assertEqual(state, [1])

@_async_test
async def test_aclosing_error(self):
state = []
class C:
Expand All @@ -496,7 +465,6 @@ async def aclose(self):
1 / 0
self.assertEqual(state, [1])

@_async_test
async def test_aclosing_bpo41229(self):
state = []

Expand All @@ -522,7 +490,7 @@ async def agenfunc():
self.assertEqual(state, [1])


class TestAsyncExitStack(TestBaseExitStack, unittest.TestCase):
class TestAsyncExitStack(TestBaseExitStack, unittest.IsolatedAsyncioTestCase):
class SyncAsyncExitStack(AsyncExitStack):
@staticmethod
def run_coroutine(coro):
Expand Down Expand Up @@ -561,13 +529,6 @@ def __exit__(self, *exc_details):
('__aexit__', 'cb_suppress = cb(*exc_details)'),
]

def setUp(self):
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.loop)
self.addCleanup(self.loop.close)
self.addCleanup(asyncio.set_event_loop_policy, None)

@_async_test
async def test_async_callback(self):
expected = [
((), {}),
Expand Down Expand Up @@ -610,7 +571,6 @@ async def _exit(*args, **kwds):
stack.push_async_callback(callback=_exit, arg=3)
self.assertEqual(result, [])

@_async_test
async def test_async_push(self):
exc_raised = ZeroDivisionError
async def _expect_exc(exc_type, exc, exc_tb):
Expand Down Expand Up @@ -646,7 +606,6 @@ async def __aexit__(self, *exc_details):
self.assertIs(stack._exit_callbacks[-1][1], _expect_exc)
1/0

@_async_test
async def test_enter_async_context(self):
class TestCM(object):
async def __aenter__(self):
Expand All @@ -668,7 +627,6 @@ async def _exit():

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

@_async_test
async def test_enter_async_context_errors(self):
class LacksEnterAndExit:
pass
Expand All @@ -688,7 +646,6 @@ async def __aenter__(self):
await stack.enter_async_context(LacksExit())
self.assertFalse(stack._exit_callbacks)

@_async_test
async def test_async_exit_exception_chaining(self):
# Ensure exception chaining matches the reference behaviour
async def raise_exc(exc):
Expand Down Expand Up @@ -720,7 +677,6 @@ async def suppress_exc(*exc_details):
self.assertIsInstance(inner_exc, ValueError)
self.assertIsInstance(inner_exc.__context__, ZeroDivisionError)

@_async_test
async def test_async_exit_exception_explicit_none_context(self):
# Ensure AsyncExitStack chaining matches actual nested `with` statements
# regarding explicit __context__ = None.
Expand Down Expand Up @@ -755,7 +711,6 @@ async def my_cm_with_exit_stack():
else:
self.fail("Expected IndexError, but no exception was raised")

@_async_test
async def test_instance_bypass_async(self):
class Example(object): pass
cm = Example()
Expand All @@ -768,8 +723,7 @@ class Example(object): pass
self.assertIs(stack._exit_callbacks[-1][1], cm)


class TestAsyncNullcontext(unittest.TestCase):
@_async_test
class TestAsyncNullcontext(unittest.IsolatedAsyncioTestCase):
async def test_async_nullcontext(self):
class C:
pass
Expand Down