Enable strict-typing in lovelace (#136327)
parent
33ce795695
commit
83e826219a
|
@ -307,6 +307,7 @@ homeassistant.components.logbook.*
|
|||
homeassistant.components.logger.*
|
||||
homeassistant.components.london_underground.*
|
||||
homeassistant.components.lookin.*
|
||||
homeassistant.components.lovelace.*
|
||||
homeassistant.components.luftdaten.*
|
||||
homeassistant.components.madvr.*
|
||||
homeassistant.components.manual.*
|
||||
|
|
|
@ -81,7 +81,7 @@ class LovelaceData:
|
|||
|
||||
mode: str
|
||||
dashboards: dict[str | None, dashboard.LovelaceConfig]
|
||||
resources: resources.ResourceStorageCollection
|
||||
resources: resources.ResourceYAMLCollection | resources.ResourceStorageCollection
|
||||
yaml_dashboards: dict[str | None, ConfigType]
|
||||
|
||||
|
||||
|
@ -115,6 +115,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
hass.data[LOVELACE_DATA].resources = resource_collection
|
||||
|
||||
default_config: dashboard.LovelaceConfig
|
||||
resource_collection: (
|
||||
resources.ResourceYAMLCollection | resources.ResourceStorageCollection
|
||||
)
|
||||
if mode == MODE_YAML:
|
||||
default_config = dashboard.LovelaceYAML(hass, None, None)
|
||||
resource_collection = await create_yaml_resource_col(hass, yaml_resources)
|
||||
|
@ -174,7 +177,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
if hass.config.recovery_mode:
|
||||
return True
|
||||
|
||||
async def storage_dashboard_changed(change_type, item_id, item):
|
||||
async def storage_dashboard_changed(
|
||||
change_type: str, item_id: str, item: dict
|
||||
) -> None:
|
||||
"""Handle a storage dashboard change."""
|
||||
url_path = item[CONF_URL_PATH]
|
||||
|
||||
|
@ -236,7 +241,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
return True
|
||||
|
||||
|
||||
async def create_yaml_resource_col(hass, yaml_resources):
|
||||
async def create_yaml_resource_col(
|
||||
hass: HomeAssistant, yaml_resources: list[ConfigType] | None
|
||||
) -> resources.ResourceYAMLCollection:
|
||||
"""Create yaml resources collection."""
|
||||
if yaml_resources is None:
|
||||
default_config = dashboard.LovelaceYAML(hass, None, None)
|
||||
|
@ -256,7 +263,9 @@ async def create_yaml_resource_col(hass, yaml_resources):
|
|||
|
||||
|
||||
@callback
|
||||
def _register_panel(hass, url_path, mode, config, update):
|
||||
def _register_panel(
|
||||
hass: HomeAssistant, url_path: str | None, mode: str, config: dict, update: bool
|
||||
) -> None:
|
||||
"""Register a panel."""
|
||||
kwargs = {
|
||||
"frontend_url_path": url_path,
|
||||
|
|
|
@ -7,7 +7,7 @@ import logging
|
|||
import os
|
||||
from pathlib import Path
|
||||
import time
|
||||
from typing import Any
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -67,21 +67,25 @@ class LovelaceConfig(ABC):
|
|||
"""Return mode of the lovelace config."""
|
||||
|
||||
@abstractmethod
|
||||
async def async_get_info(self):
|
||||
async def async_get_info(self) -> dict[str, Any]:
|
||||
"""Return the config info."""
|
||||
|
||||
@abstractmethod
|
||||
async def async_load(self, force: bool) -> dict[str, Any]:
|
||||
"""Load config."""
|
||||
|
||||
async def async_save(self, config):
|
||||
async def async_save(self, config: dict[str, Any]) -> None:
|
||||
"""Save config."""
|
||||
raise HomeAssistantError("Not supported")
|
||||
|
||||
async def async_delete(self):
|
||||
async def async_delete(self) -> None:
|
||||
"""Delete config."""
|
||||
raise HomeAssistantError("Not supported")
|
||||
|
||||
@abstractmethod
|
||||
async def async_json(self, force: bool) -> json_fragment:
|
||||
"""Return JSON representation of the config."""
|
||||
|
||||
@callback
|
||||
def _config_updated(self) -> None:
|
||||
"""Fire config updated event."""
|
||||
|
@ -113,7 +117,7 @@ class LovelaceStorage(LovelaceConfig):
|
|||
"""Return mode of the lovelace config."""
|
||||
return MODE_STORAGE
|
||||
|
||||
async def async_get_info(self):
|
||||
async def async_get_info(self) -> dict[str, Any]:
|
||||
"""Return the Lovelace storage info."""
|
||||
data = self._data or await self._load()
|
||||
if data["config"] is None:
|
||||
|
@ -129,7 +133,7 @@ class LovelaceStorage(LovelaceConfig):
|
|||
if (config := data["config"]) is None:
|
||||
raise ConfigNotFound
|
||||
|
||||
return config
|
||||
return config # type: ignore[no-any-return]
|
||||
|
||||
async def async_json(self, force: bool) -> json_fragment:
|
||||
"""Return JSON representation of the config."""
|
||||
|
@ -139,19 +143,21 @@ class LovelaceStorage(LovelaceConfig):
|
|||
await self._load()
|
||||
return self._json_config or self._async_build_json()
|
||||
|
||||
async def async_save(self, config):
|
||||
async def async_save(self, config: dict[str, Any]) -> None:
|
||||
"""Save config."""
|
||||
if self.hass.config.recovery_mode:
|
||||
raise HomeAssistantError("Saving not supported in recovery mode")
|
||||
|
||||
if self._data is None:
|
||||
await self._load()
|
||||
if TYPE_CHECKING:
|
||||
assert self._data is not None
|
||||
self._data["config"] = config
|
||||
self._json_config = None
|
||||
self._config_updated()
|
||||
await self._store.async_save(self._data)
|
||||
|
||||
async def async_delete(self):
|
||||
async def async_delete(self) -> None:
|
||||
"""Delete config."""
|
||||
if self.hass.config.recovery_mode:
|
||||
raise HomeAssistantError("Deleting not supported in recovery mode")
|
||||
|
@ -195,7 +201,7 @@ class LovelaceYAML(LovelaceConfig):
|
|||
"""Return mode of the lovelace config."""
|
||||
return MODE_YAML
|
||||
|
||||
async def async_get_info(self):
|
||||
async def async_get_info(self) -> dict[str, Any]:
|
||||
"""Return the YAML storage mode."""
|
||||
try:
|
||||
config = await self.async_load(False)
|
||||
|
@ -251,7 +257,7 @@ class LovelaceYAML(LovelaceConfig):
|
|||
return is_updated, config, json
|
||||
|
||||
|
||||
def _config_info(mode, config):
|
||||
def _config_info(mode: str, config: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Generate info about the config."""
|
||||
return {
|
||||
"mode": mode,
|
||||
|
@ -265,7 +271,7 @@ class DashboardsCollection(collection.DictStorageCollection):
|
|||
CREATE_SCHEMA = vol.Schema(STORAGE_DASHBOARD_CREATE_FIELDS)
|
||||
UPDATE_SCHEMA = vol.Schema(STORAGE_DASHBOARD_UPDATE_FIELDS)
|
||||
|
||||
def __init__(self, hass):
|
||||
def __init__(self, hass: HomeAssistant) -> None:
|
||||
"""Initialize the dashboards collection."""
|
||||
super().__init__(
|
||||
storage.Store(hass, DASHBOARDS_STORAGE_VERSION, DASHBOARDS_STORAGE_KEY),
|
||||
|
@ -283,12 +289,12 @@ class DashboardsCollection(collection.DictStorageCollection):
|
|||
if url_path in self.hass.data[DATA_PANELS]:
|
||||
raise vol.Invalid("Panel url path needs to be unique")
|
||||
|
||||
return self.CREATE_SCHEMA(data)
|
||||
return self.CREATE_SCHEMA(data) # type: ignore[no-any-return]
|
||||
|
||||
@callback
|
||||
def _get_suggested_id(self, info: dict) -> str:
|
||||
"""Suggest an ID based on the config."""
|
||||
return info[CONF_URL_PATH]
|
||||
return info[CONF_URL_PATH] # type: ignore[no-any-return]
|
||||
|
||||
async def _update_data(self, item: dict, update_data: dict) -> dict:
|
||||
"""Return a new updated data object."""
|
||||
|
|
|
@ -34,11 +34,11 @@ class ResourceYAMLCollection:
|
|||
|
||||
loaded = True
|
||||
|
||||
def __init__(self, data):
|
||||
def __init__(self, data: list[dict[str, Any]]) -> None:
|
||||
"""Initialize a resource YAML collection."""
|
||||
self.data = data
|
||||
|
||||
async def async_get_info(self):
|
||||
async def async_get_info(self) -> dict[str, int]:
|
||||
"""Return the resources info for YAML mode."""
|
||||
return {"resources": len(self.async_items() or [])}
|
||||
|
||||
|
@ -62,7 +62,7 @@ class ResourceStorageCollection(collection.DictStorageCollection):
|
|||
)
|
||||
self.ll_config = ll_config
|
||||
|
||||
async def async_get_info(self):
|
||||
async def async_get_info(self) -> dict[str, int]:
|
||||
"""Return the resources info for YAML mode."""
|
||||
if not self.loaded:
|
||||
await self.async_load()
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from functools import wraps
|
||||
from typing import Any
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -14,10 +15,20 @@ from homeassistant.helpers import config_validation as cv
|
|||
from homeassistant.helpers.json import json_fragment
|
||||
|
||||
from .const import CONF_URL_PATH, LOVELACE_DATA, ConfigNotFound
|
||||
from .dashboard import LovelaceStorage
|
||||
from .dashboard import LovelaceConfig
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .resources import ResourceStorageCollection
|
||||
|
||||
type AsyncLovelaceWebSocketCommandHandler[_R] = Callable[
|
||||
[HomeAssistant, websocket_api.ActiveConnection, dict[str, Any], LovelaceConfig],
|
||||
Awaitable[_R],
|
||||
]
|
||||
|
||||
|
||||
def _handle_errors(func):
|
||||
def _handle_errors[_R](
|
||||
func: AsyncLovelaceWebSocketCommandHandler[_R],
|
||||
) -> websocket_api.AsyncWebSocketCommandHandler:
|
||||
"""Handle error with WebSocket calls."""
|
||||
|
||||
@wraps(func)
|
||||
|
@ -75,6 +86,8 @@ async def websocket_lovelace_resources_impl(
|
|||
This function is called by both Storage and YAML mode WS handlers.
|
||||
"""
|
||||
resources = hass.data[LOVELACE_DATA].resources
|
||||
if TYPE_CHECKING:
|
||||
assert isinstance(resources, ResourceStorageCollection)
|
||||
|
||||
if hass.config.safe_mode:
|
||||
connection.send_result(msg["id"], [])
|
||||
|
@ -100,7 +113,7 @@ async def websocket_lovelace_config(
|
|||
hass: HomeAssistant,
|
||||
connection: websocket_api.ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
config: LovelaceStorage,
|
||||
config: LovelaceConfig,
|
||||
) -> json_fragment:
|
||||
"""Send Lovelace UI config over WebSocket connection."""
|
||||
return await config.async_json(msg["force"])
|
||||
|
@ -120,7 +133,7 @@ async def websocket_lovelace_save_config(
|
|||
hass: HomeAssistant,
|
||||
connection: websocket_api.ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
config: LovelaceStorage,
|
||||
config: LovelaceConfig,
|
||||
) -> None:
|
||||
"""Save Lovelace UI configuration."""
|
||||
await config.async_save(msg["config"])
|
||||
|
@ -139,7 +152,7 @@ async def websocket_lovelace_delete_config(
|
|||
hass: HomeAssistant,
|
||||
connection: websocket_api.ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
config: LovelaceStorage,
|
||||
config: LovelaceConfig,
|
||||
) -> None:
|
||||
"""Delete Lovelace UI configuration."""
|
||||
await config.async_delete()
|
||||
|
|
|
@ -2826,6 +2826,16 @@ disallow_untyped_defs = true
|
|||
warn_return_any = true
|
||||
warn_unreachable = true
|
||||
|
||||
[mypy-homeassistant.components.lovelace.*]
|
||||
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.luftdaten.*]
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
|
|
Loading…
Reference in New Issue