GeezerVison is showing github.com — Make parent attribute on device consistent across iot and smart (#1023) · python-kasa/python-kasa@2687c71
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: kasa/device.py +5Lines changed: 5 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -328,6 +328,11 @@ async def _raw_query(self, request: str | dict) -> Any: | 328 | 328 | """Send a raw query to the device.""" | 329 | 329 | return await self.protocol.query(request=request) | 330 | 330 |
| | 331 | + @property | | 332 | + def parent(self) -> Device | None: | | 333 | + """Return the parent on child devices.""" | | 334 | + return self._parent | | 335 | + | 331 | 336 | @property | 332 | 337 | def children(self) -> Sequence[Device]: | 333 | 338 | """Returns the child devices.""" | |
Collapse file Copy file name to clipboardExpand all lines: kasa/iot/iotstrip.py +9-5Lines changed: 9 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -307,10 +307,12 @@ class IotStripPlug(IotPlug): | 307 | 307 | The plug inherits (most of) the system information from the parent. | 308 | 308 | """ | 309 | 309 |
| | 310 | + _parent: IotStrip | | 311 | + | 310 | 312 | def __init__(self, host: str, parent: IotStrip, child_id: str) -> None: | 311 | 313 | super().__init__(host) | 312 | 314 |
| 313 | | - self.parent = parent | | 315 | + self._parent = parent | 314 | 316 | self.child_id = child_id | 315 | 317 | self._last_update = parent._last_update | 316 | 318 | self._set_sys_info(parent.sys_info) | @@ -380,7 +382,7 @@ async def _query_helper( | 380 | 382 | self, target: str, cmd: str, arg: dict | None = None, child_ids=None | 381 | 383 | ) -> Any: | 382 | 384 | """Override query helper to include the child_ids.""" | 383 | | - return await self.parent._query_helper( | | 385 | + return await self._parent._query_helper( | 384 | 386 | target, cmd, arg, child_ids=[self.child_id] | 385 | 387 | ) | 386 | 388 |
| @@ -441,13 +443,15 @@ def on_since(self) -> datetime | None: | 441 | 443 | @requires_update | 442 | 444 | def model(self) -> str: | 443 | 445 | """Return device model for a child socket.""" | 444 | | - sys_info = self.parent.sys_info | | 446 | + sys_info = self._parent.sys_info | 445 | 447 | return f"Socket for {sys_info['model']}" | 446 | 448 |
| 447 | 449 | def _get_child_info(self) -> dict: | 448 | 450 | """Return the subdevice information for this device.""" | 449 | | - for plug in self.parent.sys_info["children"]: | | 451 | + for plug in self._parent.sys_info["children"]: | 450 | 452 | if plug["id"] == self.child_id: | 451 | 453 | return plug | 452 | 454 |
| 453 | | - raise KasaException(f"Unable to find children {self.child_id}") | | 455 | + raise KasaException( | | 456 | + f"Unable to find children {self.child_id}" | | 457 | + ) # pragma: no cover |
Collapse file Copy file name to clipboardExpand all lines: kasa/tests/test_childdevice.py +21-1Lines changed: 21 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 3 | 3 |
| 4 | 4 | import pytest | 5 | 5 |
| | 6 | +from kasa import Device | 6 | 7 | from kasa.device_type import DeviceType | 7 | 8 | from kasa.smart.smartchilddevice import SmartChildDevice | 8 | 9 | from kasa.smart.smartdevice import NON_HUB_PARENT_ONLY_MODULES | 9 | 10 | from kasa.smartprotocol import _ChildProtocolWrapper | 10 | 11 |
| 11 | | -from .conftest import parametrize, parametrize_subtract, strip_smart | | 12 | +from .conftest import ( | | 13 | + parametrize, | | 14 | + parametrize_combine, | | 15 | + parametrize_subtract, | | 16 | + strip_iot, | | 17 | + strip_smart, | | 18 | +) | 12 | 19 |
| 13 | 20 | has_children_smart = parametrize( | 14 | 21 | "has children", component_filter="control_child", protocol_filter={"SMART"} | | 18 | 25 | ) | 19 | 26 | non_hub_parent_smart = parametrize_subtract(has_children_smart, hub_smart) | 20 | 27 |
| | 28 | +has_children = parametrize_combine([has_children_smart, strip_iot]) | | 29 | + | 21 | 30 |
| 22 | 31 | @strip_smart | 23 | 32 | def test_childdevice_init(dev, dummy_protocol, mocker): | @@ -100,3 +109,14 @@ async def test_parent_only_modules(dev, dummy_protocol, mocker): | 100 | 109 | for child in dev.children: | 101 | 110 | for module in NON_HUB_PARENT_ONLY_MODULES: | 102 | 111 | assert module not in [type(module) for module in child.modules.values()] | | 112 | + | | 113 | + | | 114 | +@has_children | | 115 | +async def test_parent_property(dev: Device): | | 116 | + """Test a child device exposes it's parent.""" | | 117 | + if not dev.children: | | 118 | + pytest.skip(f"Device {dev} fixture does not have any children") | | 119 | + | | 120 | + assert dev.parent is None | | 121 | + for child in dev.children: | | 122 | + assert child.parent == dev |
|