From 99010bab18de0c15fff0cb2fb7e3580d176108d0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 15 Oct 2020 02:26:51 -0500 Subject: [PATCH] Permit event trackers to accept an empty list of entities or domains (#41857) --- homeassistant/helpers/event.py | 17 +++++++++++ tests/helpers/test_event.py | 52 ++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/homeassistant/helpers/event.py b/homeassistant/helpers/event.py index b6d59bb500c..33d2082c99e 100644 --- a/homeassistant/helpers/event.py +++ b/homeassistant/helpers/event.py @@ -233,6 +233,9 @@ def async_track_state_change_event( care about the state change events so we can do a fast dict lookup to route events. """ + entity_ids = _async_string_to_lower_list(entity_ids) + if not entity_ids: + return _remove_empty_listener entity_callbacks = hass.data.setdefault(TRACK_STATE_CHANGE_CALLBACKS, {}) @@ -277,6 +280,11 @@ def async_track_state_change_event( return remove_listener +@callback +def _remove_empty_listener() -> None: + """Remove a listener that does nothing.""" + + @callback def _async_remove_indexed_listeners( hass: HomeAssistant, @@ -309,6 +317,9 @@ def async_track_entity_registry_updated_event( Similar to async_track_state_change_event. """ + entity_ids = _async_string_to_lower_list(entity_ids) + if not entity_ids: + return _remove_empty_listener entity_callbacks = hass.data.setdefault(TRACK_ENTITY_REGISTRY_UPDATED_CALLBACKS, {}) @@ -381,6 +392,9 @@ def async_track_state_added_domain( action: Callable[[Event], Any], ) -> Callable[[], None]: """Track state change events when an entity is added to domains.""" + domains = _async_string_to_lower_list(domains) + if not domains: + return _remove_empty_listener domain_callbacks = hass.data.setdefault(TRACK_STATE_ADDED_DOMAIN_CALLBACKS, {}) @@ -424,6 +438,9 @@ def async_track_state_removed_domain( action: Callable[[Event], Any], ) -> Callable[[], None]: """Track state change events when an entity is removed from domains.""" + domains = _async_string_to_lower_list(domains) + if not domains: + return _remove_empty_listener domain_callbacks = hass.data.setdefault(TRACK_STATE_REMOVED_DOMAIN_CALLBACKS, {}) diff --git a/tests/helpers/test_event.py b/tests/helpers/test_event.py index bb0d17d7b0e..14b208b68d4 100644 --- a/tests/helpers/test_event.py +++ b/tests/helpers/test_event.py @@ -486,6 +486,19 @@ async def test_async_track_state_change_event(hass): unsub_throws() +async def test_async_track_state_change_event_with_empty_list(hass): + """Test async_track_state_change_event passing an empty list of entities.""" + unsub_single = async_track_state_change_event( + hass, [], ha.callback(lambda event: None) + ) + unsub_single2 = async_track_state_change_event( + hass, [], ha.callback(lambda event: None) + ) + + unsub_single2() + unsub_single() + + async def test_async_track_state_added_domain(hass): """Test async_track_state_added_domain.""" single_entity_id_tracker = [] @@ -568,6 +581,32 @@ async def test_async_track_state_added_domain(hass): unsub_throws() +async def test_async_track_state_added_domain_with_empty_list(hass): + """Test async_track_state_added_domain passing an empty list of domains.""" + unsub_single = async_track_state_added_domain( + hass, [], ha.callback(lambda event: None) + ) + unsub_single2 = async_track_state_added_domain( + hass, [], ha.callback(lambda event: None) + ) + + unsub_single2() + unsub_single() + + +async def test_async_track_state_removed_domain_with_empty_list(hass): + """Test async_track_state_removed_domain passing an empty list of domains.""" + unsub_single = async_track_state_removed_domain( + hass, [], ha.callback(lambda event: None) + ) + unsub_single2 = async_track_state_removed_domain( + hass, [], ha.callback(lambda event: None) + ) + + unsub_single2() + unsub_single() + + async def test_async_track_state_removed_domain(hass): """Test async_track_state_removed_domain.""" single_entity_id_tracker = [] @@ -2876,3 +2915,16 @@ async def test_async_track_entity_registry_updated_event_with_a_callback_that_th unsub2() assert event_data[0] == {"action": "create", "entity_id": "switch.puppy_feeder"} + + +async def test_async_track_entity_registry_updated_event_with_empty_list(hass): + """Test async_track_entity_registry_updated_event passing an empty list of entities.""" + unsub_single = hass.helpers.event.async_track_entity_registry_updated_event( + [], ha.callback(lambda event: None) + ) + unsub_single2 = hass.helpers.event.async_track_entity_registry_updated_event( + [], ha.callback(lambda event: None) + ) + + unsub_single2() + unsub_single()