Deprecate device level light, effect and led attributes (#916)

Deprecates the attributes at device level for light, light effects, and led. i.e. device.led, device.is_color. Will continue to support consumers using these attributes and emit a warning.
This commit is contained in:
Steven B
2024-05-15 18:49:08 +01:00
committed by GitHub
parent 133a839f22
commit a2e8d2c4e8
10 changed files with 232 additions and 172 deletions

View File

@@ -9,7 +9,7 @@ from unittest.mock import Mock, patch
import pytest
import kasa
from kasa import Credentials, Device, DeviceConfig, DeviceType
from kasa import Credentials, Device, DeviceConfig, DeviceType, KasaException, Module
from kasa.iot import IotDevice
from kasa.smart import SmartChildDevice, SmartDevice
@@ -139,14 +139,12 @@ deprecated_is_light_function_smart_module = {
}
def test_deprecated_attributes(dev: SmartDevice):
def test_deprecated_device_type_attributes(dev: SmartDevice):
"""Test deprecated attributes on all devices."""
tested_keys = set()
def _test_attr(attribute):
tested_keys.add(attribute)
msg = f"{attribute} is deprecated"
if module := Device._deprecated_attributes[attribute][0]:
if module := Device._deprecated_device_type_attributes[attribute][0]:
msg += f", use: {module} in device.modules instead"
with pytest.deprecated_call(match=msg):
val = getattr(dev, attribute)
@@ -157,20 +155,86 @@ def test_deprecated_attributes(dev: SmartDevice):
expected_val = dev.device_type == deprecated_is_device_type[attribute]
assert val == expected_val
for attribute in deprecated_is_light_function_smart_module:
val = _test_attr(attribute)
if isinstance(dev, SmartDevice):
expected_val = (
deprecated_is_light_function_smart_module[attribute] in dev.modules
)
elif hasattr(dev, f"_{attribute}"):
expected_val = getattr(dev, f"_{attribute}")
else:
expected_val = False
assert val == expected_val
assert len(tested_keys) == len(Device._deprecated_attributes)
untested_keys = [
key for key in Device._deprecated_attributes if key not in tested_keys
]
assert len(untested_keys) == 0
async def _test_attribute(
dev: Device, attribute_name, is_expected, module_name, *args, will_raise=False
):
if is_expected and will_raise:
ctx = pytest.raises(will_raise)
elif is_expected:
ctx = pytest.deprecated_call(
match=(
f"{attribute_name} is deprecated, use: Module."
+ f"{module_name} in device.modules instead"
)
)
else:
ctx = pytest.raises(
AttributeError, match=f"Device has no attribute '{attribute_name}'"
)
with ctx:
if args:
await getattr(dev, attribute_name)(*args)
else:
attribute_val = getattr(dev, attribute_name)
assert attribute_val is not None
async def test_deprecated_light_effect_attributes(dev: Device):
light_effect = dev.modules.get(Module.LightEffect)
await _test_attribute(dev, "effect", bool(light_effect), "LightEffect")
await _test_attribute(dev, "effect_list", bool(light_effect), "LightEffect")
await _test_attribute(dev, "set_effect", bool(light_effect), "LightEffect", "Off")
exc = (
NotImplementedError
if light_effect and not light_effect.has_custom_effects
else None
)
await _test_attribute(
dev,
"set_custom_effect",
bool(light_effect),
"LightEffect",
{"enable": 0, "name": "foo", "id": "bar"},
will_raise=exc,
)
async def test_deprecated_light_attributes(dev: Device):
light = dev.modules.get(Module.Light)
await _test_attribute(dev, "is_dimmable", bool(light), "Light")
await _test_attribute(dev, "is_color", bool(light), "Light")
await _test_attribute(dev, "is_variable_color_temp", bool(light), "Light")
exc = KasaException if light and not light.is_dimmable else None
await _test_attribute(dev, "brightness", bool(light), "Light", will_raise=exc)
await _test_attribute(
dev, "set_brightness", bool(light), "Light", 50, will_raise=exc
)
exc = KasaException if light and not light.is_color else None
await _test_attribute(dev, "hsv", bool(light), "Light", will_raise=exc)
await _test_attribute(
dev, "set_hsv", bool(light), "Light", 50, 50, 50, will_raise=exc
)
exc = KasaException if light and not light.is_variable_color_temp else None
await _test_attribute(dev, "color_temp", bool(light), "Light", will_raise=exc)
await _test_attribute(
dev, "set_color_temp", bool(light), "Light", 2700, will_raise=exc
)
await _test_attribute(
dev, "valid_temperature_range", bool(light), "Light", will_raise=exc
)
await _test_attribute(dev, "has_effects", bool(light), "Light")
async def test_deprecated_other_attributes(dev: Device):
led_module = dev.modules.get(Module.Led)
await _test_attribute(dev, "led", bool(led_module), "Led")
await _test_attribute(dev, "set_led", bool(led_module), "Led", True)