From e469c6892b29a3580507b510cf8c2867e19d7986 Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Sun, 24 Dec 2023 02:16:15 +0100 Subject: [PATCH] Add Airnow to strict typing (#105566) --- .strict-typing | 1 + .../components/airnow/config_flow.py | 35 ++++++++++++------- .../components/airnow/coordinator.py | 19 +++++++--- mypy.ini | 10 ++++++ 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/.strict-typing b/.strict-typing index d83bd4d7adb5..aa9c801fbf67 100644 --- a/.strict-typing +++ b/.strict-typing @@ -48,6 +48,7 @@ homeassistant.components.adguard.* homeassistant.components.aftership.* homeassistant.components.air_quality.* homeassistant.components.airly.* +homeassistant.components.airnow.* homeassistant.components.airvisual.* homeassistant.components.airvisual_pro.* homeassistant.components.airzone.* diff --git a/homeassistant/components/airnow/config_flow.py b/homeassistant/components/airnow/config_flow.py index d72d145f7dec..a6fa7aa5088d 100644 --- a/homeassistant/components/airnow/config_flow.py +++ b/homeassistant/components/airnow/config_flow.py @@ -6,8 +6,17 @@ from pyairnow import WebServiceAPI from pyairnow.errors import AirNowError, EmptyResponseError, InvalidKeyError import voluptuous as vol -from homeassistant import config_entries, core, data_entry_flow, exceptions +from homeassistant import core +from homeassistant.config_entries import ( + ConfigEntry, + ConfigFlow, + OptionsFlow, + OptionsFlowWithConfigEntry, +) from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS +from homeassistant.core import HomeAssistant +from homeassistant.data_entry_flow import FlowResult +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.aiohttp_client import async_get_clientsession import homeassistant.helpers.config_validation as cv @@ -16,7 +25,7 @@ from .const import DOMAIN _LOGGER = logging.getLogger(__name__) -async def validate_input(hass: core.HomeAssistant, data): +async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> bool: """Validate the user input allows us to connect. Data has the keys from DATA_SCHEMA with values provided by the user. @@ -46,12 +55,14 @@ async def validate_input(hass: core.HomeAssistant, data): return True -class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): +class AirNowConfigFlow(ConfigFlow, domain=DOMAIN): """Handle a config flow for AirNow.""" VERSION = 2 - async def async_step_user(self, user_input=None): + async def async_step_user( + self, user_input: dict[str, Any] | None = None + ) -> FlowResult: """Handle the initial step.""" errors = {} if user_input is not None: @@ -108,18 +119,18 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): @staticmethod @core.callback def async_get_options_flow( - config_entry: config_entries.ConfigEntry, - ) -> config_entries.OptionsFlow: + config_entry: ConfigEntry, + ) -> OptionsFlow: """Return the options flow.""" - return OptionsFlowHandler(config_entry) + return AirNowOptionsFlowHandler(config_entry) -class OptionsFlowHandler(config_entries.OptionsFlowWithConfigEntry): +class AirNowOptionsFlowHandler(OptionsFlowWithConfigEntry): """Handle an options flow for AirNow.""" async def async_step_init( self, user_input: dict[str, Any] | None = None - ) -> data_entry_flow.FlowResult: + ) -> FlowResult: """Manage the options.""" if user_input is not None: return self.async_create_entry(data=user_input) @@ -141,13 +152,13 @@ class OptionsFlowHandler(config_entries.OptionsFlowWithConfigEntry): ) -class CannotConnect(exceptions.HomeAssistantError): +class CannotConnect(HomeAssistantError): """Error to indicate we cannot connect.""" -class InvalidAuth(exceptions.HomeAssistantError): +class InvalidAuth(HomeAssistantError): """Error to indicate there is invalid auth.""" -class InvalidLocation(exceptions.HomeAssistantError): +class InvalidLocation(HomeAssistantError): """Error to indicate the location is invalid.""" diff --git a/homeassistant/components/airnow/coordinator.py b/homeassistant/components/airnow/coordinator.py index e89afc2f7ce0..4bdaadff0da3 100644 --- a/homeassistant/components/airnow/coordinator.py +++ b/homeassistant/components/airnow/coordinator.py @@ -1,11 +1,15 @@ """DataUpdateCoordinator for the AirNow integration.""" +from datetime import timedelta import logging +from typing import Any +from aiohttp import ClientSession from aiohttp.client_exceptions import ClientConnectorError from pyairnow import WebServiceAPI from pyairnow.conv import aqi_to_concentration from pyairnow.errors import AirNowError +from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import ( @@ -31,12 +35,19 @@ from .const import ( _LOGGER = logging.getLogger(__name__) -class AirNowDataUpdateCoordinator(DataUpdateCoordinator): +class AirNowDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): """The AirNow update coordinator.""" def __init__( - self, hass, session, api_key, latitude, longitude, distance, update_interval - ): + self, + hass: HomeAssistant, + session: ClientSession, + api_key: str, + latitude: float, + longitude: float, + distance: int, + update_interval: timedelta, + ) -> None: """Initialize.""" self.latitude = latitude self.longitude = longitude @@ -46,7 +57,7 @@ class AirNowDataUpdateCoordinator(DataUpdateCoordinator): super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval) - async def _async_update_data(self): + async def _async_update_data(self) -> dict[str, Any]: """Update data via library.""" data = {} try: diff --git a/mypy.ini b/mypy.ini index db175cc13f15..e19c6c6fa925 100644 --- a/mypy.ini +++ b/mypy.ini @@ -240,6 +240,16 @@ disallow_untyped_defs = true warn_return_any = true warn_unreachable = true +[mypy-homeassistant.components.airnow.*] +check_untyped_defs = true +disallow_incomplete_defs = true +disallow_subclassing_any = true +disallow_untyped_calls = true +disallow_untyped_decorators = true +disallow_untyped_defs = true +warn_return_any = true +warn_unreachable = true + [mypy-homeassistant.components.airvisual.*] check_untyped_defs = true disallow_incomplete_defs = true