1
mirror of https://github.com/home-assistant/core synced 2024-09-25 00:41:32 +02:00

Update typing 16 (#48087)

This commit is contained in:
Marc Mueller 2021-03-18 22:58:19 +01:00 committed by GitHub
parent 0f5efca76b
commit 4cb7718192
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 180 additions and 166 deletions

View File

@ -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(

View File

@ -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()

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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]:

View File

@ -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()

View File

@ -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:

View File

@ -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):

View File

@ -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",

View File

@ -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:

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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(

View File

@ -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."""
#

View File

@ -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)

View File

@ -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."""

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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,

View File

@ -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")

View File

@ -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:

View File

@ -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],

View File

@ -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:

View File

@ -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:

View File

@ -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"

View File

@ -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():

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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", [])

View File

@ -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:

View File

@ -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.

View File

@ -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():

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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]}

View File

@ -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 = []

View File

@ -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 = []

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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(

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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