From a27d483009a969cedd6156071811674c1e19b62a Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Wed, 6 Jul 2022 10:25:53 +0200 Subject: [PATCH] Remove unifi from mypy ignore list (#74456) * Remove unifi diagnostics from mypy ignore list * Remove unifi init from mypy ignore list * Remove unifi device tracker from mypy ignore list * Adjust doc string * Adjust doc string * Remove unifi entity base from mypy ignore list * Keep comprehension * Remove unifi config flow from mypy ignore list * Fix circular import --- homeassistant/components/unifi/__init__.py | 8 +++++- homeassistant/components/unifi/config_flow.py | 28 ++++++++----------- .../components/unifi/device_tracker.py | 12 +++----- homeassistant/components/unifi/diagnostics.py | 5 ++-- .../components/unifi/unifi_client.py | 8 ++++-- .../components/unifi/unifi_entity_base.py | 15 +++++++--- mypy.ini | 15 ---------- script/hassfest/mypy_config.py | 5 ---- 8 files changed, 43 insertions(+), 53 deletions(-) diff --git a/homeassistant/components/unifi/__init__.py b/homeassistant/components/unifi/__init__.py index 7a874aff993..1369bb69e1b 100644 --- a/homeassistant/components/unifi/__init__.py +++ b/homeassistant/components/unifi/__init__.py @@ -1,4 +1,7 @@ """Integration to UniFi Network and its various features.""" +from collections.abc import Mapping +from typing import Any + from homeassistant.config_entries import ConfigEntry from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.core import HomeAssistant, callback @@ -92,7 +95,10 @@ async def async_flatten_entry_data( Keep controller key layer in case user rollbacks. """ - data: dict = {**config_entry.data, **config_entry.data[CONF_CONTROLLER]} + data: Mapping[str, Any] = { + **config_entry.data, + **config_entry.data[CONF_CONTROLLER], + } if config_entry.data != data: hass.config_entries.async_update_entry(config_entry, data=data) diff --git a/homeassistant/components/unifi/config_flow.py b/homeassistant/components/unifi/config_flow.py index fcf5970bf6c..2f49c15e4d8 100644 --- a/homeassistant/components/unifi/config_flow.py +++ b/homeassistant/components/unifi/config_flow.py @@ -46,7 +46,7 @@ from .const import ( DEFAULT_POE_CLIENTS, DOMAIN as UNIFI_DOMAIN, ) -from .controller import get_controller +from .controller import UniFiController, get_controller from .errors import AuthenticationRequired, CannotConnect DEFAULT_PORT = 443 @@ -75,11 +75,11 @@ class UnifiFlowHandler(config_entries.ConfigFlow, domain=UNIFI_DOMAIN): def __init__(self) -> None: """Initialize the UniFi Network flow.""" - self.config = {} - self.site_ids = {} - self.site_names = {} - self.reauth_config_entry = None - self.reauth_schema = {} + self.config: dict[str, Any] = {} + self.site_ids: dict[str, str] = {} + self.site_names: dict[str, str] = {} + self.reauth_config_entry: config_entries.ConfigEntry | None = None + self.reauth_schema: dict[vol.Marker, Any] = {} async def async_step_user( self, user_input: dict[str, Any] | None = None @@ -156,8 +156,6 @@ class UnifiFlowHandler(config_entries.ConfigFlow, domain=UNIFI_DOMAIN): self, user_input: dict[str, Any] | None = None ) -> FlowResult: """Select site to control.""" - errors = {} - if user_input is not None: unique_id = user_input[CONF_SITE_ID] @@ -173,9 +171,9 @@ class UnifiFlowHandler(config_entries.ConfigFlow, domain=UNIFI_DOMAIN): abort_reason = "reauth_successful" if config_entry: - controller = self.hass.data.get(UNIFI_DOMAIN, {}).get( - config_entry.entry_id - ) + controller: UniFiController | None = self.hass.data.get( + UNIFI_DOMAIN, {} + ).get(config_entry.entry_id) if controller and controller.available: return self.async_abort(reason="already_configured") @@ -199,7 +197,6 @@ class UnifiFlowHandler(config_entries.ConfigFlow, domain=UNIFI_DOMAIN): data_schema=vol.Schema( {vol.Required(CONF_SITE_ID): vol.In(self.site_names)} ), - errors=errors, ) async def async_step_reauth(self, entry_data: Mapping[str, Any]) -> FlowResult: @@ -207,6 +204,7 @@ class UnifiFlowHandler(config_entries.ConfigFlow, domain=UNIFI_DOMAIN): config_entry = self.hass.config_entries.async_get_entry( self.context["entry_id"] ) + assert config_entry self.reauth_config_entry = config_entry self.context["title_placeholders"] = { @@ -258,11 +256,12 @@ class UnifiFlowHandler(config_entries.ConfigFlow, domain=UNIFI_DOMAIN): class UnifiOptionsFlowHandler(config_entries.OptionsFlow): """Handle Unifi Network options.""" + controller: UniFiController + def __init__(self, config_entry: config_entries.ConfigEntry) -> None: """Initialize UniFi Network options flow.""" self.config_entry = config_entry self.options = dict(config_entry.options) - self.controller = None async def async_step_init( self, user_input: dict[str, Any] | None = None @@ -379,8 +378,6 @@ class UnifiOptionsFlowHandler(config_entries.OptionsFlow): self, user_input: dict[str, Any] | None = None ) -> FlowResult: """Manage configuration of network access controlled clients.""" - errors = {} - if user_input is not None: self.options.update(user_input) return await self.async_step_statistics_sensors() @@ -417,7 +414,6 @@ class UnifiOptionsFlowHandler(config_entries.OptionsFlow): ): bool, } ), - errors=errors, last_step=False, ) diff --git a/homeassistant/components/unifi/device_tracker.py b/homeassistant/components/unifi/device_tracker.py index b2070362d02..f2c2230b9e0 100644 --- a/homeassistant/components/unifi/device_tracker.py +++ b/homeassistant/components/unifi/device_tracker.py @@ -27,7 +27,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback import homeassistant.util.dt as dt_util from .const import DOMAIN as UNIFI_DOMAIN -from .unifi_client import UniFiClient +from .controller import UniFiController +from .unifi_client import UniFiClientBase from .unifi_entity_base import UniFiBase LOGGER = logging.getLogger(__name__) @@ -79,7 +80,7 @@ async def async_setup_entry( async_add_entities: AddEntitiesCallback, ) -> None: """Set up device tracker for UniFi Network integration.""" - controller = hass.data[UNIFI_DOMAIN][config_entry.entry_id] + controller: UniFiController = hass.data[UNIFI_DOMAIN][config_entry.entry_id] controller.entities[DOMAIN] = {CLIENT_TRACKER: set(), DEVICE_TRACKER: set()} @callback @@ -144,7 +145,7 @@ def add_device_entities(controller, async_add_entities, devices): async_add_entities(trackers) -class UniFiClientTracker(UniFiClient, ScannerEntity): +class UniFiClientTracker(UniFiClientBase, ScannerEntity): """Representation of a network client.""" DOMAIN = DOMAIN @@ -261,11 +262,6 @@ class UniFiClientTracker(UniFiClient, ScannerEntity): self.async_write_ha_state() self._async_log_debug_data("make_disconnected") - @property - def device_info(self) -> None: - """Return no device info.""" - return None - @property def is_connected(self): """Return true if the client is connected to the network.""" diff --git a/homeassistant/components/unifi/diagnostics.py b/homeassistant/components/unifi/diagnostics.py index ed059856881..b35fd520ab0 100644 --- a/homeassistant/components/unifi/diagnostics.py +++ b/homeassistant/components/unifi/diagnostics.py @@ -12,6 +12,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import format_mac from .const import CONF_CONTROLLER, DOMAIN as UNIFI_DOMAIN +from .controller import UniFiController TO_REDACT = {CONF_CONTROLLER, CONF_PASSWORD} REDACT_CONFIG = {CONF_CONTROLLER, CONF_HOST, CONF_PASSWORD, CONF_USERNAME} @@ -56,7 +57,7 @@ def async_replace_list_data( """Redact sensitive data in a list.""" redacted = [] for item in data: - new_value = None + new_value: Any | None = None if isinstance(item, (list, set, tuple)): new_value = async_replace_list_data(item, to_replace) elif isinstance(item, Mapping): @@ -74,7 +75,7 @@ async def async_get_config_entry_diagnostics( hass: HomeAssistant, config_entry: ConfigEntry ) -> dict[str, Any]: """Return diagnostics for a config entry.""" - controller = hass.data[UNIFI_DOMAIN][config_entry.entry_id] + controller: UniFiController = hass.data[UNIFI_DOMAIN][config_entry.entry_id] diag: dict[str, Any] = {} macs_to_redact: dict[str, str] = {} diff --git a/homeassistant/components/unifi/unifi_client.py b/homeassistant/components/unifi/unifi_client.py index 9e90eef518a..82aece81b6d 100644 --- a/homeassistant/components/unifi/unifi_client.py +++ b/homeassistant/components/unifi/unifi_client.py @@ -5,8 +5,8 @@ from homeassistant.helpers.entity import DeviceInfo from .unifi_entity_base import UniFiBase -class UniFiClient(UniFiBase): - """Base class for UniFi clients.""" +class UniFiClientBase(UniFiBase): + """Base class for UniFi clients (without device info).""" def __init__(self, client, controller) -> None: """Set up client.""" @@ -44,6 +44,10 @@ class UniFiClient(UniFiBase): """Return if controller is available.""" return self.controller.available + +class UniFiClient(UniFiClientBase): + """Base class for UniFi clients (with device info).""" + @property def device_info(self) -> DeviceInfo: """Return a client description for device registry.""" diff --git a/homeassistant/components/unifi/unifi_entity_base.py b/homeassistant/components/unifi/unifi_entity_base.py index c611fc1ee60..466764714cf 100644 --- a/homeassistant/components/unifi/unifi_entity_base.py +++ b/homeassistant/components/unifi/unifi_entity_base.py @@ -1,12 +1,18 @@ """Base class for UniFi Network entities.""" +from __future__ import annotations + +from collections.abc import Callable import logging -from typing import Any +from typing import TYPE_CHECKING, Any from homeassistant.core import callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity +if TYPE_CHECKING: + from .controller import UniFiController + _LOGGER = logging.getLogger(__name__) @@ -16,7 +22,7 @@ class UniFiBase(Entity): DOMAIN = "" TYPE = "" - def __init__(self, item, controller) -> None: + def __init__(self, item, controller: UniFiController) -> None: """Set up UniFi Network entity base. Register mac to controller entities to cover disabled entities. @@ -38,11 +44,12 @@ class UniFiBase(Entity): self.entity_id, self.key, ) - for signal, method in ( + signals: tuple[tuple[str, Callable[..., Any]], ...] = ( (self.controller.signal_reachable, self.async_signal_reachable_callback), (self.controller.signal_options_update, self.options_updated), (self.controller.signal_remove, self.remove_item), - ): + ) + for signal, method in signals: self.async_on_remove(async_dispatcher_connect(self.hass, signal, method)) self._item.register_callback(self.async_update_callback) diff --git a/mypy.ini b/mypy.ini index 52c4dce061f..08cd36dfaea 100644 --- a/mypy.ini +++ b/mypy.ini @@ -2890,21 +2890,6 @@ ignore_errors = true [mypy-homeassistant.components.toon.models] ignore_errors = true -[mypy-homeassistant.components.unifi] -ignore_errors = true - -[mypy-homeassistant.components.unifi.config_flow] -ignore_errors = true - -[mypy-homeassistant.components.unifi.device_tracker] -ignore_errors = true - -[mypy-homeassistant.components.unifi.diagnostics] -ignore_errors = true - -[mypy-homeassistant.components.unifi.unifi_entity_base] -ignore_errors = true - [mypy-homeassistant.components.withings] ignore_errors = true diff --git a/script/hassfest/mypy_config.py b/script/hassfest/mypy_config.py index 521c98ea93d..69e9d8fafa4 100644 --- a/script/hassfest/mypy_config.py +++ b/script/hassfest/mypy_config.py @@ -105,11 +105,6 @@ IGNORED_MODULES: Final[list[str]] = [ "homeassistant.components.toon", "homeassistant.components.toon.config_flow", "homeassistant.components.toon.models", - "homeassistant.components.unifi", - "homeassistant.components.unifi.config_flow", - "homeassistant.components.unifi.device_tracker", - "homeassistant.components.unifi.diagnostics", - "homeassistant.components.unifi.unifi_entity_base", "homeassistant.components.withings", "homeassistant.components.withings.binary_sensor", "homeassistant.components.withings.common",