From 0cb08f951665503d4114b4efba871c596a8d29e5 Mon Sep 17 00:00:00 2001 From: Ruslan Sayfutdinov Date: Wed, 12 May 2021 15:28:44 +0100 Subject: [PATCH] Add missing type hints in entity_platform (#50453) --- homeassistant/helpers/entity_component.py | 4 +- homeassistant/helpers/entity_platform.py | 53 +++++++++++++++-------- homeassistant/helpers/entity_registry.py | 8 ++-- homeassistant/helpers/reload.py | 2 +- 4 files changed, 40 insertions(+), 27 deletions(-) diff --git a/homeassistant/helpers/entity_component.py b/homeassistant/helpers/entity_component.py index 7ac221ea06e..f1623889946 100644 --- a/homeassistant/helpers/entity_component.py +++ b/homeassistant/helpers/entity_component.py @@ -246,9 +246,7 @@ class EntityComponent: platform_type, platform, scan_interval, entity_namespace ) - await self._platforms[key].async_setup( # type: ignore - platform_config, discovery_info - ) + await self._platforms[key].async_setup(platform_config, discovery_info) async def _async_reset(self) -> None: """Remove entities and reset the entity component to initial values. diff --git a/homeassistant/helpers/entity_platform.py b/homeassistant/helpers/entity_platform.py index 6350467c05b..3331c71dd32 100644 --- a/homeassistant/helpers/entity_platform.py +++ b/homeassistant/helpers/entity_platform.py @@ -33,17 +33,19 @@ from homeassistant.exceptions import ( PlatformNotReady, RequiredParameterMissing, ) -from homeassistant.helpers import ( +from homeassistant.setup import async_start_setup +from homeassistant.util.async_ import run_callback_threadsafe + +from . import ( config_validation as cv, device_registry as dev_reg, entity_registry as ent_reg, service, ) -from homeassistant.setup import async_start_setup -from homeassistant.util.async_ import run_callback_threadsafe - -from .entity_registry import DISABLED_INTEGRATION +from .device_registry import DeviceRegistry +from .entity_registry import DISABLED_INTEGRATION, EntityRegistry from .event import async_call_later, async_track_time_interval +from .typing import ConfigType, DiscoveryInfoType if TYPE_CHECKING: from .entity import Entity @@ -148,7 +150,11 @@ class EntityPlatform: return self.parallel_updates - async def async_setup(self, platform_config, discovery_info=None): # type: ignore[no-untyped-def] + async def async_setup( + self, + platform_config: ConfigType, + discovery_info: DiscoveryInfoType | None = None, + ) -> None: """Set up the platform from a config file.""" platform = self.platform hass = self.hass @@ -206,9 +212,9 @@ class EntityPlatform: platform = self.platform @callback - def async_create_setup_task(): # type: ignore[no-untyped-def] + def async_create_setup_task() -> Coroutine: """Get task to set up platform.""" - return platform.async_setup_entry( # type: ignore + return platform.async_setup_entry( # type: ignore[no-any-return,union-attr] self.hass, config_entry, self._async_schedule_add_entities ) @@ -273,7 +279,7 @@ class EntityPlatform: wait_time, ) - async def setup_again(*_): # type: ignore[no-untyped-def] + async def setup_again(*_args: Any) -> None: """Run setup again.""" self._async_cancel_retry_setup = None await self._async_setup_platform(async_create_setup_task, tries) @@ -360,7 +366,7 @@ class EntityPlatform: device_registry = dev_reg.async_get(hass) entity_registry = ent_reg.async_get(hass) tasks = [ - self._async_add_entity( # type: ignore + self._async_add_entity( entity, update_before_add, entity_registry, device_registry ) for entity in new_entities @@ -400,9 +406,13 @@ class EntityPlatform: self.scan_interval, ) - async def _async_add_entity( # type: ignore[no-untyped-def] # noqa: C901 - self, entity, update_before_add, entity_registry, device_registry - ): + async def _async_add_entity( # noqa: C901 + self, + entity: Entity, + update_before_add: bool, + entity_registry: EntityRegistry, + device_registry: DeviceRegistry, + ) -> None: """Add an entity to the platform.""" if entity is None: raise ValueError("Entity cannot be None") @@ -424,6 +434,7 @@ class EntityPlatform: requested_entity_id = None suggested_object_id: str | None = None + generate_new_entity_id = False # Get entity_id from unique ID registration if entity.unique_id is not None: @@ -431,7 +442,7 @@ class EntityPlatform: requested_entity_id = entity.entity_id suggested_object_id = split_entity_id(entity.entity_id)[1] else: - suggested_object_id = entity.name + suggested_object_id = entity.name # type: ignore[unreachable] if self.entity_namespace is not None: suggested_object_id = f"{self.entity_namespace} {suggested_object_id}" @@ -461,10 +472,10 @@ class EntityPlatform: "suggested_area", ): if key in device_info: - processed_dev_info[key] = device_info[key] + processed_dev_info[key] = device_info[key] # type: ignore[misc] try: - device = device_registry.async_get_or_create(**processed_dev_info) + device = device_registry.async_get_or_create(**processed_dev_info) # type: ignore[arg-type] device_id = device.id except RequiredParameterMissing: pass @@ -510,10 +521,10 @@ class EntityPlatform: ): # If entity already registered, convert entity id to suggestion suggested_object_id = split_entity_id(entity.entity_id)[1] - entity.entity_id = None + generate_new_entity_id = True # Generate entity ID - if entity.entity_id is None: + if entity.entity_id is None or generate_new_entity_id: suggested_object_id = ( suggested_object_id or entity.name or DEVICE_DEFAULT_NAME ) @@ -565,7 +576,11 @@ class EntityPlatform: # has a chance to finish. self.hass.states.async_reserve(entity.entity_id) - entity.async_on_remove(lambda: self.entities.pop(entity_id)) + def remove_entity_cb() -> None: + """Remove entity from entities list.""" + self.entities.pop(entity_id) + + entity.async_on_remove(remove_entity_cb) await entity.add_to_platform_finish() diff --git a/homeassistant/helpers/entity_registry.py b/homeassistant/helpers/entity_registry.py index 936464dc423..5d3ede31ee6 100644 --- a/homeassistant/helpers/entity_registry.py +++ b/homeassistant/helpers/entity_registry.py @@ -10,7 +10,7 @@ timer. from __future__ import annotations from collections import OrderedDict -from collections.abc import Iterable +from collections.abc import Iterable, Mapping import logging from typing import TYPE_CHECKING, Any, Callable, cast @@ -96,7 +96,7 @@ class RegistryEntry: ) ), ) - capabilities: dict[str, Any] | None = attr.ib(default=None) + capabilities: Mapping[str, Any] | None = attr.ib(default=None) supported_features: int = attr.ib(default=0) device_class: str | None = attr.ib(default=None) unit_of_measurement: str | None = attr.ib(default=None) @@ -232,7 +232,7 @@ class EntityRegistry: config_entry: ConfigEntry | None = None, device_id: str | None = None, area_id: str | None = None, - capabilities: dict[str, Any] | None = None, + capabilities: Mapping[str, Any] | None = None, supported_features: int | None = None, device_class: str | None = None, unit_of_measurement: str | None = None, @@ -392,7 +392,7 @@ class EntityRegistry: area_id: str | None | UndefinedType = UNDEFINED, new_unique_id: str | UndefinedType = UNDEFINED, disabled_by: str | None | UndefinedType = UNDEFINED, - capabilities: dict[str, Any] | None | UndefinedType = UNDEFINED, + capabilities: Mapping[str, Any] | None | UndefinedType = UNDEFINED, supported_features: int | UndefinedType = UNDEFINED, device_class: str | None | UndefinedType = UNDEFINED, unit_of_measurement: str | None | UndefinedType = UNDEFINED, diff --git a/homeassistant/helpers/reload.py b/homeassistant/helpers/reload.py index 01350b579c4..da6c6935b35 100644 --- a/homeassistant/helpers/reload.py +++ b/homeassistant/helpers/reload.py @@ -124,7 +124,7 @@ async def _async_reconfig_platform( ) -> None: """Reconfigure an already loaded platform.""" await platform.async_reset() - tasks = [platform.async_setup(p_config) for p_config in platform_configs] # type: ignore + tasks = [platform.async_setup(p_config) for p_config in platform_configs] await asyncio.gather(*tasks)