From ff0e0b3e77c333bc34ecc2322e820a933695b4d3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 23 Feb 2024 21:37:33 -1000 Subject: [PATCH] Convert debouncer async_shutdown to be a normal function (#111257) * Convert debouncer async_shutdown to be a normal function nothing was being awaited here and the shutdown call was only used in integrations marked internal and other internals. Its possible that a custom component might have been using the method but it seemed uncommon enough that it did not warrent marking as a breaking change. The update coordinator is no longer awaiting anything in async_shutdown either now but it seemed likely that this use would get subclassed. * fix --- homeassistant/components/bluetooth/__init__.py | 5 +++-- homeassistant/components/samsungtv/__init__.py | 5 +++-- homeassistant/components/usb/__init__.py | 5 +++-- homeassistant/config_entries.py | 10 ++++++---- homeassistant/helpers/debounce.py | 3 ++- homeassistant/helpers/update_coordinator.py | 2 +- tests/helpers/test_debounce.py | 2 +- tests/test_config_entries.py | 2 +- 8 files changed, 20 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/bluetooth/__init__.py b/homeassistant/components/bluetooth/__init__.py index b56af7218b1..3438f4725a2 100644 --- a/homeassistant/components/bluetooth/__init__.py +++ b/homeassistant/components/bluetooth/__init__.py @@ -173,9 +173,10 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: function=_async_rediscover_adapters, ) - async def _async_shutdown_debouncer(_: Event) -> None: + @hass_callback + def _async_shutdown_debouncer(_: Event) -> None: """Shutdown debouncer.""" - await discovery_debouncer.async_shutdown() + discovery_debouncer.async_shutdown() hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _async_shutdown_debouncer) diff --git a/homeassistant/components/samsungtv/__init__.py b/homeassistant/components/samsungtv/__init__.py index a70a336ebfd..56fd230fd6f 100644 --- a/homeassistant/components/samsungtv/__init__.py +++ b/homeassistant/components/samsungtv/__init__.py @@ -93,9 +93,10 @@ class DebouncedEntryReloader: LOGGER.debug("Calling debouncer to get a reload after cooldown") await self._debounced_reload.async_call() - async def async_shutdown(self) -> None: + @callback + def async_shutdown(self) -> None: """Cancel any pending reload.""" - await self._debounced_reload.async_shutdown() + self._debounced_reload.async_shutdown() async def _async_reload_entry(self) -> None: """Reload entry.""" diff --git a/homeassistant/components/usb/__init__.py b/homeassistant/components/usb/__init__.py index b2358a4b0bd..916e9b1ea32 100644 --- a/homeassistant/components/usb/__init__.py +++ b/homeassistant/components/usb/__init__.py @@ -213,10 +213,11 @@ class USBDiscovery: """Start USB Discovery and run a manual scan.""" await self._async_scan_serial() - async def async_stop(self, event: Event) -> None: + @hass_callback + def async_stop(self, event: Event) -> None: """Stop USB Discovery.""" if self._request_debouncer: - await self._request_debouncer.async_shutdown() + self._request_debouncer.async_shutdown() async def _async_start_monitor(self) -> None: """Start monitoring hardware with pyudev.""" diff --git a/homeassistant/config_entries.py b/homeassistant/config_entries.py index bfbc16007c4..7804ae66600 100644 --- a/homeassistant/config_entries.py +++ b/homeassistant/config_entries.py @@ -1052,12 +1052,13 @@ class ConfigEntriesFlowManager(data_entry_flow.FlowManager): init_done.set_result(None) return flow, result - async def async_shutdown(self) -> None: + @callback + def async_shutdown(self) -> None: """Cancel any initializing flows.""" for future_list in self._initialize_futures.values(): for future in future_list: future.set_result(None) - await self._discovery_debouncer.async_shutdown() + self._discovery_debouncer.async_shutdown() async def async_finish_flow( self, flow: data_entry_flow.FlowHandler, result: data_entry_flow.FlowResult @@ -1418,11 +1419,12 @@ class ConfigEntries: self._async_dispatch(ConfigEntryChange.REMOVED, entry) return {"require_restart": not unload_success} - async def _async_shutdown(self, event: Event) -> None: + @callback + def _async_shutdown(self, event: Event) -> None: """Call when Home Assistant is stopping.""" for entry in self._entries.values(): entry.async_shutdown() - await self.flow.async_shutdown() + self.flow.async_shutdown() async def async_initialize(self) -> None: """Initialize config entry config.""" diff --git a/homeassistant/helpers/debounce.py b/homeassistant/helpers/debounce.py index d25026edcd1..ef98ea0225f 100644 --- a/homeassistant/helpers/debounce.py +++ b/homeassistant/helpers/debounce.py @@ -137,7 +137,8 @@ class Debouncer(Generic[_R_co]): # Schedule a new timer to prevent new runs during cooldown self._schedule_timer() - async def async_shutdown(self) -> None: + @callback + def async_shutdown(self) -> None: """Cancel any scheduled call, and prevent new runs.""" self._shutdown_requested = True self.async_cancel() diff --git a/homeassistant/helpers/update_coordinator.py b/homeassistant/helpers/update_coordinator.py index 2a926810ef1..f76ff3b89b7 100644 --- a/homeassistant/helpers/update_coordinator.py +++ b/homeassistant/helpers/update_coordinator.py @@ -187,7 +187,7 @@ class DataUpdateCoordinator(BaseDataUpdateCoordinatorProtocol, Generic[_DataT]): self._shutdown_requested = True self._async_unsub_refresh() self._async_unsub_shutdown() - await self._debounced_refresh.async_shutdown() + self._debounced_refresh.async_shutdown() @callback def _unschedule_refresh(self) -> None: diff --git a/tests/helpers/test_debounce.py b/tests/helpers/test_debounce.py index a1073ed39bf..958b88951ce 100644 --- a/tests/helpers/test_debounce.py +++ b/tests/helpers/test_debounce.py @@ -484,7 +484,7 @@ async def test_shutdown(hass: HomeAssistant, caplog: pytest.LogCaptureFixture) - # Ensure shutdown during a run doesn't create a cooldown timer hass.async_create_task(debouncer.async_call()) await asyncio.sleep(0.01) - await debouncer.async_shutdown() + debouncer.async_shutdown() future.set_result(True) await hass.async_block_till_done() assert len(calls) == 1 diff --git a/tests/test_config_entries.py b/tests/test_config_entries.py index 9f84aa1e494..6bf20234798 100644 --- a/tests/test_config_entries.py +++ b/tests/test_config_entries.py @@ -4199,7 +4199,7 @@ async def test_initializing_flows_canceled_on_shutdown( manager.flow.async_init("test", context={"source": "reauth"}) ) await hass.async_block_till_done() - await manager.flow.async_shutdown() + manager.flow.async_shutdown() with pytest.raises(asyncio.exceptions.CancelledError): await task