Update typing 16 (#48087)
parent
0f5efca76b
commit
4cb7718192
|
@ -43,7 +43,7 @@ class User:
|
|||
groups: list[Group] = attr.ib(factory=list, eq=False, order=False)
|
||||
|
||||
# List of credentials of a user.
|
||||
credentials: list["Credentials"] = attr.ib(factory=list, eq=False, order=False)
|
||||
credentials: list[Credentials] = attr.ib(factory=list, eq=False, order=False)
|
||||
|
||||
# Tokens associated with a user.
|
||||
refresh_tokens: dict[str, "RefreshToken"] = attr.ib(
|
||||
|
|
|
@ -76,7 +76,7 @@ STAGE_1_INTEGRATIONS = {
|
|||
|
||||
|
||||
async def async_setup_hass(
|
||||
runtime_config: "RuntimeConfig",
|
||||
runtime_config: RuntimeConfig,
|
||||
) -> core.HomeAssistant | None:
|
||||
"""Set up Home Assistant."""
|
||||
hass = core.HomeAssistant()
|
||||
|
|
|
@ -253,7 +253,7 @@ class AlexaEntity:
|
|||
The API handlers should manipulate entities only through this interface.
|
||||
"""
|
||||
|
||||
def __init__(self, hass: HomeAssistant, config: "AbstractConfig", entity: State):
|
||||
def __init__(self, hass: HomeAssistant, config: AbstractConfig, entity: State):
|
||||
"""Initialize Alexa Entity."""
|
||||
self.hass = hass
|
||||
self.config = config
|
||||
|
|
|
@ -15,13 +15,13 @@ class ChromecastInfo:
|
|||
This also has the same attributes as the mDNS fields by zeroconf.
|
||||
"""
|
||||
|
||||
services: Optional[set] = attr.ib()
|
||||
uuid: Optional[str] = attr.ib(
|
||||
services: set | None = attr.ib()
|
||||
uuid: str | None = attr.ib(
|
||||
converter=attr.converters.optional(str), default=None
|
||||
) # always convert UUID to string if not None
|
||||
_manufacturer = attr.ib(type=Optional[str], default=None)
|
||||
model_name: str = attr.ib(default="")
|
||||
friendly_name: Optional[str] = attr.ib(default=None)
|
||||
friendly_name: str | None = attr.ib(default=None)
|
||||
is_audio_group = attr.ib(type=Optional[bool], default=False)
|
||||
is_dynamic_group = attr.ib(type=Optional[bool], default=None)
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ class RuntimeEntryData:
|
|||
"""Store runtime data for esphome config entries."""
|
||||
|
||||
entry_id: str = attr.ib()
|
||||
client: "APIClient" = attr.ib()
|
||||
client: APIClient = attr.ib()
|
||||
store: Store = attr.ib()
|
||||
reconnect_task: asyncio.Task | None = attr.ib(default=None)
|
||||
state: dict[str, dict[str, Any]] = attr.ib(factory=dict)
|
||||
|
|
|
@ -225,7 +225,7 @@ class HERETravelTimeSensor(Entity):
|
|||
destination: str,
|
||||
origin_entity_id: str,
|
||||
destination_entity_id: str,
|
||||
here_data: "HERETravelTimeData",
|
||||
here_data: HERETravelTimeData,
|
||||
) -> None:
|
||||
"""Initialize the sensor."""
|
||||
self._name = name
|
||||
|
|
|
@ -78,7 +78,7 @@ async def async_setup_entry(
|
|||
@callback
|
||||
def init_controller(ctrl: Controller):
|
||||
"""Register the controller device and the containing zones."""
|
||||
conf = hass.data.get(DATA_CONFIG) # type: ConfigType
|
||||
conf: ConfigType = hass.data.get(DATA_CONFIG)
|
||||
|
||||
# Filter out any entities excluded in the config file
|
||||
if conf and ctrl.device_uid in conf[CONF_EXCLUDE]:
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
"""Lovelace dashboard support."""
|
||||
from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
import logging
|
||||
import os
|
||||
|
@ -231,7 +233,7 @@ class DashboardsCollection(collection.StorageCollection):
|
|||
_LOGGER,
|
||||
)
|
||||
|
||||
async def _async_load_data(self) -> Optional[dict]:
|
||||
async def _async_load_data(self) -> dict | None:
|
||||
"""Load the data."""
|
||||
data = await self.store.async_load()
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ def supports_push(hass, webhook_id: str) -> bool:
|
|||
@callback
|
||||
def get_notify_service(hass, webhook_id: str) -> str | None:
|
||||
"""Return the notify service for this webhook ID."""
|
||||
notify_service: "MobileAppNotificationService" = hass.data[DOMAIN][DATA_NOTIFY]
|
||||
notify_service: MobileAppNotificationService = hass.data[DOMAIN][DATA_NOTIFY]
|
||||
|
||||
for target_service, target_webhook_id in notify_service.registered_targets.items():
|
||||
if target_webhook_id == webhook_id:
|
||||
|
|
|
@ -87,7 +87,7 @@ class TriggerInstance:
|
|||
|
||||
action: AutomationActionType = attr.ib()
|
||||
automation_info: dict = attr.ib()
|
||||
trigger: "Trigger" = attr.ib()
|
||||
trigger: Trigger = attr.ib()
|
||||
remove: CALLBACK_TYPE | None = attr.ib(default=None)
|
||||
|
||||
async def async_attach_trigger(self):
|
||||
|
|
|
@ -69,7 +69,7 @@ ATTR_RSSI = "rssi"
|
|||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up the Shark IQ vacuum cleaner."""
|
||||
coordinator: SharkIqUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||
devices: Iterable["SharkIqVacuum"] = coordinator.shark_vacs.values()
|
||||
devices: Iterable[SharkIqVacuum] = coordinator.shark_vacs.values()
|
||||
device_names = [d.name for d in devices]
|
||||
_LOGGER.debug(
|
||||
"Found %d Shark IQ device(s): %s",
|
||||
|
|
|
@ -60,7 +60,7 @@ async def _register_system_health_platform(hass, integration_domain, platform):
|
|||
|
||||
|
||||
async def get_integration_info(
|
||||
hass: HomeAssistant, registration: "SystemHealthRegistration"
|
||||
hass: HomeAssistant, registration: SystemHealthRegistration
|
||||
):
|
||||
"""Get integration system health."""
|
||||
try:
|
||||
|
|
|
@ -48,7 +48,7 @@ class TriggerInstance:
|
|||
|
||||
action: AutomationActionType = attr.ib()
|
||||
automation_info: dict = attr.ib()
|
||||
trigger: "Trigger" = attr.ib()
|
||||
trigger: Trigger = attr.ib()
|
||||
remove: CALLBACK_TYPE | None = attr.ib(default=None)
|
||||
|
||||
async def async_attach_trigger(self):
|
||||
|
|
|
@ -3,7 +3,6 @@ from __future__ import annotations
|
|||
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import List
|
||||
|
||||
import transmissionrpc
|
||||
from transmissionrpc.error import TransmissionError
|
||||
|
@ -173,8 +172,8 @@ class TransmissionClient:
|
|||
"""Initialize the Transmission RPC API."""
|
||||
self.hass = hass
|
||||
self.config_entry = config_entry
|
||||
self.tm_api = None # type: transmissionrpc.Client
|
||||
self._tm_data = None # type: TransmissionData
|
||||
self.tm_api: transmissionrpc.Client = None
|
||||
self._tm_data: TransmissionData = None
|
||||
self.unsub_timer = None
|
||||
|
||||
@property
|
||||
|
@ -345,14 +344,14 @@ class TransmissionData:
|
|||
"""Initialize the Transmission RPC API."""
|
||||
self.hass = hass
|
||||
self.config = config
|
||||
self.data = None # type: transmissionrpc.Session
|
||||
self.available = True # type: bool
|
||||
self._all_torrents = [] # type: List[transmissionrpc.Torrent]
|
||||
self._api = api # type: transmissionrpc.Client
|
||||
self._completed_torrents = [] # type: List[transmissionrpc.Torrent]
|
||||
self._session = None # type: transmissionrpc.Session
|
||||
self._started_torrents = [] # type: List[transmissionrpc.Torrent]
|
||||
self._torrents = [] # type: List[transmissionrpc.Torrent]
|
||||
self.data: transmissionrpc.Session = None
|
||||
self.available: bool = True
|
||||
self._all_torrents: list[transmissionrpc.Torrent] = []
|
||||
self._api: transmissionrpc.Client = api
|
||||
self._completed_torrents: list[transmissionrpc.Torrent] = []
|
||||
self._session: transmissionrpc.Session = None
|
||||
self._started_torrents: list[transmissionrpc.Torrent] = []
|
||||
self._torrents: list[transmissionrpc.Torrent] = []
|
||||
|
||||
@property
|
||||
def host(self):
|
||||
|
@ -365,7 +364,7 @@ class TransmissionData:
|
|||
return f"{DATA_UPDATED}-{self.host}"
|
||||
|
||||
@property
|
||||
def torrents(self) -> List[transmissionrpc.Torrent]:
|
||||
def torrents(self) -> list[transmissionrpc.Torrent]:
|
||||
"""Get the list of torrents."""
|
||||
return self._torrents
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ class TransmissionSensor(Entity):
|
|||
|
||||
def __init__(self, tm_client, client_name, sensor_name, sub_type=None):
|
||||
"""Initialize the sensor."""
|
||||
self._tm_client = tm_client # type: TransmissionClient
|
||||
self._tm_client: TransmissionClient = tm_client
|
||||
self._client_name = client_name
|
||||
self._name = sensor_name
|
||||
self._sub_type = sub_type
|
||||
|
|
|
@ -74,7 +74,7 @@ async def async_update_options(hass: HomeAssistant, config_entry: ConfigEntry):
|
|||
|
||||
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry):
|
||||
"""Unload a config entry."""
|
||||
api: "WiffiIntegrationApi" = hass.data[DOMAIN][config_entry.entry_id]
|
||||
api: WiffiIntegrationApi = hass.data[DOMAIN][config_entry.entry_id]
|
||||
await api.server.close_server()
|
||||
|
||||
unload_ok = all(
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
"""Support for exposing Home Assistant via Zeroconf."""
|
||||
from __future__ import annotations
|
||||
|
||||
import fnmatch
|
||||
from functools import partial
|
||||
import ipaddress
|
||||
|
@ -107,7 +109,7 @@ async def _async_get_instance(hass, **zcargs):
|
|||
class HaServiceBrowser(ServiceBrowser):
|
||||
"""ServiceBrowser that only consumes DNSPointer records."""
|
||||
|
||||
def update_record(self, zc: "Zeroconf", now: float, record: DNSRecord) -> None:
|
||||
def update_record(self, zc: Zeroconf, now: float, record: DNSRecord) -> None:
|
||||
"""Pre-Filter update_record to DNSPointers for the configured type."""
|
||||
|
||||
#
|
||||
|
|
|
@ -463,7 +463,7 @@ class ConfigEntriesFlowManager(data_entry_flow.FlowManager):
|
|||
"""Manage all the config entry flows that are in progress."""
|
||||
|
||||
def __init__(
|
||||
self, hass: HomeAssistant, config_entries: "ConfigEntries", hass_config: dict
|
||||
self, hass: HomeAssistant, config_entries: ConfigEntries, hass_config: dict
|
||||
):
|
||||
"""Initialize the config entry flow manager."""
|
||||
super().__init__(hass)
|
||||
|
|
|
@ -214,9 +214,9 @@ class CoreState(enum.Enum):
|
|||
class HomeAssistant:
|
||||
"""Root object of the Home Assistant home automation."""
|
||||
|
||||
auth: "AuthManager"
|
||||
http: "HomeAssistantHTTP" = None # type: ignore
|
||||
config_entries: "ConfigEntries" = None # type: ignore
|
||||
auth: AuthManager
|
||||
http: HomeAssistantHTTP = None # type: ignore
|
||||
config_entries: ConfigEntries = None # type: ignore
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize new Home Assistant object."""
|
||||
|
|
|
@ -86,13 +86,11 @@ class FlowManager(abc.ABC):
|
|||
|
||||
@abc.abstractmethod
|
||||
async def async_finish_flow(
|
||||
self, flow: "FlowHandler", result: dict[str, Any]
|
||||
self, flow: FlowHandler, result: dict[str, Any]
|
||||
) -> dict[str, Any]:
|
||||
"""Finish a config flow and add an entry."""
|
||||
|
||||
async def async_post_init(
|
||||
self, flow: "FlowHandler", result: dict[str, Any]
|
||||
) -> None:
|
||||
async def async_post_init(self, flow: FlowHandler, result: dict[str, Any]) -> None:
|
||||
"""Entry has finished executing its first step asynchronously."""
|
||||
|
||||
@callback
|
||||
|
|
|
@ -10,7 +10,7 @@ if TYPE_CHECKING:
|
|||
from .typing import ConfigType
|
||||
|
||||
|
||||
def config_per_platform(config: "ConfigType", domain: str) -> Iterable[tuple[Any, Any]]:
|
||||
def config_per_platform(config: ConfigType, domain: str) -> Iterable[tuple[Any, Any]]:
|
||||
"""Break a component config into different platforms.
|
||||
|
||||
For example, will find 'switch', 'switch 2', 'switch 3', .. etc
|
||||
|
@ -34,7 +34,7 @@ def config_per_platform(config: "ConfigType", domain: str) -> Iterable[tuple[Any
|
|||
yield platform, item
|
||||
|
||||
|
||||
def extract_domain_configs(config: "ConfigType", domain: str) -> Sequence[str]:
|
||||
def extract_domain_configs(config: ConfigType, domain: str) -> Sequence[str]:
|
||||
"""Extract keys from config for given domain name.
|
||||
|
||||
Async friendly.
|
||||
|
|
|
@ -658,7 +658,7 @@ def async_entries_for_config_entry(
|
|||
|
||||
@callback
|
||||
def async_config_entry_disabled_by_changed(
|
||||
registry: DeviceRegistry, config_entry: "ConfigEntry"
|
||||
registry: DeviceRegistry, config_entry: ConfigEntry
|
||||
) -> None:
|
||||
"""Handle a config entry being disabled or enabled.
|
||||
|
||||
|
|
|
@ -628,7 +628,7 @@ def async_entries_for_config_entry(
|
|||
|
||||
@callback
|
||||
def async_config_entry_disabled_by_changed(
|
||||
registry: EntityRegistry, config_entry: "ConfigEntry"
|
||||
registry: EntityRegistry, config_entry: ConfigEntry
|
||||
) -> None:
|
||||
"""Handle a config entry being disabled or enabled.
|
||||
|
||||
|
|
|
@ -291,7 +291,7 @@ class _ScriptRun:
|
|||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
script: "Script",
|
||||
script: Script,
|
||||
variables: dict[str, Any],
|
||||
context: Context | None,
|
||||
log_exceptions: bool,
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
"""Selectors for Home Assistant."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Callable, Dict, cast
|
||||
|
||||
import voluptuous as vol
|
||||
|
@ -9,7 +11,7 @@ from homeassistant.util import decorator
|
|||
SELECTORS = decorator.Registry()
|
||||
|
||||
|
||||
def validate_selector(config: Any) -> Dict:
|
||||
def validate_selector(config: Any) -> dict:
|
||||
"""Validate a selector."""
|
||||
if not isinstance(config, dict):
|
||||
raise vol.Invalid("Expected a dictionary")
|
||||
|
|
|
@ -5,16 +5,7 @@ import asyncio
|
|||
import dataclasses
|
||||
from functools import partial, wraps
|
||||
import logging
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Awaitable,
|
||||
Callable,
|
||||
Iterable,
|
||||
Optional,
|
||||
TypedDict,
|
||||
Union,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Iterable, TypedDict
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -83,9 +74,9 @@ class ServiceTargetSelector:
|
|||
|
||||
def __init__(self, service_call: ha.ServiceCall):
|
||||
"""Extract ids from service call data."""
|
||||
entity_ids: Optional[Union[str, list]] = service_call.data.get(ATTR_ENTITY_ID)
|
||||
device_ids: Optional[Union[str, list]] = service_call.data.get(ATTR_DEVICE_ID)
|
||||
area_ids: Optional[Union[str, list]] = service_call.data.get(ATTR_AREA_ID)
|
||||
entity_ids: str | list | None = service_call.data.get(ATTR_ENTITY_ID)
|
||||
device_ids: str | list | None = service_call.data.get(ATTR_DEVICE_ID)
|
||||
area_ids: str | list | None = service_call.data.get(ATTR_AREA_ID)
|
||||
|
||||
self.entity_ids = (
|
||||
set(cv.ensure_list(entity_ids)) if _has_match(entity_ids) else set()
|
||||
|
@ -319,7 +310,7 @@ async def async_extract_entity_ids(
|
|||
return referenced.referenced | referenced.indirectly_referenced
|
||||
|
||||
|
||||
def _has_match(ids: Optional[Union[str, list]]) -> bool:
|
||||
def _has_match(ids: str | list | None) -> bool:
|
||||
"""Check if ids can match anything."""
|
||||
return ids not in (None, ENTITY_MATCH_NONE)
|
||||
|
||||
|
@ -514,7 +505,7 @@ def async_set_service_schema(
|
|||
@bind_hass
|
||||
async def entity_service_call(
|
||||
hass: HomeAssistantType,
|
||||
platforms: Iterable["EntityPlatform"],
|
||||
platforms: Iterable[EntityPlatform],
|
||||
func: str | Callable[..., Any],
|
||||
call: ha.ServiceCall,
|
||||
required_features: Iterable[int] | None = None,
|
||||
|
@ -557,7 +548,7 @@ async def entity_service_call(
|
|||
# Check the permissions
|
||||
|
||||
# A list with entities to call the service on.
|
||||
entity_candidates: list["Entity"] = []
|
||||
entity_candidates: list[Entity] = []
|
||||
|
||||
if entity_perms is None:
|
||||
for platform in platforms:
|
||||
|
|
|
@ -103,7 +103,7 @@ def manifest_from_legacy_module(domain: str, module: ModuleType) -> Manifest:
|
|||
|
||||
|
||||
async def _async_get_custom_components(
|
||||
hass: "HomeAssistant",
|
||||
hass: HomeAssistant,
|
||||
) -> dict[str, Integration]:
|
||||
"""Return list of custom integrations."""
|
||||
if hass.config.safe_mode:
|
||||
|
@ -144,7 +144,7 @@ async def _async_get_custom_components(
|
|||
|
||||
|
||||
async def async_get_custom_components(
|
||||
hass: "HomeAssistant",
|
||||
hass: HomeAssistant,
|
||||
) -> dict[str, Integration]:
|
||||
"""Return cached list of custom integrations."""
|
||||
reg_or_evt = hass.data.get(DATA_CUSTOM_COMPONENTS)
|
||||
|
@ -276,7 +276,7 @@ class Integration:
|
|||
|
||||
@classmethod
|
||||
def resolve_from_root(
|
||||
cls, hass: "HomeAssistant", root_module: ModuleType, domain: str
|
||||
cls, hass: HomeAssistant, root_module: ModuleType, domain: str
|
||||
) -> Integration | None:
|
||||
"""Resolve an integration from a root module."""
|
||||
for base in root_module.__path__: # type: ignore
|
||||
|
@ -300,7 +300,7 @@ class Integration:
|
|||
return None
|
||||
|
||||
@classmethod
|
||||
def resolve_legacy(cls, hass: "HomeAssistant", domain: str) -> Integration | None:
|
||||
def resolve_legacy(cls, hass: HomeAssistant, domain: str) -> Integration | None:
|
||||
"""Resolve legacy component.
|
||||
|
||||
Will create a stub manifest.
|
||||
|
@ -319,7 +319,7 @@ class Integration:
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
hass: "HomeAssistant",
|
||||
hass: HomeAssistant,
|
||||
pkg_path: str,
|
||||
file_path: pathlib.Path,
|
||||
manifest: Manifest,
|
||||
|
@ -494,7 +494,7 @@ class Integration:
|
|||
return f"<Integration {self.domain}: {self.pkg_path}>"
|
||||
|
||||
|
||||
async def async_get_integration(hass: "HomeAssistant", domain: str) -> Integration:
|
||||
async def async_get_integration(hass: HomeAssistant, domain: str) -> Integration:
|
||||
"""Get an integration."""
|
||||
cache = hass.data.get(DATA_INTEGRATIONS)
|
||||
if cache is None:
|
||||
|
@ -579,7 +579,7 @@ class CircularDependency(LoaderError):
|
|||
|
||||
|
||||
def _load_file(
|
||||
hass: "HomeAssistant", comp_or_platform: str, base_paths: list[str]
|
||||
hass: HomeAssistant, comp_or_platform: str, base_paths: list[str]
|
||||
) -> ModuleType | None:
|
||||
"""Try to load specified file.
|
||||
|
||||
|
@ -640,7 +640,7 @@ def _load_file(
|
|||
class ModuleWrapper:
|
||||
"""Class to wrap a Python module and auto fill in hass argument."""
|
||||
|
||||
def __init__(self, hass: "HomeAssistant", module: ModuleType) -> None:
|
||||
def __init__(self, hass: HomeAssistant, module: ModuleType) -> None:
|
||||
"""Initialize the module wrapper."""
|
||||
self._hass = hass
|
||||
self._module = module
|
||||
|
@ -704,7 +704,7 @@ def bind_hass(func: CALLABLE_T) -> CALLABLE_T:
|
|||
|
||||
|
||||
async def _async_component_dependencies(
|
||||
hass: "HomeAssistant",
|
||||
hass: HomeAssistant,
|
||||
start_domain: str,
|
||||
integration: Integration,
|
||||
loaded: set[str],
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""Generate CODEOWNERS."""
|
||||
from typing import Dict
|
||||
from __future__ import annotations
|
||||
|
||||
from .model import Config, Integration
|
||||
|
||||
|
@ -33,7 +33,7 @@ homeassistant/components/demo/weather @fabaff
|
|||
"""
|
||||
|
||||
|
||||
def generate_and_validate(integrations: Dict[str, Integration]):
|
||||
def generate_and_validate(integrations: dict[str, Integration]):
|
||||
"""Generate CODEOWNERS."""
|
||||
parts = [BASE]
|
||||
|
||||
|
@ -61,7 +61,7 @@ def generate_and_validate(integrations: Dict[str, Integration]):
|
|||
return "\n".join(parts)
|
||||
|
||||
|
||||
def validate(integrations: Dict[str, Integration], config: Config):
|
||||
def validate(integrations: dict[str, Integration], config: Config):
|
||||
"""Validate CODEOWNERS."""
|
||||
codeowners_path = config.root / "CODEOWNERS"
|
||||
config.cache["codeowners"] = content = generate_and_validate(integrations)
|
||||
|
@ -79,7 +79,7 @@ def validate(integrations: Dict[str, Integration], config: Config):
|
|||
return
|
||||
|
||||
|
||||
def generate(integrations: Dict[str, Integration], config: Config):
|
||||
def generate(integrations: dict[str, Integration], config: Config):
|
||||
"""Generate CODEOWNERS."""
|
||||
codeowners_path = config.root / "CODEOWNERS"
|
||||
with open(str(codeowners_path), "w") as fp:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Generate config flow file."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Dict
|
||||
|
||||
from .model import Config, Integration
|
||||
|
||||
|
@ -90,7 +91,7 @@ def validate_integration(config: Config, integration: Integration):
|
|||
)
|
||||
|
||||
|
||||
def generate_and_validate(integrations: Dict[str, Integration], config: Config):
|
||||
def generate_and_validate(integrations: dict[str, Integration], config: Config):
|
||||
"""Validate and generate config flow data."""
|
||||
domains = []
|
||||
|
||||
|
@ -117,7 +118,7 @@ def generate_and_validate(integrations: Dict[str, Integration], config: Config):
|
|||
return BASE.format(json.dumps(domains, indent=4))
|
||||
|
||||
|
||||
def validate(integrations: Dict[str, Integration], config: Config):
|
||||
def validate(integrations: dict[str, Integration], config: Config):
|
||||
"""Validate config flow file."""
|
||||
config_flow_path = config.root / "homeassistant/generated/config_flows.py"
|
||||
config.cache["config_flow"] = content = generate_and_validate(integrations, config)
|
||||
|
@ -136,7 +137,7 @@ def validate(integrations: Dict[str, Integration], config: Config):
|
|||
return
|
||||
|
||||
|
||||
def generate(integrations: Dict[str, Integration], config: Config):
|
||||
def generate(integrations: dict[str, Integration], config: Config):
|
||||
"""Generate config flow file."""
|
||||
config_flow_path = config.root / "homeassistant/generated/config_flows.py"
|
||||
with open(str(config_flow_path), "w") as fp:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Validate coverage files."""
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Dict
|
||||
|
||||
from .model import Config, Integration
|
||||
|
||||
|
@ -69,7 +70,7 @@ ALLOWED_IGNORE_VIOLATIONS = {
|
|||
}
|
||||
|
||||
|
||||
def validate(integrations: Dict[str, Integration], config: Config):
|
||||
def validate(integrations: dict[str, Integration], config: Config):
|
||||
"""Validate coverage."""
|
||||
coverage_path = config.root / ".coveragerc"
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
"""Validate dependencies."""
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
from pathlib import Path
|
||||
from typing import Dict, Set
|
||||
|
||||
from homeassistant.requirements import DISCOVERY_INTEGRATIONS
|
||||
|
||||
|
@ -14,7 +15,7 @@ class ImportCollector(ast.NodeVisitor):
|
|||
def __init__(self, integration: Integration):
|
||||
"""Initialize the import collector."""
|
||||
self.integration = integration
|
||||
self.referenced: Dict[Path, Set[str]] = {}
|
||||
self.referenced: dict[Path, set[str]] = {}
|
||||
|
||||
# Current file or dir we're inspecting
|
||||
self._cur_fil_dir = None
|
||||
|
@ -156,7 +157,7 @@ IGNORE_VIOLATIONS = {
|
|||
}
|
||||
|
||||
|
||||
def calc_allowed_references(integration: Integration) -> Set[str]:
|
||||
def calc_allowed_references(integration: Integration) -> set[str]:
|
||||
"""Return a set of allowed references."""
|
||||
allowed_references = (
|
||||
ALLOWED_USED_COMPONENTS
|
||||
|
@ -173,9 +174,9 @@ def calc_allowed_references(integration: Integration) -> Set[str]:
|
|||
|
||||
|
||||
def find_non_referenced_integrations(
|
||||
integrations: Dict[str, Integration],
|
||||
integrations: dict[str, Integration],
|
||||
integration: Integration,
|
||||
references: Dict[Path, Set[str]],
|
||||
references: dict[Path, set[str]],
|
||||
):
|
||||
"""Find intergrations that are not allowed to be referenced."""
|
||||
allowed_references = calc_allowed_references(integration)
|
||||
|
@ -221,7 +222,7 @@ def find_non_referenced_integrations(
|
|||
|
||||
|
||||
def validate_dependencies(
|
||||
integrations: Dict[str, Integration], integration: Integration
|
||||
integrations: dict[str, Integration], integration: Integration
|
||||
):
|
||||
"""Validate all dependencies."""
|
||||
# Some integrations are allowed to have violations.
|
||||
|
@ -244,7 +245,7 @@ def validate_dependencies(
|
|||
)
|
||||
|
||||
|
||||
def validate(integrations: Dict[str, Integration], config):
|
||||
def validate(integrations: dict[str, Integration], config):
|
||||
"""Handle dependencies for integrations."""
|
||||
# check for non-existing dependencies
|
||||
for integration in integrations.values():
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Generate dhcp file."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Dict, List
|
||||
|
||||
from .model import Config, Integration
|
||||
|
||||
|
@ -16,7 +17,7 @@ DHCP = {}
|
|||
""".strip()
|
||||
|
||||
|
||||
def generate_and_validate(integrations: List[Dict[str, str]]):
|
||||
def generate_and_validate(integrations: list[dict[str, str]]):
|
||||
"""Validate and generate dhcp data."""
|
||||
match_list = []
|
||||
|
||||
|
@ -37,7 +38,7 @@ def generate_and_validate(integrations: List[Dict[str, str]]):
|
|||
return BASE.format(json.dumps(match_list, indent=4))
|
||||
|
||||
|
||||
def validate(integrations: Dict[str, Integration], config: Config):
|
||||
def validate(integrations: dict[str, Integration], config: Config):
|
||||
"""Validate dhcp file."""
|
||||
dhcp_path = config.root / "homeassistant/generated/dhcp.py"
|
||||
config.cache["dhcp"] = content = generate_and_validate(integrations)
|
||||
|
@ -56,7 +57,7 @@ def validate(integrations: Dict[str, Integration], config: Config):
|
|||
return
|
||||
|
||||
|
||||
def generate(integrations: Dict[str, Integration], config: Config):
|
||||
def generate(integrations: dict[str, Integration], config: Config):
|
||||
"""Generate dhcp file."""
|
||||
dhcp_path = config.root / "homeassistant/generated/dhcp.py"
|
||||
with open(str(dhcp_path), "w") as fp:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Validate integration JSON files."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Dict
|
||||
|
||||
from .model import Integration
|
||||
|
||||
|
@ -20,7 +21,7 @@ def validate_json_files(integration: Integration):
|
|||
return
|
||||
|
||||
|
||||
def validate(integrations: Dict[str, Integration], config):
|
||||
def validate(integrations: dict[str, Integration], config):
|
||||
"""Handle JSON files inside integrations."""
|
||||
if not config.specific_integrations:
|
||||
return
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"""Manifest validation."""
|
||||
from typing import Dict
|
||||
from __future__ import annotations
|
||||
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import voluptuous as vol
|
||||
|
@ -145,7 +146,7 @@ def validate_manifest(integration: Integration):
|
|||
validate_version(integration)
|
||||
|
||||
|
||||
def validate(integrations: Dict[str, Integration], config):
|
||||
def validate(integrations: dict[str, Integration], config):
|
||||
"""Handle all integrations manifests."""
|
||||
for integration in integrations.values():
|
||||
if integration.manifest:
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
"""Models for manifest validator."""
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import json
|
||||
import pathlib
|
||||
from typing import Any, Dict, List, Optional
|
||||
from typing import Any
|
||||
|
||||
import attr
|
||||
|
||||
|
@ -24,12 +26,12 @@ class Error:
|
|||
class Config:
|
||||
"""Config for the run."""
|
||||
|
||||
specific_integrations: Optional[pathlib.Path] = attr.ib()
|
||||
specific_integrations: pathlib.Path | None = attr.ib()
|
||||
root: pathlib.Path = attr.ib()
|
||||
action: str = attr.ib()
|
||||
requirements: bool = attr.ib()
|
||||
errors: List[Error] = attr.ib(factory=list)
|
||||
cache: Dict[str, Any] = attr.ib(factory=dict)
|
||||
errors: list[Error] = attr.ib(factory=list)
|
||||
cache: dict[str, Any] = attr.ib(factory=dict)
|
||||
|
||||
def add_error(self, *args, **kwargs):
|
||||
"""Add an error."""
|
||||
|
@ -65,9 +67,9 @@ class Integration:
|
|||
return integrations
|
||||
|
||||
path: pathlib.Path = attr.ib()
|
||||
manifest: Optional[dict] = attr.ib(default=None)
|
||||
errors: List[Error] = attr.ib(factory=list)
|
||||
warnings: List[Error] = attr.ib(factory=list)
|
||||
manifest: dict | None = attr.ib(default=None)
|
||||
errors: list[Error] = attr.ib(factory=list)
|
||||
warnings: list[Error] = attr.ib(factory=list)
|
||||
|
||||
@property
|
||||
def domain(self) -> str:
|
||||
|
@ -80,17 +82,17 @@ class Integration:
|
|||
return self.path.as_posix().startswith("homeassistant/components")
|
||||
|
||||
@property
|
||||
def disabled(self) -> Optional[str]:
|
||||
def disabled(self) -> str | None:
|
||||
"""List of disabled."""
|
||||
return self.manifest.get("disabled")
|
||||
|
||||
@property
|
||||
def requirements(self) -> List[str]:
|
||||
def requirements(self) -> list[str]:
|
||||
"""List of requirements."""
|
||||
return self.manifest.get("requirements", [])
|
||||
|
||||
@property
|
||||
def dependencies(self) -> List[str]:
|
||||
def dependencies(self) -> list[str]:
|
||||
"""List of dependencies."""
|
||||
return self.manifest.get("dependencies", [])
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
"""Generate MQTT file."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import defaultdict
|
||||
import json
|
||||
from typing import Dict
|
||||
|
||||
from .model import Config, Integration
|
||||
|
||||
|
@ -17,7 +18,7 @@ MQTT = {}
|
|||
""".strip()
|
||||
|
||||
|
||||
def generate_and_validate(integrations: Dict[str, Integration]):
|
||||
def generate_and_validate(integrations: dict[str, Integration]):
|
||||
"""Validate and generate MQTT data."""
|
||||
|
||||
data = defaultdict(list)
|
||||
|
@ -39,7 +40,7 @@ def generate_and_validate(integrations: Dict[str, Integration]):
|
|||
return BASE.format(json.dumps(data, indent=4))
|
||||
|
||||
|
||||
def validate(integrations: Dict[str, Integration], config: Config):
|
||||
def validate(integrations: dict[str, Integration], config: Config):
|
||||
"""Validate MQTT file."""
|
||||
mqtt_path = config.root / "homeassistant/generated/mqtt.py"
|
||||
config.cache["mqtt"] = content = generate_and_validate(integrations)
|
||||
|
@ -57,7 +58,7 @@ def validate(integrations: Dict[str, Integration], config: Config):
|
|||
return
|
||||
|
||||
|
||||
def generate(integrations: Dict[str, Integration], config: Config):
|
||||
def generate(integrations: dict[str, Integration], config: Config):
|
||||
"""Generate MQTT file."""
|
||||
mqtt_path = config.root / "homeassistant/generated/mqtt.py"
|
||||
with open(str(mqtt_path), "w") as fp:
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
"""Validate requirements."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import deque
|
||||
import json
|
||||
import operator
|
||||
|
@ -6,7 +8,6 @@ import os
|
|||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Dict, Set
|
||||
|
||||
from stdlib_list import stdlib_list
|
||||
from tqdm import tqdm
|
||||
|
@ -58,7 +59,7 @@ def normalize_package_name(requirement: str) -> str:
|
|||
return package
|
||||
|
||||
|
||||
def validate(integrations: Dict[str, Integration], config: Config):
|
||||
def validate(integrations: dict[str, Integration], config: Config):
|
||||
"""Handle requirements for integrations."""
|
||||
ensure_cache()
|
||||
|
||||
|
@ -153,7 +154,7 @@ def ensure_cache():
|
|||
PIPDEPTREE_CACHE = cache
|
||||
|
||||
|
||||
def get_requirements(integration: Integration, packages: Set[str]) -> Set[str]:
|
||||
def get_requirements(integration: Integration, packages: set[str]) -> set[str]:
|
||||
"""Return all (recursively) requirements for an integration."""
|
||||
ensure_cache()
|
||||
|
||||
|
@ -184,7 +185,7 @@ def get_requirements(integration: Integration, packages: Set[str]) -> Set[str]:
|
|||
return all_requirements
|
||||
|
||||
|
||||
def install_requirements(integration: Integration, requirements: Set[str]) -> bool:
|
||||
def install_requirements(integration: Integration, requirements: set[str]) -> bool:
|
||||
"""Install integration requirements.
|
||||
|
||||
Return True if successful.
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
"""Validate dependencies."""
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
import re
|
||||
from typing import Dict
|
||||
|
||||
import voluptuous as vol
|
||||
from voluptuous.humanize import humanize_error
|
||||
|
@ -93,7 +94,7 @@ def validate_services(integration: Integration):
|
|||
)
|
||||
|
||||
|
||||
def validate(integrations: Dict[str, Integration], config):
|
||||
def validate(integrations: dict[str, Integration], config):
|
||||
"""Handle dependencies for integrations."""
|
||||
# check services.yaml is cool
|
||||
for integration in integrations.values():
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
"""Generate ssdp file."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import OrderedDict, defaultdict
|
||||
import json
|
||||
from typing import Dict
|
||||
|
||||
from .model import Config, Integration
|
||||
|
||||
|
@ -22,7 +23,7 @@ def sort_dict(value):
|
|||
return OrderedDict((key, value[key]) for key in sorted(value))
|
||||
|
||||
|
||||
def generate_and_validate(integrations: Dict[str, Integration]):
|
||||
def generate_and_validate(integrations: dict[str, Integration]):
|
||||
"""Validate and generate ssdp data."""
|
||||
|
||||
data = defaultdict(list)
|
||||
|
@ -44,7 +45,7 @@ def generate_and_validate(integrations: Dict[str, Integration]):
|
|||
return BASE.format(json.dumps(data, indent=4))
|
||||
|
||||
|
||||
def validate(integrations: Dict[str, Integration], config: Config):
|
||||
def validate(integrations: dict[str, Integration], config: Config):
|
||||
"""Validate ssdp file."""
|
||||
ssdp_path = config.root / "homeassistant/generated/ssdp.py"
|
||||
config.cache["ssdp"] = content = generate_and_validate(integrations)
|
||||
|
@ -62,7 +63,7 @@ def validate(integrations: Dict[str, Integration], config: Config):
|
|||
return
|
||||
|
||||
|
||||
def generate(integrations: Dict[str, Integration], config: Config):
|
||||
def generate(integrations: dict[str, Integration], config: Config):
|
||||
"""Generate ssdp file."""
|
||||
ssdp_path = config.root / "homeassistant/generated/ssdp.py"
|
||||
with open(str(ssdp_path), "w") as fp:
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
"""Validate integration translation files."""
|
||||
from __future__ import annotations
|
||||
|
||||
from functools import partial
|
||||
from itertools import chain
|
||||
import json
|
||||
import re
|
||||
from typing import Dict
|
||||
|
||||
import voluptuous as vol
|
||||
from voluptuous.humanize import humanize_error
|
||||
|
@ -295,7 +296,7 @@ def validate_translation_file(config: Config, integration: Integration, all_stri
|
|||
)
|
||||
|
||||
|
||||
def validate(integrations: Dict[str, Integration], config: Config):
|
||||
def validate(integrations: dict[str, Integration], config: Config):
|
||||
"""Handle JSON files inside integrations."""
|
||||
if config.specific_integrations:
|
||||
all_strings = None
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
"""Generate zeroconf file."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import OrderedDict, defaultdict
|
||||
import json
|
||||
from typing import Dict
|
||||
|
||||
from .model import Config, Integration
|
||||
|
||||
|
@ -19,7 +20,7 @@ HOMEKIT = {}
|
|||
""".strip()
|
||||
|
||||
|
||||
def generate_and_validate(integrations: Dict[str, Integration]):
|
||||
def generate_and_validate(integrations: dict[str, Integration]):
|
||||
"""Validate and generate zeroconf data."""
|
||||
service_type_dict = defaultdict(list)
|
||||
homekit_dict = {}
|
||||
|
@ -89,7 +90,7 @@ def generate_and_validate(integrations: Dict[str, Integration]):
|
|||
return BASE.format(json.dumps(zeroconf, indent=4), json.dumps(homekit, indent=4))
|
||||
|
||||
|
||||
def validate(integrations: Dict[str, Integration], config: Config):
|
||||
def validate(integrations: dict[str, Integration], config: Config):
|
||||
"""Validate zeroconf file."""
|
||||
zeroconf_path = config.root / "homeassistant/generated/zeroconf.py"
|
||||
config.cache["zeroconf"] = content = generate_and_validate(integrations)
|
||||
|
@ -108,7 +109,7 @@ def validate(integrations: Dict[str, Integration], config: Config):
|
|||
return
|
||||
|
||||
|
||||
def generate(integrations: Dict[str, Integration], config: Config):
|
||||
def generate(integrations: dict[str, Integration], config: Config):
|
||||
"""Generate zeroconf file."""
|
||||
zeroconf_path = config.root / "homeassistant/generated/zeroconf.py"
|
||||
with open(str(zeroconf_path), "w") as fp:
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
"""Models for scaffolding."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Set
|
||||
|
||||
import attr
|
||||
|
||||
|
@ -21,9 +22,9 @@ class Info:
|
|||
discoverable: str = attr.ib(default=None)
|
||||
oauth2: str = attr.ib(default=None)
|
||||
|
||||
files_added: Set[Path] = attr.ib(factory=set)
|
||||
tests_added: Set[Path] = attr.ib(factory=set)
|
||||
examples_added: Set[Path] = attr.ib(factory=set)
|
||||
files_added: set[Path] = attr.ib(factory=set)
|
||||
tests_added: set[Path] = attr.ib(factory=set)
|
||||
examples_added: set[Path] = attr.ib(factory=set)
|
||||
|
||||
@property
|
||||
def integration_dir(self) -> Path:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""Provides device actions for NEW_NAME."""
|
||||
from typing import List, Optional
|
||||
from __future__ import annotations
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -29,7 +29,7 @@ ACTION_SCHEMA = cv.DEVICE_ACTION_BASE_SCHEMA.extend(
|
|||
)
|
||||
|
||||
|
||||
async def async_get_actions(hass: HomeAssistant, device_id: str) -> List[dict]:
|
||||
async def async_get_actions(hass: HomeAssistant, device_id: str) -> list[dict]:
|
||||
"""List device actions for NEW_NAME devices."""
|
||||
registry = await entity_registry.async_get_registry(hass)
|
||||
actions = []
|
||||
|
@ -69,7 +69,7 @@ async def async_get_actions(hass: HomeAssistant, device_id: str) -> List[dict]:
|
|||
|
||||
|
||||
async def async_call_action_from_config(
|
||||
hass: HomeAssistant, config: dict, variables: dict, context: Optional[Context]
|
||||
hass: HomeAssistant, config: dict, variables: dict, context: Context | None
|
||||
) -> None:
|
||||
"""Execute a device action."""
|
||||
service_data = {ATTR_ENTITY_ID: config[CONF_ENTITY_ID]}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""Provide the device conditions for NEW_NAME."""
|
||||
from typing import Dict, List
|
||||
from __future__ import annotations
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -33,7 +33,7 @@ CONDITION_SCHEMA = DEVICE_CONDITION_BASE_SCHEMA.extend(
|
|||
|
||||
async def async_get_conditions(
|
||||
hass: HomeAssistant, device_id: str
|
||||
) -> List[Dict[str, str]]:
|
||||
) -> list[dict[str, str]]:
|
||||
"""List device conditions for NEW_NAME devices."""
|
||||
registry = await entity_registry.async_get_registry(hass)
|
||||
conditions = []
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""Provides device triggers for NEW_NAME."""
|
||||
from typing import List
|
||||
from __future__ import annotations
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -32,7 +32,7 @@ TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend(
|
|||
)
|
||||
|
||||
|
||||
async def async_get_triggers(hass: HomeAssistant, device_id: str) -> List[dict]:
|
||||
async def async_get_triggers(hass: HomeAssistant, device_id: str) -> list[dict]:
|
||||
"""List device triggers for NEW_NAME devices."""
|
||||
registry = await entity_registry.async_get_registry(hass)
|
||||
triggers = []
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
"""Reproduce an NEW_NAME state."""
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import Any, Dict, Iterable, Optional
|
||||
from typing import Any, Iterable
|
||||
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
|
@ -25,8 +27,8 @@ async def _async_reproduce_state(
|
|||
hass: HomeAssistantType,
|
||||
state: State,
|
||||
*,
|
||||
context: Optional[Context] = None,
|
||||
reproduce_options: Optional[Dict[str, Any]] = None,
|
||||
context: Context | None = None,
|
||||
reproduce_options: dict[str, Any] | None = None,
|
||||
) -> None:
|
||||
"""Reproduce a single state."""
|
||||
cur_state = hass.states.get(state.entity_id)
|
||||
|
@ -70,8 +72,8 @@ async def async_reproduce_states(
|
|||
hass: HomeAssistantType,
|
||||
states: Iterable[State],
|
||||
*,
|
||||
context: Optional[Context] = None,
|
||||
reproduce_options: Optional[Dict[str, Any]] = None,
|
||||
context: Context | None = None,
|
||||
reproduce_options: dict[str, Any] | None = None,
|
||||
) -> None:
|
||||
"""Reproduce NEW_NAME states."""
|
||||
# TODO pick one and remove other one
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"""Helper to test significant NEW_NAME state changes."""
|
||||
from typing import Any, Optional
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.const import ATTR_DEVICE_CLASS
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
|
@ -13,7 +15,7 @@ def async_check_significant_change(
|
|||
new_state: str,
|
||||
new_attrs: dict,
|
||||
**kwargs: Any,
|
||||
) -> Optional[bool]:
|
||||
) -> bool | None:
|
||||
"""Test if state significantly changed."""
|
||||
device_class = new_attrs.get(ATTR_DEVICE_CLASS)
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Merge all translation sources into a single JSON file."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
import subprocess
|
||||
from typing import Dict, List, Union
|
||||
|
||||
from .const import CLI_2_DOCKER_IMAGE, CORE_PROJECT_ID, INTEGRATIONS_DIR
|
||||
from .error import ExitApp
|
||||
|
@ -51,7 +52,7 @@ def run_download_docker():
|
|||
raise ExitApp("Failed to download translations")
|
||||
|
||||
|
||||
def save_json(filename: str, data: Union[List, Dict]):
|
||||
def save_json(filename: str, data: list | dict):
|
||||
"""Save JSON data to a file.
|
||||
|
||||
Returns True on success.
|
||||
|
|
|
@ -202,9 +202,9 @@ async def async_test_home_assistant(loop, load_registries=True):
|
|||
start_time: float | None = None
|
||||
|
||||
while len(self._pending_tasks) > max_remaining_tasks:
|
||||
pending = [
|
||||
pending: Collection[Awaitable[Any]] = [
|
||||
task for task in self._pending_tasks if not task.done()
|
||||
] # type: Collection[Awaitable[Any]]
|
||||
]
|
||||
self._pending_tasks.clear()
|
||||
if len(pending) > max_remaining_tasks:
|
||||
remaining_pending = await self._await_count_and_log_pending(
|
||||
|
|
|
@ -118,7 +118,7 @@ class ComponentFactory:
|
|||
if controller_config.legacy_entity_unique_id:
|
||||
component_config[CONF_LEGACY_UNIQUE_ID] = True
|
||||
|
||||
controller = MagicMock(spec=pv.VeraController) # type: pv.VeraController
|
||||
controller: pv.VeraController = MagicMock(spec=pv.VeraController)
|
||||
controller.base_url = component_config.get(CONF_CONTROLLER)
|
||||
controller.register = MagicMock()
|
||||
controller.start = MagicMock()
|
||||
|
|
|
@ -12,7 +12,7 @@ async def test_binary_sensor(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device: pv.VeraBinarySensor = MagicMock(spec=pv.VeraBinarySensor)
|
||||
vera_device.device_id = 1
|
||||
vera_device.comm_failure = False
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
|
|
|
@ -20,7 +20,7 @@ async def test_climate(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraThermostat) # type: pv.VeraThermostat
|
||||
vera_device: pv.VeraThermostat = MagicMock(spec=pv.VeraThermostat)
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.comm_failure = False
|
||||
|
@ -131,7 +131,7 @@ async def test_climate_f(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraThermostat) # type: pv.VeraThermostat
|
||||
vera_device: pv.VeraThermostat = MagicMock(spec=pv.VeraThermostat)
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.comm_failure = False
|
||||
|
|
|
@ -12,7 +12,7 @@ async def test_cover(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraCurtain) # type: pv.VeraCurtain
|
||||
vera_device: pv.VeraCurtain = MagicMock(spec=pv.VeraCurtain)
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.comm_failure = False
|
||||
|
|
|
@ -24,7 +24,7 @@ async def test_init(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test function."""
|
||||
vera_device1 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device1: pv.VeraBinarySensor = MagicMock(spec=pv.VeraBinarySensor)
|
||||
vera_device1.device_id = 1
|
||||
vera_device1.vera_device_id = vera_device1.device_id
|
||||
vera_device1.name = "first_dev"
|
||||
|
@ -51,7 +51,7 @@ async def test_init_from_file(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test function."""
|
||||
vera_device1 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device1: pv.VeraBinarySensor = MagicMock(spec=pv.VeraBinarySensor)
|
||||
vera_device1.device_id = 1
|
||||
vera_device1.vera_device_id = vera_device1.device_id
|
||||
vera_device1.name = "first_dev"
|
||||
|
@ -78,14 +78,14 @@ async def test_multiple_controllers_with_legacy_one(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test multiple controllers with one legacy controller."""
|
||||
vera_device1 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device1: pv.VeraBinarySensor = MagicMock(spec=pv.VeraBinarySensor)
|
||||
vera_device1.device_id = 1
|
||||
vera_device1.vera_device_id = vera_device1.device_id
|
||||
vera_device1.name = "first_dev"
|
||||
vera_device1.is_tripped = False
|
||||
entity1_id = "binary_sensor.first_dev_1"
|
||||
|
||||
vera_device2 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device2: pv.VeraBinarySensor = MagicMock(spec=pv.VeraBinarySensor)
|
||||
vera_device2.device_id = 2
|
||||
vera_device2.vera_device_id = vera_device2.device_id
|
||||
vera_device2.name = "second_dev"
|
||||
|
@ -133,7 +133,7 @@ async def test_unload(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test function."""
|
||||
vera_device1 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device1: pv.VeraBinarySensor = MagicMock(spec=pv.VeraBinarySensor)
|
||||
vera_device1.device_id = 1
|
||||
vera_device1.vera_device_id = vera_device1.device_id
|
||||
vera_device1.name = "first_dev"
|
||||
|
@ -187,21 +187,21 @@ async def test_exclude_and_light_ids(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory, options
|
||||
) -> None:
|
||||
"""Test device exclusion, marking switches as lights and fixing the data type."""
|
||||
vera_device1 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device1: pv.VeraBinarySensor = MagicMock(spec=pv.VeraBinarySensor)
|
||||
vera_device1.device_id = 1
|
||||
vera_device1.vera_device_id = 1
|
||||
vera_device1.name = "dev1"
|
||||
vera_device1.is_tripped = False
|
||||
entity_id1 = "binary_sensor.dev1_1"
|
||||
|
||||
vera_device2 = MagicMock(spec=pv.VeraBinarySensor) # type: pv.VeraBinarySensor
|
||||
vera_device2: pv.VeraBinarySensor = MagicMock(spec=pv.VeraBinarySensor)
|
||||
vera_device2.device_id = 2
|
||||
vera_device2.vera_device_id = 2
|
||||
vera_device2.name = "dev2"
|
||||
vera_device2.is_tripped = False
|
||||
entity_id2 = "binary_sensor.dev2_2"
|
||||
|
||||
vera_device3 = MagicMock(spec=pv.VeraSwitch) # type: pv.VeraSwitch
|
||||
vera_device3: pv.VeraSwitch = MagicMock(spec=pv.VeraSwitch)
|
||||
vera_device3.device_id = 3
|
||||
vera_device3.vera_device_id = 3
|
||||
vera_device3.name = "dev3"
|
||||
|
@ -210,7 +210,7 @@ async def test_exclude_and_light_ids(
|
|||
|
||||
entity_id3 = "switch.dev3_3"
|
||||
|
||||
vera_device4 = MagicMock(spec=pv.VeraSwitch) # type: pv.VeraSwitch
|
||||
vera_device4: pv.VeraSwitch = MagicMock(spec=pv.VeraSwitch)
|
||||
vera_device4.device_id = 4
|
||||
vera_device4.vera_device_id = 4
|
||||
vera_device4.name = "dev4"
|
||||
|
|
|
@ -13,7 +13,7 @@ async def test_light(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraDimmer) # type: pv.VeraDimmer
|
||||
vera_device: pv.VeraDimmer = MagicMock(spec=pv.VeraDimmer)
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.comm_failure = False
|
||||
|
|
|
@ -13,7 +13,7 @@ async def test_lock(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraLock) # type: pv.VeraLock
|
||||
vera_device: pv.VeraLock = MagicMock(spec=pv.VeraLock)
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.comm_failure = False
|
||||
|
|
|
@ -12,7 +12,7 @@ async def test_scene(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test function."""
|
||||
vera_scene = MagicMock(spec=pv.VeraScene) # type: pv.VeraScene
|
||||
vera_scene: pv.VeraScene = MagicMock(spec=pv.VeraScene)
|
||||
vera_scene.scene_id = 1
|
||||
vera_scene.vera_scene_id = vera_scene.scene_id
|
||||
vera_scene.name = "dev1"
|
||||
|
|
|
@ -22,7 +22,7 @@ async def run_sensor_test(
|
|||
setup_callback: Callable[[pv.VeraController], None] = None,
|
||||
) -> None:
|
||||
"""Test generic sensor."""
|
||||
vera_device = MagicMock(spec=pv.VeraSensor) # type: pv.VeraSensor
|
||||
vera_device: pv.VeraSensor = MagicMock(spec=pv.VeraSensor)
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.comm_failure = False
|
||||
|
@ -178,7 +178,7 @@ async def test_scene_controller_sensor(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraSensor) # type: pv.VeraSensor
|
||||
vera_device: pv.VeraSensor = MagicMock(spec=pv.VeraSensor)
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.comm_failure = False
|
||||
|
|
|
@ -12,7 +12,7 @@ async def test_switch(
|
|||
hass: HomeAssistant, vera_component_factory: ComponentFactory
|
||||
) -> None:
|
||||
"""Test function."""
|
||||
vera_device = MagicMock(spec=pv.VeraSwitch) # type: pv.VeraSwitch
|
||||
vera_device: pv.VeraSwitch = MagicMock(spec=pv.VeraSwitch)
|
||||
vera_device.device_id = 1
|
||||
vera_device.vera_device_id = vera_device.device_id
|
||||
vera_device.comm_failure = False
|
||||
|
|
Loading…
Reference in New Issue