Drop last bits of asyncio.coroutine (#39280)

This commit is contained in:
Paulus Schoutsen 2020-08-26 16:57:52 +02:00 committed by GitHub
parent b47992dba0
commit 51a63c1fc4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 204 deletions

View file

@ -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

View file

@ -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()

View file

@ -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).

View file

@ -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)

View file

@ -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):

View file

@ -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,