From b50dcef94fba6528c842448c53bab7c31be35be9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 26 Mar 2021 21:54:49 -1000 Subject: [PATCH] Block detectable I/O in the event loop (#48387) We added a warning when this happens last April and gave developers a year to fix the instability. We now prevent the instability by raising RuntimeError when code attempts to do known I/O in the event loop instead of the executor. We now provide a suggestion on how to fix the code that is causing the issue. --- homeassistant/util/async_.py | 4 ++++ tests/util/test_async.py | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/homeassistant/util/async_.py b/homeassistant/util/async_.py index 0fd1b564f0d..15353d1f7eb 100644 --- a/homeassistant/util/async_.py +++ b/homeassistant/util/async_.py @@ -136,6 +136,10 @@ def check_loop() -> None: found_frame.lineno, found_frame.line.strip(), ) + raise RuntimeError( + f"I/O must be done in the executor; Use `await hass.async_add_executor_job()` " + f"at {found_frame.filename[index:]}, line {found_frame.lineno}: {found_frame.line.strip()}" + ) def protect_loop(func: Callable) -> Callable: diff --git a/tests/util/test_async.py b/tests/util/test_async.py index d4fdce1e912..d5564a90d0e 100644 --- a/tests/util/test_async.py +++ b/tests/util/test_async.py @@ -78,7 +78,7 @@ async def test_check_loop_async(): async def test_check_loop_async_integration(caplog): """Test check_loop detects when called from event loop from integration context.""" - with patch( + with pytest.raises(RuntimeError), patch( "homeassistant.util.async_.extract_stack", return_value=[ Mock( @@ -107,7 +107,7 @@ async def test_check_loop_async_integration(caplog): async def test_check_loop_async_custom(caplog): """Test check_loop detects when called from event loop with custom component context.""" - with patch( + with pytest.raises(RuntimeError), patch( "homeassistant.util.async_.extract_stack", return_value=[ Mock(