From 8f31b09b55f4c87d6a274ce7340f26c944934f99 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sat, 6 Mar 2021 00:33:26 +0100 Subject: [PATCH] Complete typing on TwenteMilieu integration (#47480) --- .../components/twentemilieu/__init__.py | 23 ++++++++-------- .../components/twentemilieu/config_flow.py | 26 +++++++++++-------- .../components/twentemilieu/sensor.py | 16 +++++++----- .../twentemilieu/test_config_flow.py | 20 ++++++++++---- 4 files changed, 51 insertions(+), 34 deletions(-) diff --git a/homeassistant/components/twentemilieu/__init__.py b/homeassistant/components/twentemilieu/__init__.py index 06c2cb27f35..f53e4463146 100644 --- a/homeassistant/components/twentemilieu/__init__.py +++ b/homeassistant/components/twentemilieu/__init__.py @@ -1,7 +1,8 @@ """Support for Twente Milieu.""" +from __future__ import annotations + import asyncio from datetime import timedelta -from typing import Optional from twentemilieu import TwenteMilieu import voluptuous as vol @@ -15,11 +16,12 @@ from homeassistant.components.twentemilieu.const import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ID +from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.event import async_track_time_interval -from homeassistant.helpers.typing import ConfigType, HomeAssistantType +from homeassistant.helpers.typing import ConfigType SCAN_INTERVAL = timedelta(seconds=3600) @@ -27,9 +29,7 @@ SERVICE_UPDATE = "update" SERVICE_SCHEMA = vol.Schema({vol.Optional(CONF_ID): cv.string}) -async def _update_twentemilieu( - hass: HomeAssistantType, unique_id: Optional[str] -) -> None: +async def _update_twentemilieu(hass: HomeAssistant, unique_id: str | None) -> None: """Update Twente Milieu.""" if unique_id is not None: twentemilieu = hass.data[DOMAIN].get(unique_id) @@ -37,16 +37,15 @@ async def _update_twentemilieu( await twentemilieu.update() async_dispatcher_send(hass, DATA_UPDATE, unique_id) else: - tasks = [] - for twentemilieu in hass.data[DOMAIN].values(): - tasks.append(twentemilieu.update()) - await asyncio.wait(tasks) + await asyncio.wait( + [twentemilieu.update() for twentemilieu in hass.data[DOMAIN].values()] + ) for uid in hass.data[DOMAIN]: async_dispatcher_send(hass, DATA_UPDATE, uid) -async def async_setup(hass: HomeAssistantType, config: ConfigType) -> bool: +async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the Twente Milieu components.""" async def update(call) -> None: @@ -59,7 +58,7 @@ async def async_setup(hass: HomeAssistantType, config: ConfigType) -> bool: return True -async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Twente Milieu from a config entry.""" session = async_get_clientsession(hass) twentemilieu = TwenteMilieu( @@ -85,7 +84,7 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool return True -async def async_unload_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload Twente Milieu config entry.""" await hass.config_entries.async_forward_entry_unload(entry, "sensor") diff --git a/homeassistant/components/twentemilieu/config_flow.py b/homeassistant/components/twentemilieu/config_flow.py index 76c9f33b3e9..769d24e334a 100644 --- a/homeassistant/components/twentemilieu/config_flow.py +++ b/homeassistant/components/twentemilieu/config_flow.py @@ -1,4 +1,8 @@ """Config flow to configure the Twente Milieu integration.""" +from __future__ import annotations + +from typing import Any + from twentemilieu import ( TwenteMilieu, TwenteMilieuAddressError, @@ -7,25 +11,23 @@ from twentemilieu import ( import voluptuous as vol from homeassistant import config_entries -from homeassistant.components.twentemilieu.const import ( - CONF_HOUSE_LETTER, - CONF_HOUSE_NUMBER, - CONF_POST_CODE, - DOMAIN, -) from homeassistant.config_entries import ConfigFlow from homeassistant.const import CONF_ID from homeassistant.helpers.aiohttp_client import async_get_clientsession +from .const import CONF_HOUSE_LETTER, CONF_HOUSE_NUMBER, CONF_POST_CODE +from .const import DOMAIN # pylint: disable=unused-import -@config_entries.HANDLERS.register(DOMAIN) -class TwenteMilieuFlowHandler(ConfigFlow): + +class TwenteMilieuFlowHandler(ConfigFlow, domain=DOMAIN): """Handle a Twente Milieu config flow.""" VERSION = 1 CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL - async def _show_setup_form(self, errors=None): + async def _show_setup_form( + self, errors: dict[str, str] | None = None + ) -> dict[str, Any]: """Show the setup form to the user.""" return self.async_show_form( step_id="user", @@ -39,7 +41,9 @@ class TwenteMilieuFlowHandler(ConfigFlow): errors=errors or {}, ) - async def async_step_user(self, user_input=None): + async def async_step_user( + self, user_input: dict[str, Any] | None = None + ) -> dict[str, Any]: """Handle a flow initiated by the user.""" if user_input is None: return await self._show_setup_form(user_input) @@ -70,7 +74,7 @@ class TwenteMilieuFlowHandler(ConfigFlow): return self.async_abort(reason="already_configured") return self.async_create_entry( - title=unique_id, + title=str(unique_id), data={ CONF_ID: unique_id, CONF_POST_CODE: user_input[CONF_POST_CODE], diff --git a/homeassistant/components/twentemilieu/sensor.py b/homeassistant/components/twentemilieu/sensor.py index 92194e12172..34da746cf06 100644 --- a/homeassistant/components/twentemilieu/sensor.py +++ b/homeassistant/components/twentemilieu/sensor.py @@ -1,5 +1,7 @@ """Support for Twente Milieu sensors.""" -from typing import Any, Dict +from __future__ import annotations + +from typing import Any, Callable from twentemilieu import ( WASTE_TYPE_NON_RECYCLABLE, @@ -10,20 +12,22 @@ from twentemilieu import ( TwenteMilieuConnectionError, ) -from homeassistant.components.twentemilieu.const import DATA_UPDATE, DOMAIN from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ID -from homeassistant.core import callback +from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity -from homeassistant.helpers.typing import HomeAssistantType + +from .const import DATA_UPDATE, DOMAIN PARALLEL_UPDATES = 1 async def async_setup_entry( - hass: HomeAssistantType, entry: ConfigEntry, async_add_entities + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: Callable[[list[Entity], bool], None], ) -> None: """Set up Twente Milieu sensor based on a config entry.""" twentemilieu = hass.data[DOMAIN][entry.data[CONF_ID]] @@ -142,7 +146,7 @@ class TwenteMilieuSensor(Entity): self._state = next_pickup.date().isoformat() @property - def device_info(self) -> Dict[str, Any]: + def device_info(self) -> dict[str, Any]: """Return device information about Twente Milieu.""" return { "identifiers": {(DOMAIN, self._unique_id)}, diff --git a/tests/components/twentemilieu/test_config_flow.py b/tests/components/twentemilieu/test_config_flow.py index ec3edf73f29..27fd86d0868 100644 --- a/tests/components/twentemilieu/test_config_flow.py +++ b/tests/components/twentemilieu/test_config_flow.py @@ -10,8 +10,10 @@ from homeassistant.components.twentemilieu.const import ( DOMAIN, ) from homeassistant.const import CONF_ID, CONTENT_TYPE_JSON +from homeassistant.core import HomeAssistant from tests.common import MockConfigEntry +from tests.test_util.aiohttp import AiohttpClientMocker FIXTURE_USER_INPUT = { CONF_ID: "12345", @@ -21,7 +23,7 @@ FIXTURE_USER_INPUT = { } -async def test_show_set_form(hass): +async def test_show_set_form(hass: HomeAssistant) -> None: """Test that the setup form is served.""" flow = config_flow.TwenteMilieuFlowHandler() flow.hass = hass @@ -31,7 +33,9 @@ async def test_show_set_form(hass): assert result["step_id"] == "user" -async def test_connection_error(hass, aioclient_mock): +async def test_connection_error( + hass: HomeAssistant, aioclient_mock: AiohttpClientMocker +) -> None: """Test we show user form on Twente Milieu connection error.""" aioclient_mock.post( "https://twentemilieuapi.ximmio.com/api/FetchAdress", exc=aiohttp.ClientError @@ -46,7 +50,9 @@ async def test_connection_error(hass, aioclient_mock): assert result["errors"] == {"base": "cannot_connect"} -async def test_invalid_address(hass, aioclient_mock): +async def test_invalid_address( + hass: HomeAssistant, aioclient_mock: AiohttpClientMocker +) -> None: """Test we show user form on Twente Milieu invalid address error.""" aioclient_mock.post( "https://twentemilieuapi.ximmio.com/api/FetchAdress", @@ -63,7 +69,9 @@ async def test_invalid_address(hass, aioclient_mock): assert result["errors"] == {"base": "invalid_address"} -async def test_address_already_set_up(hass, aioclient_mock): +async def test_address_already_set_up( + hass: HomeAssistant, aioclient_mock: AiohttpClientMocker +) -> None: """Test we abort if address has already been set up.""" MockConfigEntry(domain=DOMAIN, data=FIXTURE_USER_INPUT, title="12345").add_to_hass( hass @@ -83,7 +91,9 @@ async def test_address_already_set_up(hass, aioclient_mock): assert result["reason"] == "already_configured" -async def test_full_flow_implementation(hass, aioclient_mock): +async def test_full_flow_implementation( + hass: HomeAssistant, aioclient_mock: AiohttpClientMocker +) -> None: """Test registering an integration and finishing flow works.""" aioclient_mock.post( "https://twentemilieuapi.ximmio.com/api/FetchAdress",