Enable strict typing for here_travel_time (#83814)

* Enable strict typing for here_travel_time

* Use dict[str, Any] instead of Any

* Use kwargs ctor

* Specify dicts
This commit is contained in:
Kevin Stillhammer 2022-12-18 09:34:47 +01:00 committed by GitHub
parent 119664b55e
commit 487d84c8f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 51 deletions

View File

@ -130,6 +130,7 @@ homeassistant.components.group.*
homeassistant.components.guardian.*
homeassistant.components.hardkernel.*
homeassistant.components.hardware.*
homeassistant.components.here_travel_time.*
homeassistant.components.history.*
homeassistant.components.homeassistant.triggers.event
homeassistant.components.homeassistant_alerts.*

View File

@ -3,6 +3,7 @@ from __future__ import annotations
from datetime import datetime, time, timedelta
import logging
from typing import Any
import here_routing
from here_routing import HERERoutingApi, Return, RoutingMode, Spans, TransportMode
@ -15,7 +16,7 @@ from here_transit import (
)
import voluptuous as vol
from homeassistant.const import ATTR_ATTRIBUTION, UnitOfLength
from homeassistant.const import UnitOfLength
from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.location import find_coordinates
@ -23,18 +24,7 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda
from homeassistant.util import dt
from homeassistant.util.unit_conversion import DistanceConverter
from .const import (
ATTR_DESTINATION,
ATTR_DESTINATION_NAME,
ATTR_DISTANCE,
ATTR_DURATION,
ATTR_DURATION_IN_TRAFFIC,
ATTR_ORIGIN,
ATTR_ORIGIN_NAME,
DEFAULT_SCAN_INTERVAL,
DOMAIN,
ROUTE_MODE_FASTEST,
)
from .const import DEFAULT_SCAN_INTERVAL, DOMAIN, ROUTE_MODE_FASTEST
from .model import HERETravelTimeConfig, HERETravelTimeData
_LOGGER = logging.getLogger(__name__)
@ -96,10 +86,10 @@ class HERERoutingDataUpdateCoordinator(DataUpdateCoordinator):
return self._parse_routing_response(response)
def _parse_routing_response(self, response) -> HERETravelTimeData:
def _parse_routing_response(self, response: dict[str, Any]) -> HERETravelTimeData:
"""Parse the routing response dict to a HERETravelTimeData."""
section: dict = response["routes"][0]["sections"][0]
summary: dict = section["summary"]
section: dict[str, Any] = response["routes"][0]["sections"][0]
summary: dict[str, int] = section["summary"]
mapped_origin_lat: float = section["departure"]["place"]["location"]["lat"]
mapped_origin_lon: float = section["departure"]["place"]["location"]["lng"]
mapped_destination_lat: float = section["arrival"]["place"]["location"]["lat"]
@ -114,16 +104,14 @@ class HERERoutingDataUpdateCoordinator(DataUpdateCoordinator):
if (names := section["spans"][-1].get("names")) is not None:
destination_name = names[0]["value"]
return HERETravelTimeData(
{
ATTR_ATTRIBUTION: None,
ATTR_DURATION: round(summary["baseDuration"] / 60), # type: ignore[misc]
ATTR_DURATION_IN_TRAFFIC: round(summary["duration"] / 60),
ATTR_DISTANCE: distance,
ATTR_ORIGIN: f"{mapped_origin_lat},{mapped_origin_lon}",
ATTR_DESTINATION: f"{mapped_destination_lat},{mapped_destination_lon}",
ATTR_ORIGIN_NAME: origin_name,
ATTR_DESTINATION_NAME: destination_name,
}
attribution=None,
duration=round(summary["baseDuration"] / 60),
duration_in_traffic=round(summary["duration"] / 60),
distance=distance,
origin=f"{mapped_origin_lat},{mapped_origin_lon}",
destination=f"{mapped_destination_lat},{mapped_destination_lon}",
origin_name=origin_name,
destination_name=destination_name,
)
@ -182,9 +170,9 @@ class HERETransitDataUpdateCoordinator(DataUpdateCoordinator):
except (HERETransitConnectionError, HERETransitNoRouteFoundError) as error:
raise UpdateFailed from error
def _parse_transit_response(self, response) -> HERETravelTimeData:
def _parse_transit_response(self, response: dict[str, Any]) -> HERETravelTimeData:
"""Parse the transit response dict to a HERETravelTimeData."""
sections: dict = response["routes"][0]["sections"]
sections: list[dict[str, Any]] = response["routes"][0]["sections"]
attribution: str | None = build_hass_attribution(sections)
mapped_origin_lat: float = sections[0]["departure"]["place"]["location"]["lat"]
mapped_origin_lon: float = sections[0]["departure"]["place"]["location"]["lng"]
@ -203,16 +191,14 @@ class HERETransitDataUpdateCoordinator(DataUpdateCoordinator):
section["travelSummary"]["duration"] for section in sections
)
return HERETravelTimeData(
{
ATTR_ATTRIBUTION: attribution,
ATTR_DURATION: round(duration / 60), # type: ignore[misc]
ATTR_DURATION_IN_TRAFFIC: round(duration / 60),
ATTR_DISTANCE: distance,
ATTR_ORIGIN: f"{mapped_origin_lat},{mapped_origin_lon}",
ATTR_DESTINATION: f"{mapped_destination_lat},{mapped_destination_lon}",
ATTR_ORIGIN_NAME: sections[0]["departure"]["place"].get("name"),
ATTR_DESTINATION_NAME: sections[-1]["arrival"]["place"].get("name"),
}
attribution=attribution,
duration=round(duration / 60),
duration_in_traffic=round(duration / 60),
distance=distance,
origin=f"{mapped_origin_lat},{mapped_origin_lon}",
destination=f"{mapped_destination_lat},{mapped_destination_lon}",
origin_name=sections[0]["departure"]["place"].get("name"),
destination_name=sections[-1]["arrival"]["place"].get("name"),
)
@ -266,7 +252,7 @@ def prepare_parameters(
return (origin, destination, arrival, departure)
def build_hass_attribution(sections: dict) -> str | None:
def build_hass_attribution(sections: list[dict[str, Any]]) -> str | None:
"""Build a hass frontend ready string out of the attributions."""
relevant_attributions = []
for section in sections:

View File

@ -9,14 +9,14 @@ from typing import TypedDict
class HERETravelTimeData(TypedDict):
"""Routing information."""
ATTR_ATTRIBUTION: str | None
ATTR_DURATION: float
ATTR_DURATION_IN_TRAFFIC: float
ATTR_DISTANCE: float
ATTR_ORIGIN: str
ATTR_DESTINATION: str
ATTR_ORIGIN_NAME: str
ATTR_DESTINATION_NAME: str
attribution: str | None
duration: float
duration_in_traffic: float
distance: float
origin: str
destination: str
origin_name: str | None
destination_name: str | None
@dataclass

View File

@ -40,7 +40,10 @@ from .const import (
ICON_CAR,
ICONS,
)
from .coordinator import HERERoutingDataUpdateCoordinator
from .coordinator import (
HERERoutingDataUpdateCoordinator,
HERETransitDataUpdateCoordinator,
)
SCAN_INTERVAL = timedelta(minutes=5)
@ -107,7 +110,8 @@ class HERETravelTimeSensor(CoordinatorEntity, RestoreSensor):
unique_id_prefix: str,
name: str,
sensor_description: SensorEntityDescription,
coordinator: HERERoutingDataUpdateCoordinator,
coordinator: HERERoutingDataUpdateCoordinator
| HERETransitDataUpdateCoordinator,
) -> None:
"""Initialize the sensor."""
super().__init__(coordinator)
@ -131,7 +135,7 @@ class HERETravelTimeSensor(CoordinatorEntity, RestoreSensor):
await self._async_restore_state()
await super().async_added_to_hass()
async def _update_at_start(_):
async def _update_at_start(_: HomeAssistant) -> None:
await self.async_update()
self.async_on_remove(async_at_started(self.hass, _update_at_start))
@ -149,7 +153,8 @@ class HERETravelTimeSensor(CoordinatorEntity, RestoreSensor):
def attribution(self) -> str | None:
"""Return the attribution."""
if self.coordinator.data is not None:
return self.coordinator.data.get(ATTR_ATTRIBUTION)
if (attribution := self.coordinator.data.get(ATTR_ATTRIBUTION)) is not None:
return str(attribution)
return None

View File

@ -1054,6 +1054,16 @@ disallow_untyped_defs = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.here_travel_time.*]
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.history.*]
check_untyped_defs = true
disallow_incomplete_defs = true