From 500d9a4da00008ff54435ebc11466cf1abdfa916 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Tue, 8 Aug 2023 17:15:25 +0200 Subject: [PATCH] Alexa strict type hints (#97485) * Enable strict typing * Adjustments for stict typing --- .strict-typing | 1 + homeassistant/components/alexa/auth.py | 3 ++- homeassistant/components/alexa/capabilities.py | 2 +- homeassistant/components/alexa/config.py | 2 +- homeassistant/components/alexa/entities.py | 9 +++++---- homeassistant/components/alexa/handlers.py | 4 +++- homeassistant/components/alexa/intent.py | 5 +++-- homeassistant/components/alexa/smart_home.py | 2 +- homeassistant/components/alexa/state_report.py | 17 ++++++++++------- mypy.ini | 10 ++++++++++ 10 files changed, 37 insertions(+), 18 deletions(-) diff --git a/.strict-typing b/.strict-typing index eec8bd906fe..c56c7d9f137 100644 --- a/.strict-typing +++ b/.strict-typing @@ -53,6 +53,7 @@ homeassistant.components.airzone_cloud.* homeassistant.components.aladdin_connect.* homeassistant.components.alarm_control_panel.* homeassistant.components.alert.* +homeassistant.components.alexa.* homeassistant.components.amazon_polly.* homeassistant.components.ambient_station.* homeassistant.components.amcrest.* diff --git a/homeassistant/components/alexa/auth.py b/homeassistant/components/alexa/auth.py index ea237e4c92c..61a87d9ebab 100644 --- a/homeassistant/components/alexa/auth.py +++ b/homeassistant/components/alexa/auth.py @@ -76,7 +76,8 @@ class Auth: assert self._prefs is not None if self.is_token_valid(): _LOGGER.debug("Token still valid, using it") - return self._prefs[STORAGE_ACCESS_TOKEN] + token: str = self._prefs[STORAGE_ACCESS_TOKEN] + return token if self._prefs[STORAGE_REFRESH_TOKEN] is None: _LOGGER.debug("Token invalid and no refresh token available") diff --git a/homeassistant/components/alexa/capabilities.py b/homeassistant/components/alexa/capabilities.py index 042ddfac3d5..a7065a38686 100644 --- a/homeassistant/components/alexa/capabilities.py +++ b/homeassistant/components/alexa/capabilities.py @@ -1990,7 +1990,7 @@ class AlexaDoorbellEventSource(AlexaCapability): """Return the Alexa API name of this interface.""" return "Alexa.DoorbellEventSource" - def capability_proactively_reported(self): + def capability_proactively_reported(self) -> bool: """Return True for proactively reported capability.""" return True diff --git a/homeassistant/components/alexa/config.py b/homeassistant/components/alexa/config.py index 8c9965662bc..a1ab1d77081 100644 --- a/homeassistant/components/alexa/config.py +++ b/homeassistant/components/alexa/config.py @@ -145,7 +145,7 @@ class AlexaConfigStore: def authorized(self) -> bool: """Return authorization status.""" assert self._data is not None - return self._data[STORE_AUTHORIZED] + return bool(self._data[STORE_AUTHORIZED]) @callback def set_authorized(self, authorized: bool) -> None: diff --git a/homeassistant/components/alexa/entities.py b/homeassistant/components/alexa/entities.py index 2931326d430..7f6331515c6 100644 --- a/homeassistant/components/alexa/entities.py +++ b/homeassistant/components/alexa/entities.py @@ -280,9 +280,10 @@ class AlexaEntity: def friendly_name(self) -> str: """Return the Alexa API friendly name.""" - return self.entity_conf.get(CONF_NAME, self.entity.name).translate( - TRANSLATION_TABLE - ) + friendly_name: str = self.entity_conf.get( + CONF_NAME, self.entity.name + ).translate(TRANSLATION_TABLE) + return friendly_name def description(self) -> str: """Return the Alexa API description.""" @@ -725,7 +726,7 @@ class MediaPlayerCapabilities(AlexaEntity): class SceneCapabilities(AlexaEntity): """Class to represent Scene capabilities.""" - def description(self): + def description(self) -> str: """Return the Alexa API description.""" description = AlexaEntity.description(self) if "scene" not in description.casefold(): diff --git a/homeassistant/components/alexa/handlers.py b/homeassistant/components/alexa/handlers.py index a37c8b64ab8..06ce4f88b56 100644 --- a/homeassistant/components/alexa/handlers.py +++ b/homeassistant/components/alexa/handlers.py @@ -758,7 +758,9 @@ async def async_api_previous( return directive.response() -def temperature_from_object(hass: ha.HomeAssistant, temp_obj, interval=False): +def temperature_from_object( + hass: ha.HomeAssistant, temp_obj: dict[str, Any], interval: bool = False +) -> float: """Get temperature from Temperature object in requested unit.""" to_unit = hass.config.units.temperature_unit from_unit = UnitOfTemperature.CELSIUS diff --git a/homeassistant/components/alexa/intent.py b/homeassistant/components/alexa/intent.py index ad950803f5c..58319dd44b5 100644 --- a/homeassistant/components/alexa/intent.py +++ b/homeassistant/components/alexa/intent.py @@ -129,7 +129,8 @@ async def async_handle_message( if not (handler := HANDLERS.get(req_type)): raise UnknownRequest(f"Received unknown request {req_type}") - return await handler(hass, message) + response: dict[str, Any] = await handler(hass, message) + return response @HANDLERS.register("SessionEndedRequest") @@ -282,7 +283,7 @@ class AlexaIntentResponse: self.speech = {"type": speech_type.value, key: text} - def add_reprompt(self, speech_type: SpeechType, text) -> None: + def add_reprompt(self, speech_type: SpeechType, text: str) -> None: """Add reprompt if user does not answer.""" assert self.reprompt is None diff --git a/homeassistant/components/alexa/smart_home.py b/homeassistant/components/alexa/smart_home.py index 288f6adcc15..a8101896116 100644 --- a/homeassistant/components/alexa/smart_home.py +++ b/homeassistant/components/alexa/smart_home.py @@ -82,7 +82,7 @@ class AlexaConfig(AbstractConfig): def should_expose(self, entity_id: str) -> bool: """If an entity should be exposed.""" if not self._config[CONF_FILTER].empty_filter: - return self._config[CONF_FILTER](entity_id) + return bool(self._config[CONF_FILTER](entity_id)) entity_registry = er.async_get(self.hass) if registry_entry := entity_registry.async_get(entity_id): diff --git a/homeassistant/components/alexa/state_report.py b/homeassistant/components/alexa/state_report.py index 4e3c33386ca..bbaa8a240f7 100644 --- a/homeassistant/components/alexa/state_report.py +++ b/homeassistant/components/alexa/state_report.py @@ -14,7 +14,7 @@ import async_timeout from homeassistant.components import event from homeassistant.const import MATCH_ALL, STATE_ON -from homeassistant.core import HomeAssistant, State, callback +from homeassistant.core import CALLBACK_TYPE, HomeAssistant, State, callback from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.event import async_track_state_change from homeassistant.helpers.significant_change import create_checker @@ -159,12 +159,14 @@ class AlexaResponse: @property def name(self) -> str: """Return the name of this response.""" - return self._response[API_EVENT][API_HEADER]["name"] + name: str = self._response[API_EVENT][API_HEADER]["name"] + return name @property def namespace(self) -> str: """Return the namespace of this response.""" - return self._response[API_EVENT][API_HEADER]["namespace"] + namespace: str = self._response[API_EVENT][API_HEADER]["namespace"] + return namespace def set_correlation_token(self, token: str) -> None: """Set the correlationToken. @@ -196,9 +198,10 @@ class AlexaResponse: """ self._response[API_EVENT][API_ENDPOINT] = endpoint - def _properties(self): - context = self._response.setdefault(API_CONTEXT, {}) - return context.setdefault("properties", []) + def _properties(self) -> list[dict[str, Any]]: + context: dict[str, Any] = self._response.setdefault(API_CONTEXT, {}) + properties: list[dict[str, Any]] = context.setdefault("properties", []) + return properties def add_context_property(self, prop: dict[str, Any]) -> None: """Add a property to the response context. @@ -236,7 +239,7 @@ class AlexaResponse: async def async_enable_proactive_mode( hass: HomeAssistant, smart_home_config: AbstractConfig -): +) -> CALLBACK_TYPE | None: """Enable the proactive mode. Proactive mode makes this component report state changes to Alexa. diff --git a/mypy.ini b/mypy.ini index 639f27bbabb..b3ab53bf8a9 100644 --- a/mypy.ini +++ b/mypy.ini @@ -291,6 +291,16 @@ disallow_untyped_defs = true warn_return_any = true warn_unreachable = true +[mypy-homeassistant.components.alexa.*] +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.amazon_polly.*] check_untyped_defs = true disallow_incomplete_defs = true