Always run keyed event trackers immediately (#114709)

This commit is contained in:
J. Nick Koston 2024-04-04 15:30:01 -10:00 committed by GitHub
parent 78920e1d71
commit d321906342
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 47 additions and 24 deletions

View file

@ -107,7 +107,6 @@ class _KeyedEventTracker(Generic[_TypedDictT]):
], ],
bool, bool,
] ]
run_immediately: bool
@dataclass(slots=True) @dataclass(slots=True)
@ -339,7 +338,6 @@ _KEYED_TRACK_STATE_CHANGE = _KeyedEventTracker(
event_type=EVENT_STATE_CHANGED, event_type=EVENT_STATE_CHANGED,
dispatcher_callable=_async_dispatch_entity_id_event, dispatcher_callable=_async_dispatch_entity_id_event,
filter_callable=_async_state_change_filter, filter_callable=_async_state_change_filter,
run_immediately=False,
) )
@ -417,7 +415,7 @@ def _async_track_event(
tracker.event_type, tracker.event_type,
ft.partial(tracker.dispatcher_callable, hass, callbacks), ft.partial(tracker.dispatcher_callable, hass, callbacks),
event_filter=ft.partial(tracker.filter_callable, hass, callbacks), event_filter=ft.partial(tracker.filter_callable, hass, callbacks),
run_immediately=tracker.run_immediately, run_immediately=True,
) )
job = HassJob(action, f"track {tracker.event_type} event {keys}", job_type=job_type) job = HassJob(action, f"track {tracker.event_type} event {keys}", job_type=job_type)
@ -471,7 +469,6 @@ _KEYED_TRACK_ENTITY_REGISTRY_UPDATED = _KeyedEventTracker(
event_type=EVENT_ENTITY_REGISTRY_UPDATED, event_type=EVENT_ENTITY_REGISTRY_UPDATED,
dispatcher_callable=_async_dispatch_old_entity_id_or_entity_id_event, dispatcher_callable=_async_dispatch_old_entity_id_or_entity_id_event,
filter_callable=_async_entity_registry_updated_filter, filter_callable=_async_entity_registry_updated_filter,
run_immediately=True,
) )
@ -530,7 +527,6 @@ _KEYED_TRACK_DEVICE_REGISTRY_UPDATED = _KeyedEventTracker(
event_type=EVENT_DEVICE_REGISTRY_UPDATED, event_type=EVENT_DEVICE_REGISTRY_UPDATED,
dispatcher_callable=_async_dispatch_device_id_event, dispatcher_callable=_async_dispatch_device_id_event,
filter_callable=_async_device_registry_updated_filter, filter_callable=_async_device_registry_updated_filter,
run_immediately=True,
) )
@ -599,7 +595,6 @@ _KEYED_TRACK_STATE_ADDED_DOMAIN = _KeyedEventTracker(
event_type=EVENT_STATE_CHANGED, event_type=EVENT_STATE_CHANGED,
dispatcher_callable=_async_dispatch_domain_event, dispatcher_callable=_async_dispatch_domain_event,
filter_callable=_async_domain_added_filter, filter_callable=_async_domain_added_filter,
run_immediately=False,
) )
@ -635,7 +630,6 @@ _KEYED_TRACK_STATE_REMOVED_DOMAIN = _KeyedEventTracker(
event_type=EVENT_STATE_CHANGED, event_type=EVENT_STATE_CHANGED,
dispatcher_callable=_async_dispatch_domain_event, dispatcher_callable=_async_dispatch_domain_event,
filter_callable=_async_domain_removed_filter, filter_callable=_async_domain_removed_filter,
run_immediately=False,
) )

View file

@ -808,10 +808,10 @@ async def test_heating_cooling_switch_does_not_toggle_when_within_min_cycle_dura
# Given # Given
await _setup_thermostat_with_min_cycle_duration(hass, ac_mode, initial_hvac_mode) await _setup_thermostat_with_min_cycle_duration(hass, ac_mode, initial_hvac_mode)
calls = _setup_switch(hass, initial_switch_state) calls = _setup_switch(hass, initial_switch_state)
_setup_sensor(hass, sensor_temperature)
# When # When
await common.async_set_temperature(hass, target_temperature) await common.async_set_temperature(hass, target_temperature)
_setup_sensor(hass, sensor_temperature)
await hass.async_block_till_done() await hass.async_block_till_done()
# Then # Then
@ -849,10 +849,10 @@ async def test_heating_cooling_switch_toggles_when_outside_min_cycle_duration(
fake_changed = datetime.datetime(1970, 11, 11, 11, 11, 11, tzinfo=dt_util.UTC) fake_changed = datetime.datetime(1970, 11, 11, 11, 11, 11, tzinfo=dt_util.UTC)
with freeze_time(fake_changed): with freeze_time(fake_changed):
calls = _setup_switch(hass, initial_switch_state) calls = _setup_switch(hass, initial_switch_state)
_setup_sensor(hass, sensor_temperature)
# When # When
await common.async_set_temperature(hass, target_temperature) await common.async_set_temperature(hass, target_temperature)
_setup_sensor(hass, sensor_temperature)
await hass.async_block_till_done() await hass.async_block_till_done()
# Then # Then
@ -894,10 +894,10 @@ async def test_hvac_mode_change_toggles_heating_cooling_switch_even_when_within_
# Given # Given
await _setup_thermostat_with_min_cycle_duration(hass, ac_mode, initial_hvac_mode) await _setup_thermostat_with_min_cycle_duration(hass, ac_mode, initial_hvac_mode)
calls = _setup_switch(hass, initial_switch_state) calls = _setup_switch(hass, initial_switch_state)
_setup_sensor(hass, sensor_temperature)
# When # When
await common.async_set_temperature(hass, target_temperature) await common.async_set_temperature(hass, target_temperature)
_setup_sensor(hass, sensor_temperature)
await hass.async_block_till_done() await hass.async_block_till_done()
# Then # Then

View file

@ -540,6 +540,7 @@ async def test_config_flow_preview(
} }
) )
msg = await client.receive_json() msg = await client.receive_json()
preview_subscribe_id = msg["id"]
assert msg["success"] assert msg["success"]
assert msg["result"] is None assert msg["result"] is None
@ -549,9 +550,32 @@ async def test_config_flow_preview(
"state": "unavailable", "state": "unavailable",
} }
await client.send_json_auto_id(
{
"type": "unsubscribe_events",
"subscription": preview_subscribe_id,
}
)
msg = await client.receive_json()
assert msg["success"]
hass.states.async_set(input_entities[0], input_states[0]) hass.states.async_set(input_entities[0], input_states[0])
hass.states.async_set(input_entities[1], input_states[1]) hass.states.async_set(input_entities[1], input_states[1])
await client.send_json_auto_id(
{
"type": "group/start_preview",
"flow_id": result["flow_id"],
"flow_type": "config_flow",
"user_input": {"name": "My group", "entities": input_entities}
| extra_user_input,
}
)
msg = await client.receive_json()
preview_subscribe_id = msg["id"]
assert msg["success"]
assert msg["result"] is None
msg = await client.receive_json() msg = await client.receive_json()
assert msg["event"] == { assert msg["event"] == {
"attributes": { "attributes": {

View file

@ -8,6 +8,7 @@ from pytest_unordered import unordered
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.components.template import DOMAIN, async_setup_entry from homeassistant.components.template import DOMAIN, async_setup_entry
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType from homeassistant.data_entry_flow import FlowResultType
@ -276,7 +277,7 @@ async def test_options(
"{{ float(states('sensor.one'), default='') + float(states('sensor.two'), default='') }}", "{{ float(states('sensor.one'), default='') + float(states('sensor.two'), default='') }}",
{}, {},
{"one": "30.0", "two": "20.0"}, {"one": "30.0", "two": "20.0"},
["", "50.0"], ["", STATE_UNAVAILABLE, "50.0"],
[{}, {}], [{}, {}],
[["one", "two"], ["one", "two"]], [["one", "two"], ["one", "two"]],
), ),
@ -342,20 +343,24 @@ async def test_config_flow_preview(
hass.states.async_set( hass.states.async_set(
f"{template_type}.{input_entity}", input_states[input_entity], {} f"{template_type}.{input_entity}", input_states[input_entity], {}
) )
await hass.async_block_till_done()
msg = await client.receive_json() for template_state in template_states[1:]:
assert msg["event"] == { msg = await client.receive_json()
"attributes": {"friendly_name": "My template"} assert msg["event"] == {
| extra_attributes[0] "attributes": {"friendly_name": "My template"}
| extra_attributes[1], | extra_attributes[0]
"listeners": { | extra_attributes[1],
"all": False, "listeners": {
"domains": [], "all": False,
"entities": unordered([f"{template_type}.{_id}" for _id in listeners[1]]), "domains": [],
"time": False, "entities": unordered(
}, [f"{template_type}.{_id}" for _id in listeners[1]]
"state": template_states[1], ),
} "time": False,
},
"state": template_state,
}
assert len(hass.states.async_all()) == 2 assert len(hass.states.async_all()) == 2