diff --git a/homeassistant/auth/auth_store.py b/homeassistant/auth/auth_store.py index 0b360668ad4..63cbeb1bf7e 100644 --- a/homeassistant/auth/auth_store.py +++ b/homeassistant/auth/auth_store.py @@ -17,6 +17,8 @@ from .const import GROUP_ID_ADMIN, GROUP_ID_READ_ONLY, GROUP_ID_USER from .permissions import PermissionLookup, system_policies from .permissions.types import PolicyType +# mypy: disallow-any-generics + STORAGE_VERSION = 1 STORAGE_KEY = "auth" GROUP_NAME_ADMIN = "Administrators" @@ -491,7 +493,7 @@ class AuthStore: self._store.async_delay_save(self._data_to_save, 1) @callback - def _data_to_save(self) -> dict: + def _data_to_save(self) -> dict[str, list[dict[str, Any]]]: """Return the data to store.""" assert self._users is not None assert self._groups is not None diff --git a/homeassistant/auth/providers/__init__.py b/homeassistant/auth/providers/__init__.py index d2dfa0e1c6d..4faa277a081 100644 --- a/homeassistant/auth/providers/__init__.py +++ b/homeassistant/auth/providers/__init__.py @@ -22,6 +22,8 @@ from ..auth_store import AuthStore from ..const import MFA_SESSION_EXPIRATION from ..models import Credentials, RefreshToken, User, UserMeta +# mypy: disallow-any-generics + _LOGGER = logging.getLogger(__name__) DATA_REQS = "auth_prov_reqs_processed" @@ -96,7 +98,7 @@ class AuthProvider: # Implement by extending class - async def async_login_flow(self, context: dict | None) -> LoginFlow: + async def async_login_flow(self, context: dict[str, Any] | None) -> LoginFlow: """Return the data flow for logging in with auth provider. Auth provider should extend LoginFlow and return an instance. diff --git a/homeassistant/auth/providers/command_line.py b/homeassistant/auth/providers/command_line.py index f462ad4be9d..6d1a1627fd5 100644 --- a/homeassistant/auth/providers/command_line.py +++ b/homeassistant/auth/providers/command_line.py @@ -17,6 +17,8 @@ from homeassistant.exceptions import HomeAssistantError from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow from ..models import Credentials, UserMeta +# mypy: disallow-any-generics + CONF_ARGS = "args" CONF_META = "meta" @@ -56,7 +58,7 @@ class CommandLineAuthProvider(AuthProvider): super().__init__(*args, **kwargs) self._user_meta: dict[str, dict[str, Any]] = {} - async def async_login_flow(self, context: dict | None) -> LoginFlow: + async def async_login_flow(self, context: dict[str, Any] | None) -> LoginFlow: """Return a flow to login.""" return CommandLineLoginFlow(self) diff --git a/homeassistant/auth/providers/homeassistant.py b/homeassistant/auth/providers/homeassistant.py index dfbf077a89d..b08c59bf3aa 100644 --- a/homeassistant/auth/providers/homeassistant.py +++ b/homeassistant/auth/providers/homeassistant.py @@ -19,6 +19,8 @@ from homeassistant.exceptions import HomeAssistantError from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow from ..models import Credentials, UserMeta +# mypy: disallow-any-generics + STORAGE_VERSION = 1 STORAGE_KEY = "auth_provider.homeassistant" @@ -235,7 +237,7 @@ class HassAuthProvider(AuthProvider): await data.async_load() self.data = data - async def async_login_flow(self, context: dict | None) -> LoginFlow: + async def async_login_flow(self, context: dict[str, Any] | None) -> LoginFlow: """Return a flow to login.""" return HassLoginFlow(self) diff --git a/homeassistant/auth/providers/insecure_example.py b/homeassistant/auth/providers/insecure_example.py index 5a3a890ff66..fb390b65b0d 100644 --- a/homeassistant/auth/providers/insecure_example.py +++ b/homeassistant/auth/providers/insecure_example.py @@ -4,7 +4,7 @@ from __future__ import annotations from collections import OrderedDict from collections.abc import Mapping import hmac -from typing import cast +from typing import Any, cast import voluptuous as vol @@ -15,6 +15,8 @@ from homeassistant.exceptions import HomeAssistantError from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow from ..models import Credentials, UserMeta +# mypy: disallow-any-generics + USER_SCHEMA = vol.Schema( { vol.Required("username"): str, @@ -37,7 +39,7 @@ class InvalidAuthError(HomeAssistantError): class ExampleAuthProvider(AuthProvider): """Example auth provider based on hardcoded usernames and passwords.""" - async def async_login_flow(self, context: dict | None) -> LoginFlow: + async def async_login_flow(self, context: dict[str, Any] | None) -> LoginFlow: """Return a flow to login.""" return ExampleLoginFlow(self) diff --git a/homeassistant/auth/providers/legacy_api_password.py b/homeassistant/auth/providers/legacy_api_password.py index b385aa0ed59..af24506210b 100644 --- a/homeassistant/auth/providers/legacy_api_password.py +++ b/homeassistant/auth/providers/legacy_api_password.py @@ -7,7 +7,7 @@ from __future__ import annotations from collections.abc import Mapping import hmac -from typing import cast +from typing import Any, cast import voluptuous as vol @@ -19,6 +19,8 @@ import homeassistant.helpers.config_validation as cv from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow from ..models import Credentials, UserMeta +# mypy: disallow-any-generics + AUTH_PROVIDER_TYPE = "legacy_api_password" CONF_API_PASSWORD = "api_password" @@ -44,7 +46,7 @@ class LegacyApiPasswordAuthProvider(AuthProvider): """Return api_password.""" return str(self.config[CONF_API_PASSWORD]) - async def async_login_flow(self, context: dict | None) -> LoginFlow: + async def async_login_flow(self, context: dict[str, Any] | None) -> LoginFlow: """Return a flow to login.""" return LegacyLoginFlow(self) diff --git a/homeassistant/auth/providers/trusted_networks.py b/homeassistant/auth/providers/trusted_networks.py index 7b609f371ef..a9ee6a48335 100644 --- a/homeassistant/auth/providers/trusted_networks.py +++ b/homeassistant/auth/providers/trusted_networks.py @@ -27,6 +27,8 @@ from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow from .. import InvalidAuthError from ..models import Credentials, RefreshToken, UserMeta +# mypy: disallow-any-generics + IPAddress = Union[IPv4Address, IPv6Address] IPNetwork = Union[IPv4Network, IPv6Network] @@ -97,7 +99,7 @@ class TrustedNetworksAuthProvider(AuthProvider): """Trusted Networks auth provider does not support MFA.""" return False - async def async_login_flow(self, context: dict | None) -> LoginFlow: + async def async_login_flow(self, context: dict[str, Any] | None) -> LoginFlow: """Return a flow to login.""" assert context is not None ip_addr = cast(IPAddress, context.get("ip_address")) diff --git a/homeassistant/config_entries.py b/homeassistant/config_entries.py index ec074f81b95..07cb9eae7f9 100644 --- a/homeassistant/config_entries.py +++ b/homeassistant/config_entries.py @@ -21,7 +21,12 @@ from homeassistant.exceptions import ( ) from homeassistant.helpers import device_registry, entity_registry from homeassistant.helpers.event import Event -from homeassistant.helpers.typing import UNDEFINED, DiscoveryInfoType, UndefinedType +from homeassistant.helpers.typing import ( + UNDEFINED, + ConfigType, + DiscoveryInfoType, + UndefinedType, +) from homeassistant.setup import async_process_deps_reqs, async_setup_component from homeassistant.util.decorator import Registry import homeassistant.util.uuid as uuid_util @@ -598,7 +603,10 @@ 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: ConfigType, ) -> None: """Initialize the config entry flow manager.""" super().__init__(hass) @@ -748,7 +756,7 @@ class ConfigEntries: An instance of this object is available via `hass.config_entries`. """ - def __init__(self, hass: HomeAssistant, hass_config: dict) -> None: + def __init__(self, hass: HomeAssistant, hass_config: ConfigType) -> None: """Initialize the entry manager.""" self.hass = hass self.flow = ConfigEntriesFlowManager(hass, self, hass_config) diff --git a/homeassistant/exceptions.py b/homeassistant/exceptions.py index 844fd369cac..2a82c2652ed 100644 --- a/homeassistant/exceptions.py +++ b/homeassistant/exceptions.py @@ -9,6 +9,8 @@ import attr if TYPE_CHECKING: from .core import Context +# mypy: disallow-any-generics + class HomeAssistantError(Exception): """General Home Assistant exception occurred.""" @@ -42,7 +44,7 @@ class ConditionError(HomeAssistantError): """Return indentation.""" return " " * indent + message - def output(self, indent: int) -> Generator: + def output(self, indent: int) -> Generator[str, None, None]: """Yield an indented representation.""" raise NotImplementedError() @@ -58,7 +60,7 @@ class ConditionErrorMessage(ConditionError): # A message describing this error message: str = attr.ib() - def output(self, indent: int) -> Generator: + def output(self, indent: int) -> Generator[str, None, None]: """Yield an indented representation.""" yield self._indent(indent, f"In '{self.type}' condition: {self.message}") @@ -74,7 +76,7 @@ class ConditionErrorIndex(ConditionError): # The error that this error wraps error: ConditionError = attr.ib() - def output(self, indent: int) -> Generator: + def output(self, indent: int) -> Generator[str, None, None]: """Yield an indented representation.""" if self.total > 1: yield self._indent( @@ -93,7 +95,7 @@ class ConditionErrorContainer(ConditionError): # List of ConditionErrors that this error wraps errors: Sequence[ConditionError] = attr.ib() - def output(self, indent: int) -> Generator: + def output(self, indent: int) -> Generator[str, None, None]: """Yield an indented representation.""" for item in self.errors: yield from item.output(indent) diff --git a/homeassistant/helpers/reload.py b/homeassistant/helpers/reload.py index da6c6935b35..cedd07676ba 100644 --- a/homeassistant/helpers/reload.py +++ b/homeassistant/helpers/reload.py @@ -4,6 +4,7 @@ from __future__ import annotations import asyncio from collections.abc import Iterable import logging +from typing import Any from homeassistant import config as conf_util from homeassistant.const import SERVICE_RELOAD @@ -15,11 +16,13 @@ from homeassistant.helpers.typing import ConfigType from homeassistant.loader import async_get_integration from homeassistant.setup import async_setup_component +# mypy: disallow-any-generics + _LOGGER = logging.getLogger(__name__) async def async_reload_integration_platforms( - hass: HomeAssistant, integration_name: str, integration_platforms: Iterable + hass: HomeAssistant, integration_name: str, integration_platforms: Iterable[str] ) -> None: """Reload an integration's platforms. @@ -62,7 +65,7 @@ async def _resetup_platform( if not conf: return - root_config: dict = {integration_platform: []} + root_config: dict[str, Any] = {integration_platform: []} # Extract only the config for template, ignore the rest. for p_type, p_config in config_per_platform(conf, integration_platform): if p_type != integration_name: @@ -102,7 +105,7 @@ async def _async_setup_platform( hass: HomeAssistant, integration_name: str, integration_platform: str, - platform_configs: list[dict], + platform_configs: list[dict[str, Any]], ) -> None: """Platform for the first time when new configuration is added.""" if integration_platform not in hass.data: @@ -120,7 +123,7 @@ async def _async_setup_platform( async def _async_reconfig_platform( - platform: EntityPlatform, platform_configs: list[dict] + platform: EntityPlatform, platform_configs: list[dict[str, Any]] ) -> None: """Reconfigure an already loaded platform.""" await platform.async_reset() @@ -155,7 +158,7 @@ def async_get_platform_without_config_entry( async def async_setup_reload_service( - hass: HomeAssistant, domain: str, platforms: Iterable + hass: HomeAssistant, domain: str, platforms: Iterable[str] ) -> None: """Create the reload service for the domain.""" if hass.services.has_service(domain, SERVICE_RELOAD): @@ -171,7 +174,9 @@ async def async_setup_reload_service( ) -def setup_reload_service(hass: HomeAssistant, domain: str, platforms: Iterable) -> None: +def setup_reload_service( + hass: HomeAssistant, domain: str, platforms: Iterable[str] +) -> None: """Sync version of async_setup_reload_service.""" asyncio.run_coroutine_threadsafe( async_setup_reload_service(hass, domain, platforms), diff --git a/homeassistant/helpers/script_variables.py b/homeassistant/helpers/script_variables.py index 23241f22d1e..3dae84166f6 100644 --- a/homeassistant/helpers/script_variables.py +++ b/homeassistant/helpers/script_variables.py @@ -8,6 +8,8 @@ from homeassistant.core import HomeAssistant, callback from . import template +# mypy: disallow-any-generics + class ScriptVariables: """Class to hold and render script variables.""" @@ -65,6 +67,6 @@ class ScriptVariables: return rendered_variables - def as_dict(self) -> dict: + def as_dict(self) -> dict[str, Any]: """Return dict version of this class.""" return self.variables diff --git a/homeassistant/scripts/__init__.py b/homeassistant/scripts/__init__.py index b31fc718173..69ca1d6083b 100644 --- a/homeassistant/scripts/__init__.py +++ b/homeassistant/scripts/__init__.py @@ -15,10 +15,10 @@ from homeassistant.config import get_default_config_dir from homeassistant.requirements import pip_kwargs from homeassistant.util.package import install_package, is_installed, is_virtual_env -# mypy: allow-untyped-defs, no-warn-return-any +# mypy: allow-untyped-defs, disallow-any-generics, no-warn-return-any -def run(args: list) -> int: +def run(args: list[str]) -> int: """Run a script.""" scripts = [] path = os.path.dirname(__file__) diff --git a/homeassistant/setup.py b/homeassistant/setup.py index 9575a4331b8..95bb29c4b9d 100644 --- a/homeassistant/setup.py +++ b/homeassistant/setup.py @@ -16,10 +16,13 @@ from homeassistant.const import ( EVENT_HOMEASSISTANT_START, PLATFORM_FORMAT, ) +from homeassistant.core import CALLBACK_TYPE from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.typing import ConfigType from homeassistant.util import dt as dt_util, ensure_unique_string +# mypy: disallow-any-generics + _LOGGER = logging.getLogger(__name__) ATTR_COMPONENT = "component" @@ -422,7 +425,7 @@ def _async_when_setup( hass.async_create_task(when_setup()) return - listeners: list[Callable] = [] + listeners: list[CALLBACK_TYPE] = [] async def _matched_event(event: core.Event) -> None: """Call the callback when we matched an event.""" @@ -443,7 +446,7 @@ def _async_when_setup( @core.callback -def async_get_loaded_integrations(hass: core.HomeAssistant) -> set: +def async_get_loaded_integrations(hass: core.HomeAssistant) -> set[str]: """Return the complete list of loaded integrations.""" integrations = set() for component in hass.config.components: @@ -457,7 +460,9 @@ def async_get_loaded_integrations(hass: core.HomeAssistant) -> set: @contextlib.contextmanager -def async_start_setup(hass: core.HomeAssistant, components: Iterable) -> Generator: +def async_start_setup( + hass: core.HomeAssistant, components: Iterable[str] +) -> Generator[None, None, None]: """Keep track of when setup starts and finishes.""" setup_started = hass.data.setdefault(DATA_SETUP_STARTED, {}) started = dt_util.utcnow() diff --git a/homeassistant/util/color.py b/homeassistant/util/color.py index 47144f0e782..c81beddb07a 100644 --- a/homeassistant/util/color.py +++ b/homeassistant/util/color.py @@ -6,6 +6,8 @@ import math import attr +# mypy: disallow-any-generics + # Official CSS3 colors from w3.org: # https://www.w3.org/TR/2010/PR-css3-color-20101028/#html4 # names do not have spaces in them so that we can compare against @@ -392,7 +394,9 @@ def color_hs_to_xy( return color_RGB_to_xy(*color_hs_to_RGB(iH, iS), Gamut) -def _match_max_scale(input_colors: tuple, output_colors: tuple) -> tuple: +def _match_max_scale( + input_colors: tuple[int, ...], output_colors: tuple[int, ...] +) -> tuple[int, ...]: """Match the maximum value of the output to the input.""" max_in = max(input_colors) max_out = max(output_colors)