Improve iteration in device registry + add tests

This commit is contained in:
Erik
2026-08-24 08:40:06 +02:00
parent ad3c2445c6
commit 74776af4c1
3 changed files with 36 additions and 3 deletions
@@ -1,5 +1,6 @@
"""HTTP views to interact with the device registry."""
from itertools import chain
import logging
from typing import Any
@@ -92,7 +93,7 @@ def websocket_list_devices(
inner = b",".join(
[
entry.json_repr
for entry in (*registry.devices, *registry.child_devices)
for entry in chain(registry.devices, registry.child_devices)
if entry.json_repr is not None
]
)
@@ -1,6 +1,7 @@
"""Device functions for Home Assistant templates."""
from collections.abc import Iterable
from itertools import chain
from typing import TYPE_CHECKING, Any
import voluptuous as vol
@@ -85,7 +86,7 @@ class DeviceExtension(BaseTemplateExtension):
return next(
(
device.id
for device in (*dev_reg.devices, *dev_reg.child_devices)
for device in chain(dev_reg.devices, dev_reg.child_devices)
if (name := device.name_by_user or device.name)
and (str(entity_id_or_device_name) == name)
),
+32 -1
View File
@@ -4365,6 +4365,34 @@ async def test_devices_collection_operations(
assert entry in device_registry.devices
async def test_child_devices_collection_operations(
device_registry: dr.DeviceRegistry,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test the supported `Collection[ChildDeviceEntry]` surface of `child_devices`.
Iteration yields the entries (not the ids), `len()` returns the count, and
`ChildDeviceEntry` membership works. Unlike `DeviceRegistry.devices`, the child
collection is a plain read-only view, so mapping-style access, `.values()`, and
mutation are unavailable.
"""
_, child_device = _create_parent_and_child(
device_registry, mock_config_entry.entry_id
)
assert list(device_registry.child_devices) == [child_device]
assert [device.id for device in device_registry.child_devices] == [child_device.id]
assert len(device_registry.child_devices) == 1
assert child_device in device_registry.child_devices
with pytest.raises(TypeError):
_ = device_registry.child_devices[child_device.id] # type: ignore[index]
with pytest.raises(AttributeError):
device_registry.child_devices.values() # type: ignore[attr-defined]
with pytest.raises(TypeError):
device_registry.child_devices[child_device.id] = child_device # type: ignore[index]
@pytest.mark.parametrize(
("integration_frame_path", "expectation", "expected_log"),
[
@@ -11123,7 +11151,10 @@ async def test_link_device_info_matching_child_raises(
# The child device is left untouched: not converted, no new device created
assert len(device_registry.devices) == 1
assert len(device_registry.child_devices) == 1
assert device_registry._child_devices[child_device.id] == child_device
assert (
device_registry.async_get(child_device.id, include_main_devices=False)
== child_device
)
assert child_device.identifiers == {("test", "strip_outlet_1")}