diff --git a/.strict-typing b/.strict-typing index f128385834bbe1..d0b47db2d59869 100644 --- a/.strict-typing +++ b/.strict-typing @@ -304,6 +304,7 @@ homeassistant.components.notify.* homeassistant.components.notion.* homeassistant.components.number.* homeassistant.components.nut.* +homeassistant.components.onboarding.* homeassistant.components.oncue.* homeassistant.components.onewire.* homeassistant.components.open_meteo.* diff --git a/homeassistant/components/onboarding/__init__.py b/homeassistant/components/onboarding/__init__.py index d334a0051c3db7..4243d05c08567c 100644 --- a/homeassistant/components/onboarding/__init__.py +++ b/homeassistant/components/onboarding/__init__.py @@ -1,4 +1,6 @@ """Support to help onboard new users.""" +from __future__ import annotations + from typing import TYPE_CHECKING from homeassistant.core import HomeAssistant, callback @@ -23,10 +25,15 @@ CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN) -class OnboadingStorage(Store): +class OnboadingStorage(Store[dict[str, list[str]]]): """Store onboarding data.""" - async def _async_migrate_func(self, old_major_version, old_minor_version, old_data): + async def _async_migrate_func( + self, + old_major_version: int, + old_minor_version: int, + old_data: dict[str, list[str]], + ) -> dict[str, list[str]]: """Migrate to the new version.""" # From version 1 -> 2, we automatically mark the integration step done if old_major_version < 2: @@ -56,6 +63,7 @@ def async_is_user_onboarded(hass: HomeAssistant) -> bool: async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the onboarding component.""" store = OnboadingStorage(hass, STORAGE_VERSION, STORAGE_KEY, private=True) + data: dict[str, list[str]] | None if (data := await store.async_load()) is None: data = {"done": []} diff --git a/homeassistant/components/onboarding/views.py b/homeassistant/components/onboarding/views.py index b1b4ea292220eb..c403bcd5ab2a69 100644 --- a/homeassistant/components/onboarding/views.py +++ b/homeassistant/components/onboarding/views.py @@ -3,7 +3,7 @@ import asyncio from http import HTTPStatus -from typing import cast +from typing import TYPE_CHECKING, Any, cast from aiohttp import web from aiohttp.web_exceptions import HTTPUnauthorized @@ -21,6 +21,9 @@ from homeassistant.helpers.system_info import async_get_system_info from homeassistant.helpers.translation import async_get_translations +if TYPE_CHECKING: + from . import OnboadingStorage + from .const import ( DEFAULT_AREAS, DOMAIN, @@ -32,7 +35,9 @@ ) -async def async_setup(hass, data, store): +async def async_setup( + hass: HomeAssistant, data: dict[str, list[str]], store: OnboadingStorage +) -> None: """Set up the onboarding view.""" hass.http.register_view(OnboardingView(data, store)) hass.http.register_view(InstallationTypeOnboardingView(data)) @@ -49,12 +54,12 @@ class OnboardingView(HomeAssistantView): url = "/api/onboarding" name = "api:onboarding" - def __init__(self, data, store): + def __init__(self, data: dict[str, list[str]], store: OnboadingStorage) -> None: """Initialize the onboarding view.""" self._store = store self._data = data - async def get(self, request): + async def get(self, request: web.Request) -> web.Response: """Return the onboarding status.""" return self.json( [{"step": key, "done": key in self._data["done"]} for key in STEPS] @@ -68,16 +73,16 @@ class InstallationTypeOnboardingView(HomeAssistantView): url = "/api/onboarding/installation_type" name = "api:onboarding:installation_type" - def __init__(self, data): + def __init__(self, data: dict[str, list[str]]) -> None: """Initialize the onboarding installation type view.""" self._data = data - async def get(self, request): + async def get(self, request: web.Request) -> web.Response: """Return the onboarding status.""" if self._data["done"]: raise HTTPUnauthorized() - hass = request.app["hass"] + hass: HomeAssistant = request.app["hass"] info = await async_get_system_info(hass) return self.json({"installation_type": info["installation_type"]}) @@ -85,20 +90,20 @@ async def get(self, request): class _BaseOnboardingView(HomeAssistantView): """Base class for onboarding.""" - step: str | None = None + step: str - def __init__(self, data, store): + def __init__(self, data: dict[str, list[str]], store: OnboadingStorage) -> None: """Initialize the onboarding view.""" self._store = store self._data = data self._lock = asyncio.Lock() @callback - def _async_is_done(self): + def _async_is_done(self) -> bool: """Return if this step is done.""" return self.step in self._data["done"] - async def _async_mark_done(self, hass): + async def _async_mark_done(self, hass: HomeAssistant) -> None: """Mark step as done.""" self._data["done"].append(self.step) await self._store.async_save(self._data) @@ -180,9 +185,9 @@ class CoreConfigOnboardingView(_BaseOnboardingView): name = "api:onboarding:core_config" step = STEP_CORE_CONFIG - async def post(self, request): + async def post(self, request: web.Request) -> web.Response: """Handle finishing core config step.""" - hass = request.app["hass"] + hass: HomeAssistant = request.app["hass"] async with self._lock: if self._async_is_done(): @@ -205,7 +210,8 @@ async def post(self, request): if ( hassio.is_hassio(hass) - and "raspberrypi" in hassio.get_core_info(hass)["machine"] + and (core_info := hassio.get_core_info(hass)) + and "raspberrypi" in core_info["machine"] ): onboard_integrations.append("rpi_power") @@ -232,9 +238,9 @@ class IntegrationOnboardingView(_BaseOnboardingView): @RequestDataValidator( vol.Schema({vol.Required("client_id"): str, vol.Required("redirect_uri"): str}) ) - async def post(self, request, data): + async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response: """Handle token creation.""" - hass = request.app["hass"] + hass: HomeAssistant = request.app["hass"] refresh_token_id = request[KEY_HASS_REFRESH_TOKEN_ID] async with self._lock: @@ -276,9 +282,9 @@ class AnalyticsOnboardingView(_BaseOnboardingView): name = "api:onboarding:analytics" step = STEP_ANALYTICS - async def post(self, request): + async def post(self, request: web.Request) -> web.Response: """Handle finishing analytics step.""" - hass = request.app["hass"] + hass: HomeAssistant = request.app["hass"] async with self._lock: if self._async_is_done(): diff --git a/homeassistant/components/person/__init__.py b/homeassistant/components/person/__init__.py index 49b719a549032a..f6444a869ee7df 100644 --- a/homeassistant/components/person/__init__.py +++ b/homeassistant/components/person/__init__.py @@ -92,7 +92,13 @@ @bind_hass -async def async_create_person(hass, name, *, user_id=None, device_trackers=None): +async def async_create_person( + hass: HomeAssistant, + name: str, + *, + user_id: str | None = None, + device_trackers: list[str] | None = None, +) -> None: """Create a new person.""" await hass.data[DOMAIN][1].async_create_item( { diff --git a/mypy.ini b/mypy.ini index a47452f6012e3d..87829af666bfea 100644 --- a/mypy.ini +++ b/mypy.ini @@ -2801,6 +2801,16 @@ disallow_untyped_defs = true warn_return_any = true warn_unreachable = true +[mypy-homeassistant.components.onboarding.*] +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.oncue.*] check_untyped_defs = true disallow_incomplete_defs = true