From 51a63c1fc413670fb776560380c1ad24c3998297 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 26 Aug 2020 16:57:52 +0200 Subject: [PATCH] Drop last bits of asyncio.coroutine (#39280) --- .../components/mqtt_eventstream/__init__.py | 6 +- tests/common.py | 3 +- tests/components/shell_command/test_init.py | 5 +- tests/test_core.py | 158 ++++++++---------- tests/util/test_async.py | 101 ----------- tests/util/test_package.py | 5 +- 6 files changed, 74 insertions(+), 204 deletions(-) diff --git a/homeassistant/components/mqtt_eventstream/__init__.py b/homeassistant/components/mqtt_eventstream/__init__.py index 48448355df89..5a5f3b3c74d5 100644 --- a/homeassistant/components/mqtt_eventstream/__init__.py +++ b/homeassistant/components/mqtt_eventstream/__init__.py @@ -1,5 +1,4 @@ """Connect two Home Assistant instances via MQTT.""" -import asyncio import json import voluptuous as vol @@ -39,8 +38,7 @@ CONFIG_SCHEMA = vol.Schema( ) -@asyncio.coroutine -def async_setup(hass, config): +async def async_setup(hass, config): """Set up the MQTT eventstream component.""" mqtt = hass.components.mqtt conf = config.get(DOMAIN, {}) @@ -103,6 +101,6 @@ def async_setup(hass, config): # Only subscribe if you specified a topic. if sub_topic: - yield from mqtt.async_subscribe(sub_topic, _event_receiver) + await mqtt.async_subscribe(sub_topic, _event_receiver) return True diff --git a/tests/common.py b/tests/common.py index e2e183061a72..1cba478767fc 100644 --- a/tests/common.py +++ b/tests/common.py @@ -261,8 +261,7 @@ def async_mock_intent(hass, intent_typ): class MockIntentHandler(intent.IntentHandler): intent_type = intent_typ - @asyncio.coroutine - def async_handle(self, intent): + async def async_handle(self, intent): """Handle the intent.""" intents.append(intent) return intent.create_response() diff --git a/tests/components/shell_command/test_init.py b/tests/components/shell_command/test_init.py index 7019d22fac83..1f8e442e93d9 100644 --- a/tests/components/shell_command/test_init.py +++ b/tests/components/shell_command/test_init.py @@ -12,11 +12,10 @@ from tests.async_mock import Mock, patch from tests.common import get_test_home_assistant -def mock_process_creator(error: bool = False) -> asyncio.coroutine: +def mock_process_creator(error: bool = False): """Mock a coroutine that creates a process when yielded.""" - @asyncio.coroutine - def communicate() -> Tuple[bytes, bytes]: + async def communicate() -> Tuple[bytes, bytes]: """Mock a coroutine that runs a process when yielded. Returns a tuple of (stdout, stderr). diff --git a/tests/test_core.py b/tests/test_core.py index 05a969d0a75d..22f1e7790613 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -174,120 +174,98 @@ def test_stage_shutdown(): assert len(test_all) == 2 -class TestHomeAssistant(unittest.TestCase): - """Test the Home Assistant core classes.""" +async def test_pending_sheduler(hass): + """Add a coro to pending tasks.""" + call_count = [] - # pylint: disable=invalid-name - def setUp(self): - """Set up things to be run when tests are started.""" - self.hass = get_test_home_assistant() + async def test_coro(): + """Test Coro.""" + call_count.append("call") - # pylint: disable=invalid-name - def tearDown(self): - """Stop everything that was started.""" - self.hass.stop() + for _ in range(3): + hass.async_add_job(test_coro()) - def test_pending_sheduler(self): - """Add a coro to pending tasks.""" - call_count = [] + await asyncio.wait(hass._pending_tasks) - @asyncio.coroutine - def test_coro(): - """Test Coro.""" - call_count.append("call") + assert len(hass._pending_tasks) == 3 + assert len(call_count) == 3 - for _ in range(3): - self.hass.add_job(test_coro()) - asyncio.run_coroutine_threadsafe( - asyncio.wait(self.hass._pending_tasks), loop=self.hass.loop - ).result() +async def test_async_add_job_pending_tasks_coro(hass): + """Add a coro to pending tasks.""" + call_count = [] - assert len(self.hass._pending_tasks) == 3 - assert len(call_count) == 3 + async def test_coro(): + """Test Coro.""" + call_count.append("call") - def test_async_add_job_pending_tasks_coro(self): - """Add a coro to pending tasks.""" - call_count = [] + for _ in range(2): + hass.add_job(test_coro()) - @asyncio.coroutine - def test_coro(): - """Test Coro.""" - call_count.append("call") + async def wait_finish_callback(): + """Wait until all stuff is scheduled.""" + await asyncio.sleep(0) + await asyncio.sleep(0) - for _ in range(2): - self.hass.add_job(test_coro()) + await wait_finish_callback() - @asyncio.coroutine - def wait_finish_callback(): - """Wait until all stuff is scheduled.""" - yield from asyncio.sleep(0) - yield from asyncio.sleep(0) + assert len(hass._pending_tasks) == 2 + await hass.async_block_till_done() + assert len(call_count) == 2 - asyncio.run_coroutine_threadsafe( - wait_finish_callback(), self.hass.loop - ).result() - assert len(self.hass._pending_tasks) == 2 - self.hass.block_till_done() - assert len(call_count) == 2 +async def test_async_add_job_pending_tasks_executor(hass): + """Run an executor in pending tasks.""" + call_count = [] - def test_async_add_job_pending_tasks_executor(self): - """Run an executor in pending tasks.""" - call_count = [] + def test_executor(): + """Test executor.""" + call_count.append("call") - def test_executor(): - """Test executor.""" - call_count.append("call") + async def wait_finish_callback(): + """Wait until all stuff is scheduled.""" + await asyncio.sleep(0) + await asyncio.sleep(0) - @asyncio.coroutine - def wait_finish_callback(): - """Wait until all stuff is scheduled.""" - yield from asyncio.sleep(0) - yield from asyncio.sleep(0) + for _ in range(2): + hass.async_add_job(test_executor) - for _ in range(2): - self.hass.add_job(test_executor) + await wait_finish_callback() - asyncio.run_coroutine_threadsafe( - wait_finish_callback(), self.hass.loop - ).result() + assert len(hass._pending_tasks) == 2 + await hass.async_block_till_done() + assert len(call_count) == 2 - assert len(self.hass._pending_tasks) == 2 - self.hass.block_till_done() - assert len(call_count) == 2 - def test_async_add_job_pending_tasks_callback(self): - """Run a callback in pending tasks.""" - call_count = [] +async def test_async_add_job_pending_tasks_callback(hass): + """Run a callback in pending tasks.""" + call_count = [] - @ha.callback - def test_callback(): - """Test callback.""" - call_count.append("call") + @ha.callback + def test_callback(): + """Test callback.""" + call_count.append("call") - @asyncio.coroutine - def wait_finish_callback(): - """Wait until all stuff is scheduled.""" - yield from asyncio.sleep(0) - yield from asyncio.sleep(0) + async def wait_finish_callback(): + """Wait until all stuff is scheduled.""" + await asyncio.sleep(0) + await asyncio.sleep(0) - for _ in range(2): - self.hass.add_job(test_callback) + for _ in range(2): + hass.async_add_job(test_callback) - asyncio.run_coroutine_threadsafe( - wait_finish_callback(), self.hass.loop - ).result() + await wait_finish_callback() - self.hass.block_till_done() + await hass.async_block_till_done() - assert len(self.hass._pending_tasks) == 0 - assert len(call_count) == 2 + assert len(hass._pending_tasks) == 0 + assert len(call_count) == 2 - def test_add_job_with_none(self): - """Try to add a job with None as function.""" - with pytest.raises(ValueError): - self.hass.add_job(None, "test_arg") + +async def test_add_job_with_none(hass): + """Try to add a job with None as function.""" + with pytest.raises(ValueError): + hass.async_add_job(None, "test_arg") class TestEvent(unittest.TestCase): @@ -412,8 +390,7 @@ class TestEventBus(unittest.TestCase): """Test listen_once_event method.""" runs = [] - @asyncio.coroutine - def event_handler(event): + async def event_handler(event): runs.append(event) self.bus.listen_once("test_event", event_handler) @@ -470,8 +447,7 @@ class TestEventBus(unittest.TestCase): """Test coroutine event listener.""" coroutine_calls = [] - @asyncio.coroutine - def coroutine_listener(event): + async def coroutine_listener(event): coroutine_calls.append(event) self.bus.listen("test_coroutine", coroutine_listener) diff --git a/tests/util/test_async.py b/tests/util/test_async.py index b60b4097c520..460490eb7837 100644 --- a/tests/util/test_async.py +++ b/tests/util/test_async.py @@ -1,7 +1,4 @@ """Tests for async util methods from Python source.""" -import asyncio -from unittest import TestCase - import pytest from homeassistant.util import async_ as hasync @@ -70,104 +67,6 @@ def test_run_callback_threadsafe_from_inside_event_loop(mock_ident, _): assert len(loop.call_soon_threadsafe.mock_calls) == 2 -class RunThreadsafeTests(TestCase): - """Test case for hasync.run_coroutine_threadsafe.""" - - def setUp(self): - """Test setup method.""" - self.loop = asyncio.new_event_loop() - - def tearDown(self): - """Test teardown method.""" - executor = self.loop._default_executor - if executor is not None: - executor.shutdown(wait=True) - self.loop.close() - - @staticmethod - def run_briefly(loop): - """Momentarily run a coroutine on the given loop.""" - - @asyncio.coroutine - def once(): - pass - - gen = once() - t = loop.create_task(gen) - try: - loop.run_until_complete(t) - finally: - gen.close() - - def add_callback(self, a, b, fail, invalid): - """Return a + b.""" - if fail: - raise RuntimeError("Fail!") - if invalid: - raise ValueError("Invalid!") - return a + b - - @asyncio.coroutine - def add_coroutine(self, a, b, fail, invalid, cancel): - """Wait 0.05 second and return a + b.""" - yield from asyncio.sleep(0.05, loop=self.loop) - if cancel: - asyncio.current_task(self.loop).cancel() - yield - return self.add_callback(a, b, fail, invalid) - - def target_callback(self, fail=False, invalid=False): - """Run add callback in the event loop.""" - future = hasync.run_callback_threadsafe( - self.loop, self.add_callback, 1, 2, fail, invalid - ) - try: - return future.result() - finally: - future.done() or future.cancel() - - def target_coroutine( - self, fail=False, invalid=False, cancel=False, timeout=None, advance_coro=False - ): - """Run add coroutine in the event loop.""" - coro = self.add_coroutine(1, 2, fail, invalid, cancel) - future = hasync.run_coroutine_threadsafe(coro, self.loop) - if advance_coro: - # this is for test_run_coroutine_threadsafe_task_factory_exception; - # otherwise it spills errors and breaks **other** unittests, since - # 'target_coroutine' is interacting with threads. - - # With this call, `coro` will be advanced, so that - # CoroWrapper.__del__ won't do anything when asyncio tests run - # in debug mode. - self.loop.call_soon_threadsafe(coro.send, None) - try: - return future.result(timeout) - finally: - future.done() or future.cancel() - - def test_run_callback_threadsafe(self): - """Test callback submission from a thread to an event loop.""" - future = self.loop.run_in_executor(None, self.target_callback) - result = self.loop.run_until_complete(future) - self.assertEqual(result, 3) - - def test_run_callback_threadsafe_with_exception(self): - """Test callback submission from thread to event loop on exception.""" - future = self.loop.run_in_executor(None, self.target_callback, True) - with self.assertRaises(RuntimeError) as exc_context: - self.loop.run_until_complete(future) - self.assertIn("Fail!", exc_context.exception.args) - - def test_run_callback_threadsafe_with_invalid(self): - """Test callback submission from thread to event loop on invalid.""" - callback = lambda: self.target_callback(invalid=True) # noqa: E731 - future = self.loop.run_in_executor(None, callback) - with self.assertRaises(ValueError) as exc_context: - self.loop.run_until_complete(future) - self.assertIn("Invalid!", exc_context.exception.args) - - async def test_check_loop_async(): """Test check_loop detects when called from event loop without integration context.""" with pytest.raises(RuntimeError): diff --git a/tests/util/test_package.py b/tests/util/test_package.py index c9f5183249e4..064d1379e08f 100644 --- a/tests/util/test_package.py +++ b/tests/util/test_package.py @@ -216,8 +216,7 @@ def test_install_find_links(mock_sys, mock_popen, mock_env_copy, mock_venv): assert mock_popen.return_value.communicate.call_count == 1 -@asyncio.coroutine -def test_async_get_user_site(mock_env_copy): +async def test_async_get_user_site(mock_env_copy): """Test async get user site directory.""" deps_dir = "/deps_dir" env = mock_env_copy() @@ -227,7 +226,7 @@ def test_async_get_user_site(mock_env_copy): "homeassistant.util.package.asyncio.create_subprocess_exec", return_value=mock_async_subprocess(), ) as popen_mock: - ret = yield from package.async_get_user_site(deps_dir) + ret = await package.async_get_user_site(deps_dir) assert popen_mock.call_count == 1 assert popen_mock.call_args == call( *args,