diff options
author | Yury Selivanov <yury@magic.io> | 2017-12-13 14:49:42 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-13 14:49:42 -0500 |
commit | a70232f28882d2fecb3ebe06643867701016070f (patch) | |
tree | e037779085e42db44777bc841648ea37391faeab /Lib/test | |
parent | d5dda98fa80405db82e2eb36ac48671b4c8c0983 (diff) | |
download | cpython-git-a70232f28882d2fecb3ebe06643867701016070f.tar.gz |
bpo-32296: Implement asyncio.get_event_loop and _get_running_loop in C. (#4827)
asyncio.get_event_loop(), and, subsequently asyncio._get_running_loop()
are one of the most frequently executed functions in asyncio. They also
can't be sped up by third-party event loops like uvloop.
When implemented in C they become 4x faster.
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/test_asyncio/test_events.py | 133 |
1 files changed, 113 insertions, 20 deletions
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 1315febe40..144921ad0e 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -27,6 +27,7 @@ if sys.platform != 'win32': import asyncio from asyncio import coroutines +from asyncio import events from asyncio import proactor_events from asyncio import selector_events from test.test_asyncio import utils as test_utils @@ -2145,23 +2146,6 @@ else: asyncio.set_child_watcher(None) super().tearDown() - def test_get_event_loop_new_process(self): - # Issue bpo-32126: The multiprocessing module used by - # ProcessPoolExecutor is not functional when the - # multiprocessing.synchronize module cannot be imported. - support.import_module('multiprocessing.synchronize') - async def main(): - pool = concurrent.futures.ProcessPoolExecutor() - result = await self.loop.run_in_executor( - pool, _test_get_event_loop_new_process__sub_proc) - pool.shutdown() - return result - - self.unpatch_get_running_loop() - - self.assertEqual( - self.loop.run_until_complete(main()), - 'hello') if hasattr(selectors, 'KqueueSelector'): class KqueueEventLoopTests(UnixEventLoopTestsMixin, @@ -2722,17 +2706,95 @@ class PolicyTests(unittest.TestCase): self.assertIs(policy, asyncio.get_event_loop_policy()) self.assertIsNot(policy, old_policy) + +class GetEventLoopTestsMixin: + + _get_running_loop_impl = None + _set_running_loop_impl = None + get_running_loop_impl = None + get_event_loop_impl = None + + def setUp(self): + self._get_running_loop_saved = events._get_running_loop + self._set_running_loop_saved = events._set_running_loop + self.get_running_loop_saved = events.get_running_loop + self.get_event_loop_saved = events.get_event_loop + + events._get_running_loop = type(self)._get_running_loop_impl + events._set_running_loop = type(self)._set_running_loop_impl + events.get_running_loop = type(self).get_running_loop_impl + events.get_event_loop = type(self).get_event_loop_impl + + asyncio._get_running_loop = type(self)._get_running_loop_impl + asyncio._set_running_loop = type(self)._set_running_loop_impl + asyncio.get_running_loop = type(self).get_running_loop_impl + asyncio.get_event_loop = type(self).get_event_loop_impl + + super().setUp() + + self.loop = asyncio.new_event_loop() + asyncio.set_event_loop(self.loop) + + watcher = asyncio.SafeChildWatcher() + watcher.attach_loop(self.loop) + asyncio.set_child_watcher(watcher) + + def tearDown(self): + try: + asyncio.set_child_watcher(None) + super().tearDown() + finally: + self.loop.close() + asyncio.set_event_loop(None) + + events._get_running_loop = self._get_running_loop_saved + events._set_running_loop = self._set_running_loop_saved + events.get_running_loop = self.get_running_loop_saved + events.get_event_loop = self.get_event_loop_saved + + asyncio._get_running_loop = self._get_running_loop_saved + asyncio._set_running_loop = self._set_running_loop_saved + asyncio.get_running_loop = self.get_running_loop_saved + asyncio.get_event_loop = self.get_event_loop_saved + + if sys.platform != 'win32': + + def test_get_event_loop_new_process(self): + # Issue bpo-32126: The multiprocessing module used by + # ProcessPoolExecutor is not functional when the + # multiprocessing.synchronize module cannot be imported. + support.import_module('multiprocessing.synchronize') + + async def main(): + pool = concurrent.futures.ProcessPoolExecutor() + result = await self.loop.run_in_executor( + pool, _test_get_event_loop_new_process__sub_proc) + pool.shutdown() + return result + + self.assertEqual( + self.loop.run_until_complete(main()), + 'hello') + def test_get_event_loop_returns_running_loop(self): + class TestError(Exception): + pass + class Policy(asyncio.DefaultEventLoopPolicy): def get_event_loop(self): - raise NotImplementedError - - loop = None + raise TestError old_policy = asyncio.get_event_loop_policy() try: asyncio.set_event_loop_policy(Policy()) loop = asyncio.new_event_loop() + + with self.assertRaises(TestError): + asyncio.get_event_loop() + asyncio.set_event_loop(None) + with self.assertRaises(TestError): + asyncio.get_event_loop() + with self.assertRaisesRegex(RuntimeError, 'no running'): self.assertIs(asyncio.get_running_loop(), None) self.assertIs(asyncio._get_running_loop(), None) @@ -2743,6 +2805,15 @@ class PolicyTests(unittest.TestCase): self.assertIs(asyncio._get_running_loop(), loop) loop.run_until_complete(func()) + + asyncio.set_event_loop(loop) + with self.assertRaises(TestError): + asyncio.get_event_loop() + + asyncio.set_event_loop(None) + with self.assertRaises(TestError): + asyncio.get_event_loop() + finally: asyncio.set_event_loop_policy(old_policy) if loop is not None: @@ -2754,5 +2825,27 @@ class PolicyTests(unittest.TestCase): self.assertIs(asyncio._get_running_loop(), None) +class TestPyGetEventLoop(GetEventLoopTestsMixin, unittest.TestCase): + + _get_running_loop_impl = events._py__get_running_loop + _set_running_loop_impl = events._py__set_running_loop + get_running_loop_impl = events._py_get_running_loop + get_event_loop_impl = events._py_get_event_loop + + +try: + import _asyncio # NoQA +except ImportError: + pass +else: + + class TestCGetEventLoop(GetEventLoopTestsMixin, unittest.TestCase): + + _get_running_loop_impl = events._c__get_running_loop + _set_running_loop_impl = events._c__set_running_loop + get_running_loop_impl = events._c_get_running_loop + get_event_loop_impl = events._c_get_event_loop + + if __name__ == '__main__': unittest.main() |