Avoid recreating ReadOnly dicts when attributes do not change (#106687)
parent
2177113c6e
commit
9e3869ae1c
|
@ -1409,7 +1409,13 @@ class State:
|
|||
|
||||
self.entity_id = entity_id
|
||||
self.state = state
|
||||
self.attributes = ReadOnlyDict(attributes or {})
|
||||
# State only creates and expects a ReadOnlyDict so
|
||||
# there is no need to check for subclassing with
|
||||
# isinstance here so we can use the faster type check.
|
||||
if type(attributes) is not ReadOnlyDict: # noqa: E721
|
||||
self.attributes = ReadOnlyDict(attributes or {})
|
||||
else:
|
||||
self.attributes = attributes
|
||||
self.last_updated = last_updated or dt_util.utcnow()
|
||||
self.last_changed = last_changed or self.last_updated
|
||||
self.context = context or Context()
|
||||
|
@ -1828,6 +1834,11 @@ class StateMachine:
|
|||
else:
|
||||
now = dt_util.utcnow()
|
||||
|
||||
if same_attr:
|
||||
if TYPE_CHECKING:
|
||||
assert old_state is not None
|
||||
attributes = old_state.attributes
|
||||
|
||||
state = State(
|
||||
entity_id,
|
||||
new_state,
|
||||
|
|
|
@ -1157,6 +1157,26 @@ async def test_statemachine_force_update(hass: HomeAssistant) -> None:
|
|||
assert len(events) == 1
|
||||
|
||||
|
||||
async def test_statemachine_avoids_updating_attributes(hass: HomeAssistant) -> None:
|
||||
"""Test async_set avoids recreating ReadOnly dicts when possible."""
|
||||
attrs = {"some_attr": "attr_value"}
|
||||
|
||||
hass.states.async_set("light.bowl", "off", attrs)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.bowl")
|
||||
assert state.attributes == attrs
|
||||
|
||||
hass.states.async_set("light.bowl", "on", attrs)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
new_state = hass.states.get("light.bowl")
|
||||
assert new_state.attributes == attrs
|
||||
|
||||
assert new_state.attributes is state.attributes
|
||||
assert isinstance(new_state.attributes, ReadOnlyDict)
|
||||
|
||||
|
||||
def test_service_call_repr() -> None:
|
||||
"""Test ServiceCall repr."""
|
||||
call = ha.ServiceCall("homeassistant", "start")
|
||||
|
|
Loading…
Reference in New Issue