From 6ac05784a63f7490f875959139ef903034bc45b0 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Mon, 11 Jul 2022 17:33:20 +0200 Subject: [PATCH] Remove icloud from mypy ignore list (#75007) --- homeassistant/components/icloud/__init__.py | 16 ++++--- homeassistant/components/icloud/account.py | 45 +++++++++---------- .../components/icloud/device_tracker.py | 6 +-- homeassistant/components/icloud/sensor.py | 4 +- mypy.ini | 12 ----- script/hassfest/mypy_config.py | 4 -- 6 files changed, 37 insertions(+), 50 deletions(-) diff --git a/homeassistant/components/icloud/__init__.py b/homeassistant/components/icloud/__init__.py index 06028ebce6c..63802804f4d 100644 --- a/homeassistant/components/icloud/__init__.py +++ b/homeassistant/components/icloud/__init__.py @@ -1,4 +1,8 @@ """The iCloud component.""" +from __future__ import annotations + +from typing import Any + import voluptuous as vol from homeassistant.config_entries import ConfigEntry @@ -82,7 +86,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: if entry.unique_id is None: hass.config_entries.async_update_entry(entry, unique_id=username) - icloud_dir = Store(hass, STORAGE_VERSION, STORAGE_KEY) + icloud_dir = Store[Any](hass, STORAGE_VERSION, STORAGE_KEY) account = IcloudAccount( hass, @@ -103,7 +107,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: def play_sound(service: ServiceCall) -> None: """Play sound on the device.""" account = service.data[ATTR_ACCOUNT] - device_name = service.data.get(ATTR_DEVICE_NAME) + device_name: str = service.data[ATTR_DEVICE_NAME] device_name = slugify(device_name.replace(" ", "", 99)) for device in _get_account(account).get_devices_with_name(device_name): @@ -112,7 +116,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: def display_message(service: ServiceCall) -> None: """Display a message on the device.""" account = service.data[ATTR_ACCOUNT] - device_name = service.data.get(ATTR_DEVICE_NAME) + device_name: str = service.data[ATTR_DEVICE_NAME] device_name = slugify(device_name.replace(" ", "", 99)) message = service.data.get(ATTR_LOST_DEVICE_MESSAGE) sound = service.data.get(ATTR_LOST_DEVICE_SOUND, False) @@ -123,7 +127,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: def lost_device(service: ServiceCall) -> None: """Make the device in lost state.""" account = service.data[ATTR_ACCOUNT] - device_name = service.data.get(ATTR_DEVICE_NAME) + device_name: str = service.data[ATTR_DEVICE_NAME] device_name = slugify(device_name.replace(" ", "", 99)) number = service.data.get(ATTR_LOST_DEVICE_NUMBER) message = service.data.get(ATTR_LOST_DEVICE_MESSAGE) @@ -139,11 +143,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: else: _get_account(account).keep_alive() - def _get_account(account_identifier: str) -> any: + def _get_account(account_identifier: str) -> IcloudAccount: if account_identifier is None: return None - icloud_account = hass.data[DOMAIN].get(account_identifier) + icloud_account: IcloudAccount | None = hass.data[DOMAIN].get(account_identifier) if icloud_account is None: for account in hass.data[DOMAIN].values(): if account.username == account_identifier: diff --git a/homeassistant/components/icloud/account.py b/homeassistant/components/icloud/account.py index 95b90791165..4dc3c07aba7 100644 --- a/homeassistant/components/icloud/account.py +++ b/homeassistant/components/icloud/account.py @@ -91,21 +91,19 @@ class IcloudAccount: self._username = username self._password = password self._with_family = with_family - self._fetch_interval = max_interval + self._fetch_interval: float = max_interval self._max_interval = max_interval self._gps_accuracy_threshold = gps_accuracy_threshold self._icloud_dir = icloud_dir self.api: PyiCloudService | None = None - self._owner_fullname = None - self._family_members_fullname = {} - self._devices = {} + self._owner_fullname: str | None = None + self._family_members_fullname: dict[str, str] = {} + self._devices: dict[str, IcloudDevice] = {} self._retried_fetch = False self._config_entry = config_entry - self.listeners = [] - def setup(self) -> None: """Set up an iCloud account.""" try: @@ -271,6 +269,8 @@ class IcloudAccount: distances = [] for zone_state in zones: + if zone_state is None: + continue zone_state_lat = zone_state.attributes[DEVICE_LOCATION_LATITUDE] zone_state_long = zone_state.attributes[DEVICE_LOCATION_LONGITUDE] zone_distance = distance( @@ -279,7 +279,8 @@ class IcloudAccount: zone_state_lat, zone_state_long, ) - distances.append(round(zone_distance / 1000, 1)) + if zone_distance is not None: + distances.append(round(zone_distance / 1000, 1)) # Max interval if no zone if not distances: @@ -288,7 +289,7 @@ class IcloudAccount: # Calculate out how long it would take for the device to drive # to the nearest zone at 120 km/h: - interval = round(mindistance / 2, 0) + interval = round(mindistance / 2) # Never poll more than once per minute interval = max(interval, 1) @@ -324,7 +325,7 @@ class IcloudAccount: self.api.authenticate() self.update_devices() - def get_devices_with_name(self, name: str) -> [any]: + def get_devices_with_name(self, name: str) -> list[Any]: """Get devices by name.""" result = [] name_slug = slugify(name.replace(" ", "", 99)) @@ -341,7 +342,7 @@ class IcloudAccount: return self._username @property - def owner_fullname(self) -> str: + def owner_fullname(self) -> str | None: """Return the account owner fullname.""" return self._owner_fullname @@ -351,7 +352,7 @@ class IcloudAccount: return self._family_members_fullname @property - def fetch_interval(self) -> int: + def fetch_interval(self) -> float: """Return the account fetch interval.""" return self._fetch_interval @@ -386,14 +387,7 @@ class IcloudDevice: self._device_class = self._status[DEVICE_CLASS] self._device_model = self._status[DEVICE_DISPLAY_NAME] - if self._status[DEVICE_PERSON_ID]: - owner_fullname = account.family_members_fullname[ - self._status[DEVICE_PERSON_ID] - ] - else: - owner_fullname = account.owner_fullname - - self._battery_level = None + self._battery_level: int | None = None self._battery_status = None self._location = None @@ -402,8 +396,13 @@ class IcloudDevice: ATTR_ACCOUNT_FETCH_INTERVAL: self._account.fetch_interval, ATTR_DEVICE_NAME: self._device_model, ATTR_DEVICE_STATUS: None, - ATTR_OWNER_NAME: owner_fullname, } + if self._status[DEVICE_PERSON_ID]: + self._attrs[ATTR_OWNER_NAME] = account.family_members_fullname[ + self._status[DEVICE_PERSON_ID] + ] + elif account.owner_fullname is not None: + self._attrs[ATTR_OWNER_NAME] = account.owner_fullname def update(self, status) -> None: """Update the iCloud device.""" @@ -487,17 +486,17 @@ class IcloudDevice: return self._device_model @property - def battery_level(self) -> int: + def battery_level(self) -> int | None: """Return the Apple device battery level.""" return self._battery_level @property - def battery_status(self) -> str: + def battery_status(self) -> str | None: """Return the Apple device battery status.""" return self._battery_status @property - def location(self) -> dict[str, Any]: + def location(self) -> dict[str, Any] | None: """Return the Apple device location.""" return self._location diff --git a/homeassistant/components/icloud/device_tracker.py b/homeassistant/components/icloud/device_tracker.py index c9d251b06c7..6886d500a84 100644 --- a/homeassistant/components/icloud/device_tracker.py +++ b/homeassistant/components/icloud/device_tracker.py @@ -36,7 +36,7 @@ async def async_setup_entry( ) -> None: """Set up device tracker for iCloud component.""" account = hass.data[DOMAIN][entry.unique_id] - tracked = set() + tracked = set[str]() @callback def update_account(): @@ -51,7 +51,7 @@ async def async_setup_entry( @callback -def add_entities(account, async_add_entities, tracked): +def add_entities(account: IcloudAccount, async_add_entities, tracked): """Add new tracker entities from the account.""" new_tracked = [] @@ -101,7 +101,7 @@ class IcloudTrackerEntity(TrackerEntity): return self._device.location[DEVICE_LOCATION_LONGITUDE] @property - def battery_level(self) -> int: + def battery_level(self) -> int | None: """Return the battery level of the device.""" return self._device.battery_level diff --git a/homeassistant/components/icloud/sensor.py b/homeassistant/components/icloud/sensor.py index 38ea3af62b6..6e415aa3350 100644 --- a/homeassistant/components/icloud/sensor.py +++ b/homeassistant/components/icloud/sensor.py @@ -21,7 +21,7 @@ async def async_setup_entry( ) -> None: """Set up device tracker for iCloud component.""" account = hass.data[DOMAIN][entry.unique_id] - tracked = set() + tracked = set[str]() @callback def update_account(): @@ -74,7 +74,7 @@ class IcloudDeviceBatterySensor(SensorEntity): return f"{self._device.name} battery state" @property - def native_value(self) -> int: + def native_value(self) -> int | None: """Battery state percentage.""" return self._device.battery_level diff --git a/mypy.ini b/mypy.ini index 8335af1ed77..65b51e9d1c9 100644 --- a/mypy.ini +++ b/mypy.ini @@ -2672,18 +2672,6 @@ ignore_errors = true [mypy-homeassistant.components.evohome.climate] ignore_errors = true -[mypy-homeassistant.components.icloud] -ignore_errors = true - -[mypy-homeassistant.components.icloud.account] -ignore_errors = true - -[mypy-homeassistant.components.icloud.device_tracker] -ignore_errors = true - -[mypy-homeassistant.components.icloud.sensor] -ignore_errors = true - [mypy-homeassistant.components.lovelace] ignore_errors = true diff --git a/script/hassfest/mypy_config.py b/script/hassfest/mypy_config.py index b492a70c8a9..17ef8edc529 100644 --- a/script/hassfest/mypy_config.py +++ b/script/hassfest/mypy_config.py @@ -25,10 +25,6 @@ IGNORED_MODULES: Final[list[str]] = [ "homeassistant.components.conversation.default_agent", "homeassistant.components.evohome", "homeassistant.components.evohome.climate", - "homeassistant.components.icloud", - "homeassistant.components.icloud.account", - "homeassistant.components.icloud.device_tracker", - "homeassistant.components.icloud.sensor", "homeassistant.components.lovelace", "homeassistant.components.lovelace.dashboard", "homeassistant.components.lovelace.resources",