tests: fix typos, child device subtype, CLI patch path, and deprecation test logic (#1677)

This commit is contained in:
ZeliardM
2026-07-05 12:16:41 -04:00
committed by GitHub
parent 76d9f68547
commit 440f1f453b
6 changed files with 22 additions and 13 deletions

View File

@@ -64,7 +64,7 @@ Many thanks to testers and new contributors - @steveredden, @DawidPietrykowski,
**Breaking changes:** **Breaking changes:**
- `uses_http` is now a readonly property of device config. Consumers that relied on `uses_http` to be persisted with `DeviceConfig.to_dict()` will need to store the value separately. - `uses_http` is now a readonly property of device config. Consumers that relied on `uses_http` to be persisted with `DeviceConfig.to_dict()` will need to store the value separately.
- `is_color`, `is_dimmable`, `is_variable_color_temp`, `valid_temperate_range`, and `has_effects` attributes from the `Light` module are deprecated, consumers should use `has_feature("hsv")`, `has_feature("brightness")`, `has_feature("color_temp")`, `get_feature("color_temp").range`, and `Module.LightEffect in dev.modules` respectively. Calling the deprecated attributes will emit a `DeprecationWarning` and type checkers will fail them. - `is_color`, `is_dimmable`, `is_variable_color_temp`, `valid_temperature_range`, and `has_effects` attributes from the `Light` module are deprecated, consumers should use `has_feature("hsv")`, `has_feature("brightness")`, `has_feature("color_temp")`, `get_feature("color_temp").range`, and `Module.LightEffect in dev.modules` respectively. Calling the deprecated attributes will emit a `DeprecationWarning` and type checkers will fail them.
- `alarm_volume` on the `smart.Alarm` module is changed from `str` to `int` - `alarm_volume` on the `smart.Alarm` module is changed from `str` to `int`
**Breaking changes:** **Breaking changes:**

View File

@@ -24,6 +24,7 @@ class SmartChildDevice(SmartDevice):
CHILD_DEVICE_TYPE_MAP = { CHILD_DEVICE_TYPE_MAP = {
"plug.powerstrip.sub-plug": DeviceType.Plug, "plug.powerstrip.sub-plug": DeviceType.Plug,
"plug.powerstrip.sub-bulb": DeviceType.Bulb,
"subg.plugswitch.switch": DeviceType.WallSwitch, "subg.plugswitch.switch": DeviceType.WallSwitch,
"subg.trigger.contact-sensor": DeviceType.Sensor, "subg.trigger.contact-sensor": DeviceType.Sensor,
"subg.trigger.temp-hmdt-sensor": DeviceType.Sensor, "subg.trigger.temp-hmdt-sensor": DeviceType.Sensor,

View File

@@ -182,7 +182,7 @@ convention = "pep257"
warn_unused_configs = true # warns if overrides sections unused/mis-spelled warn_unused_configs = true # warns if overrides sections unused/mis-spelled
[[tool.mypy.overrides]] [[tool.mypy.overrides]]
module = [ "kasa.tests.*", "devtools.*" ] module = [ "tests.*", "devtools.*" ]
disable_error_code = "annotation-unchecked" disable_error_code = "annotation-unchecked"
[[tool.mypy.overrides]] [[tool.mypy.overrides]]

View File

@@ -130,9 +130,7 @@ async def test_list_devices(discovery_mock, runner):
async def test_discover_raw(discovery_mock, runner, mocker): async def test_discover_raw(discovery_mock, runner, mocker):
"""Test the discover raw command.""" """Test the discover raw command."""
redact_spy = mocker.patch( redact_spy = mocker.patch("kasa.cli.discover.redact_data", side_effect=redact_data)
"kasa.protocols.protocol.redact_data", side_effect=redact_data
)
res = await runner.invoke( res = await runner.invoke(
cli, cli,
["--username", "foo", "--password", "bar", "discover", "raw"], ["--username", "foo", "--password", "bar", "discover", "raw"],

View File

@@ -217,6 +217,13 @@ deprecated_is_device_type = {
"is_strip": DeviceType.Strip, "is_strip": DeviceType.Strip,
"is_strip_socket": DeviceType.StripSocket, "is_strip_socket": DeviceType.StripSocket,
} }
deprecated_warns_before_attribute_error = {
"has_effects",
"is_color",
"is_dimmable",
"is_variable_color_temp",
"valid_temperature_range",
}
deprecated_is_light_function_smart_module = { deprecated_is_light_function_smart_module = {
"is_color": "Color", "is_color": "Color",
"is_dimmable": "Brightness", "is_dimmable": "Brightness",
@@ -244,20 +251,23 @@ def test_deprecated_device_type_attributes(dev: SmartDevice):
async def _test_attribute( async def _test_attribute(
dev: Device, attribute_name, is_expected, module_name, *args, will_raise=False dev: Device, attribute_name, is_expected, module_name, *args, will_raise=False
): ):
if is_expected and will_raise: will_warn = is_expected or attribute_name in deprecated_warns_before_attribute_error
if will_raise:
ctx: AbstractContextManager | nullcontext = pytest.raises(will_raise) ctx: AbstractContextManager | nullcontext = pytest.raises(will_raise)
dep_context: pytest.WarningsRecorder | nullcontext = pytest.deprecated_call( dep_context: pytest.WarningsRecorder | nullcontext
match=(f"{attribute_name} is deprecated, use:")
)
elif is_expected: elif is_expected:
ctx = nullcontext() ctx = nullcontext()
dep_context = pytest.deprecated_call(
match=(f"{attribute_name} is deprecated, use:")
)
else: else:
ctx = pytest.raises( ctx = pytest.raises(
AttributeError, match=f"Device has no attribute '{attribute_name}'" AttributeError, match=f"Device has no attribute '{attribute_name}'"
) )
if will_warn:
dep_context = pytest.deprecated_call(
match=(f"{attribute_name} is deprecated, use:")
)
else:
dep_context = nullcontext() dep_context = nullcontext()
with dep_context, ctx: with dep_context, ctx:

View File

@@ -415,7 +415,7 @@ async def test_device_update_from_new_discovery_info(discovery_mock):
KasaException, KasaException,
match=re.escape("You need to await update() to access the data"), match=re.escape("You need to await update() to access the data"),
): ):
assert device.supported_modules assert device.modules
async def test_discover_single_http_client(discovery_mock, mocker): async def test_discover_single_http_client(discovery_mock, mocker):