self._test_generator = None # type: Optional[Union[Generator, Coroutine]]
def setUp(self) -> None:
- setup_with_context_manager(self, warnings.catch_warnings())
- warnings.filterwarnings(
- "ignore",
- message="There is no current event loop",
- category=DeprecationWarning,
- module=r"tornado\..*",
- )
super().setUp()
- # NOTE: this code attempts to navigate deprecation warnings introduced
- # in Python 3.10. The idea of an implicit current event loop is
- # deprecated in that version, with the intention that tests like this
- # explicitly create a new event loop and run on it. However, other
- # packages such as pytest-asyncio (as of version 0.16.0) still rely on
- # the implicit current event loop and we want to be compatible with them
- # (even when run on 3.10, but not, of course, on the future version of
- # python that removes the get/set_event_loop methods completely).
- #
- # Deprecation warnings were introduced inconsistently:
- # asyncio.get_event_loop warns, but
- # asyncio.get_event_loop_policy().get_event_loop does not. Similarly,
- # none of the set_event_loop methods warn, although comments on
- # https://bugs.python.org/issue39529 indicate that they are also
- # intended for future removal.
- #
- # Therefore, we first attempt to access the event loop with the
- # (non-warning) policy method, and if it fails, fall back to creating a
- # new event loop. We do not have effective test coverage of the
- # new event loop case; this will have to be watched when/if
- # get_event_loop is actually removed.
- self.should_close_asyncio_loop = False
- try:
- self.asyncio_loop = asyncio.get_event_loop_policy().get_event_loop()
- except Exception:
- self.asyncio_loop = asyncio.new_event_loop()
- self.should_close_asyncio_loop = True
-
- async def get_loop() -> IOLoop:
- return self.get_new_ioloop()
-
- self.io_loop = self.asyncio_loop.run_until_complete(get_loop())
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- self.io_loop.make_current()
+ self.io_loop = self.get_new_ioloop()
+ self.io_loop.make_current()
def tearDown(self) -> None:
# Native coroutines tend to produce warnings if they're not
# Clean up Subprocess, so it can be used again with a new ioloop.
Subprocess.uninitialize()
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- self.io_loop.clear_current()
+ self.io_loop.clear_current()
if not isinstance(self.io_loop, _NON_OWNED_IOLOOPS):
# Try to clean up any file descriptors left open in the ioloop.
# This avoids leaks, especially when tests are run repeatedly
# in the same process with autoreload (because curl does not
# set FD_CLOEXEC on its file descriptors)
self.io_loop.close(all_fds=True)
- if self.should_close_asyncio_loop:
- self.asyncio_loop.close()
super().tearDown()
# In case an exception escaped or the StackContext caught an exception
# when there wasn't a wait() to re-raise it, do so here.