Use strict typing for LiteJet integration (#88629)

* Strict typing for LiteJet.

* Add test for new check.

* PR feedback.

* PR feedback.
This commit is contained in:
Jon Caruana 2023-02-24 08:51:48 -08:00 committed by GitHub
parent ee7dfdae30
commit e69091c6db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 35 additions and 9 deletions

View File

@ -186,6 +186,7 @@ homeassistant.components.ld2410_ble.*
homeassistant.components.lidarr.* homeassistant.components.lidarr.*
homeassistant.components.lifx.* homeassistant.components.lifx.*
homeassistant.components.light.* homeassistant.components.light.*
homeassistant.components.litejet.*
homeassistant.components.litterrobot.* homeassistant.components.litterrobot.*
homeassistant.components.local_ip.* homeassistant.components.local_ip.*
homeassistant.components.lock.* homeassistant.components.lock.*

View File

@ -6,7 +6,7 @@ import voluptuous as vol
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import CONF_PORT, EVENT_HOMEASSISTANT_STOP from homeassistant.const import CONF_PORT, EVENT_HOMEASSISTANT_STOP
from homeassistant.core import HomeAssistant from homeassistant.core import Event, HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.exceptions import ConfigEntryNotReady
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
@ -63,7 +63,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
system.on_connected_changed(handle_connected_changed) system.on_connected_changed(handle_connected_changed)
async def handle_stop(event) -> None: async def handle_stop(event: Event) -> None:
await system.close() await system.close()
entry.async_on_unload( entry.async_on_unload(

View File

@ -76,7 +76,7 @@ class LiteJetConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
errors=errors, errors=errors,
) )
async def async_step_import(self, import_data): async def async_step_import(self, import_data: dict[str, Any]) -> FlowResult:
"""Import litejet config from configuration.yaml.""" """Import litejet config from configuration.yaml."""
return self.async_create_entry(title=import_data[CONF_PORT], data=import_data) return self.async_create_entry(title=import_data[CONF_PORT], data=import_data)

View File

@ -2,6 +2,8 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from datetime import datetime
from typing import cast
from pylitejet import LiteJet from pylitejet import LiteJet
import voluptuous as vol import voluptuous as vol
@ -42,7 +44,7 @@ async def async_attach_trigger(
) -> CALLBACK_TYPE: ) -> CALLBACK_TYPE:
"""Listen for events based on configuration.""" """Listen for events based on configuration."""
trigger_data = trigger_info["trigger_data"] trigger_data = trigger_info["trigger_data"]
number = config.get(CONF_NUMBER) number = cast(int, config[CONF_NUMBER])
held_more_than = config.get(CONF_HELD_MORE_THAN) held_more_than = config.get(CONF_HELD_MORE_THAN)
held_less_than = config.get(CONF_HELD_LESS_THAN) held_less_than = config.get(CONF_HELD_LESS_THAN)
pressed_time = None pressed_time = None
@ -50,7 +52,7 @@ async def async_attach_trigger(
job = HassJob(action) job = HassJob(action)
@callback @callback
def call_action(): def call_action() -> None:
"""Call action with right context.""" """Call action with right context."""
hass.async_run_hass_job( hass.async_run_hass_job(
job, job,
@ -72,11 +74,11 @@ async def async_attach_trigger(
# neither: trigger on pressed # neither: trigger on pressed
@callback @callback
def pressed_more_than_satisfied(now): def pressed_more_than_satisfied(now: datetime) -> None:
"""Handle the LiteJet's switch's button pressed >= held_more_than.""" """Handle the LiteJet's switch's button pressed >= held_more_than."""
call_action() call_action()
def pressed(): def pressed() -> None:
"""Handle the press of the LiteJet switch's button.""" """Handle the press of the LiteJet switch's button."""
nonlocal cancel_pressed_more_than, pressed_time nonlocal cancel_pressed_more_than, pressed_time
nonlocal held_less_than, held_more_than nonlocal held_less_than, held_more_than
@ -88,10 +90,12 @@ async def async_attach_trigger(
hass, pressed_more_than_satisfied, dt_util.utcnow() + held_more_than hass, pressed_more_than_satisfied, dt_util.utcnow() + held_more_than
) )
def released(): def released() -> None:
"""Handle the release of the LiteJet switch's button.""" """Handle the release of the LiteJet switch's button."""
nonlocal cancel_pressed_more_than, pressed_time nonlocal cancel_pressed_more_than, pressed_time
nonlocal held_less_than, held_more_than nonlocal held_less_than, held_more_than
if pressed_time is None:
return
if cancel_pressed_more_than is not None: if cancel_pressed_more_than is not None:
cancel_pressed_more_than() cancel_pressed_more_than()
cancel_pressed_more_than = None cancel_pressed_more_than = None
@ -110,7 +114,7 @@ async def async_attach_trigger(
system.on_switch_released(number, released) system.on_switch_released(number, released)
@callback @callback
def async_remove(): def async_remove() -> None:
"""Remove all subscriptions used for this trigger.""" """Remove all subscriptions used for this trigger."""
system.unsubscribe(pressed) system.unsubscribe(pressed)
system.unsubscribe(released) system.unsubscribe(released)

View File

@ -1622,6 +1622,16 @@ disallow_untyped_defs = true
warn_return_any = true warn_return_any = true
warn_unreachable = true warn_unreachable = true
[mypy-homeassistant.components.litejet.*]
check_untyped_defs = true
disallow_incomplete_defs = true
disallow_subclassing_any = true
disallow_untyped_calls = true
disallow_untyped_decorators = true
disallow_untyped_defs = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.litterrobot.*] [mypy-homeassistant.components.litterrobot.*]
check_untyped_defs = true check_untyped_defs = true
disallow_incomplete_defs = true disallow_incomplete_defs = true

View File

@ -107,6 +107,17 @@ async def test_simple(hass: HomeAssistant, calls, mock_litejet) -> None:
assert calls[0].data["id"] == 0 assert calls[0].data["id"] == 0
async def test_only_release(hass: HomeAssistant, calls, mock_litejet) -> None:
"""Test the simplest form of a LiteJet trigger."""
await setup_automation(
hass, {"platform": "litejet", "number": ENTITY_OTHER_SWITCH_NUMBER}
)
await simulate_release(hass, mock_litejet, ENTITY_OTHER_SWITCH_NUMBER)
assert len(calls) == 0
async def test_held_more_than_short(hass: HomeAssistant, calls, mock_litejet) -> None: async def test_held_more_than_short(hass: HomeAssistant, calls, mock_litejet) -> None:
"""Test a too short hold.""" """Test a too short hold."""
await setup_automation( await setup_automation(