Improve handling of empty iterable in async_add_entities (#141889)

* Improve handling of empty iterable in async_add_entities

We had two checks here because we were doing an empty
iterable check. If its a list we can check it directly
but if its not we need to convert it to a list to know
if its empty.

* tweaks

* tasks never used
This commit is contained in:
J. Nick Koston 2025-03-30 15:22:47 -10:00 committed by GitHub
parent 704d7a037c
commit 018651ff1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -573,9 +573,9 @@ class EntityPlatform:
async def _async_add_and_update_entities( async def _async_add_and_update_entities(
self, self,
coros: list[Coroutine[Any, Any, None]],
entities: list[Entity], entities: list[Entity],
timeout: float, timeout: float,
config_subentry_id: str | None,
) -> None: ) -> None:
"""Add entities for a single platform and update them. """Add entities for a single platform and update them.
@ -585,10 +585,21 @@ class EntityPlatform:
event loop and will finish faster if we run them concurrently. event loop and will finish faster if we run them concurrently.
""" """
results: list[BaseException | None] | None = None results: list[BaseException | None] | None = None
tasks = [create_eager_task(coro, loop=self.hass.loop) for coro in coros] entity_registry = ent_reg.async_get(self.hass)
try: try:
async with self.hass.timeout.async_timeout(timeout, self.domain): async with self.hass.timeout.async_timeout(timeout, self.domain):
results = await asyncio.gather(*tasks, return_exceptions=True) results = await asyncio.gather(
*(
create_eager_task(
self._async_add_entity(
entity, True, entity_registry, config_subentry_id
),
loop=self.hass.loop,
)
for entity in entities
),
return_exceptions=True,
)
except TimeoutError: except TimeoutError:
self.logger.warning( self.logger.warning(
"Timed out adding entities for domain %s with platform %s after %ds", "Timed out adding entities for domain %s with platform %s after %ds",
@ -615,9 +626,9 @@ class EntityPlatform:
async def _async_add_entities( async def _async_add_entities(
self, self,
coros: list[Coroutine[Any, Any, None]],
entities: list[Entity], entities: list[Entity],
timeout: float, timeout: float,
config_subentry_id: str | None,
) -> None: ) -> None:
"""Add entities for a single platform without updating. """Add entities for a single platform without updating.
@ -626,13 +637,15 @@ class EntityPlatform:
to the event loop so we can await the coros directly without to the event loop so we can await the coros directly without
scheduling them as tasks. scheduling them as tasks.
""" """
entity_registry = ent_reg.async_get(self.hass)
try: try:
async with self.hass.timeout.async_timeout(timeout, self.domain): async with self.hass.timeout.async_timeout(timeout, self.domain):
for idx, coro in enumerate(coros): for entity in entities:
try: try:
await coro await self._async_add_entity(
entity, False, entity_registry, config_subentry_id
)
except Exception as ex: except Exception as ex:
entity = entities[idx]
self.logger.exception( self.logger.exception(
"Error adding entity %s for domain %s with platform %s", "Error adding entity %s for domain %s with platform %s",
entity.entity_id, entity.entity_id,
@ -670,33 +683,20 @@ class EntityPlatform:
f"entry {self.config_entry.entry_id if self.config_entry else None}" f"entry {self.config_entry.entry_id if self.config_entry else None}"
) )
entities: list[Entity] = (
new_entities if type(new_entities) is list else list(new_entities)
)
# handle empty list from component/platform # handle empty list from component/platform
if not new_entities: # type: ignore[truthy-iterable] if not entities:
return return
hass = self.hass timeout = max(SLOW_ADD_ENTITY_MAX_WAIT * len(entities), SLOW_ADD_MIN_TIMEOUT)
entity_registry = ent_reg.async_get(hass)
coros: list[Coroutine[Any, Any, None]] = []
entities: list[Entity] = []
for entity in new_entities:
coros.append(
self._async_add_entity(
entity, update_before_add, entity_registry, config_subentry_id
)
)
entities.append(entity)
# No entities for processing
if not coros:
return
timeout = max(SLOW_ADD_ENTITY_MAX_WAIT * len(coros), SLOW_ADD_MIN_TIMEOUT)
if update_before_add: if update_before_add:
add_func = self._async_add_and_update_entities await self._async_add_and_update_entities(
entities, timeout, config_subentry_id
)
else: else:
add_func = self._async_add_entities await self._async_add_entities(entities, timeout, config_subentry_id)
await add_func(coros, entities, timeout)
if ( if (
(self.config_entry and self.config_entry.pref_disable_polling) (self.config_entry and self.config_entry.pref_disable_polling)