Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions kasa/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,10 +509,13 @@ def __repr__(self) -> str:
update_needed = " - update() needed" if not self._last_update else ""
if not self._last_update and not self._discovery_info:
return f"<{self.device_type} at {self.host}{update_needed}>"
return (
f"<{self.device_type} at {self.host} -"
f" {self.alias} ({self.model}){update_needed}>"
)
try:
return (
f"<{self.device_type} at {self.host} -"
f" {self.alias} ({self.model}){update_needed}>"
)
except Exception:
return f"<{self.device_type} at {self.host}{update_needed}>"

_deprecated_device_type_attributes = {
# is_type
Expand Down
20 changes: 20 additions & 0 deletions tests/smart/test_smartdevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -1010,3 +1010,23 @@ async def test_unpair(dev: SmartDevice, mocker: MockerFixture):
await unpair_feat.set_value(None)

unpair_call.assert_called_with(child.device_id)


@device_smart
@pytest.mark.requires_dummy
async def test_device_info_with_smarterrorcode(dev: SmartDevice):
"""Test that __repr__ doesn't crash when get_device_info is a SmartErrorCode.

When a device returns INTERNAL_QUERY_ERROR for get_device_info, the response
is stored as a SmartErrorCode enum value instead of a dict. __repr__ accesses
.model which calls _get_device_info, and should not crash with
'SmartErrorCode object is not subscriptable'.

See https://github.com/python-kasa/python-kasa/issues/1671
"""
# Simulate the device returning an error for get_device_info
dev._last_update["get_device_info"] = SmartErrorCode.INTERNAL_QUERY_ERROR

# __repr__ should not raise
result = repr(dev)
assert dev.host in result
Loading