diff --git a/homeassistant/components/obihai/config_flow.py b/homeassistant/components/obihai/config_flow.py index 1a7d29fadba525ad4a4b871aab07577c6c3a9014..6216fe0b9730367435204ee9e377808f3de98e72 100644 --- a/homeassistant/components/obihai/config_flow.py +++ b/homeassistant/components/obihai/config_flow.py @@ -66,7 +66,9 @@ class ObihaiFlowHandler(ConfigFlow, domain=DOMAIN): if user_input is not None: try: - ip = gethostbyname(user_input[CONF_HOST]) + ip = await self.hass.async_add_executor_job( + gethostbyname, user_input[CONF_HOST] + ) except gaierror: errors["base"] = "cannot_connect" @@ -139,7 +141,7 @@ class ObihaiFlowHandler(ConfigFlow, domain=DOMAIN): """Handle a flow initialized by importing a config.""" try: - _ = gethostbyname(config[CONF_HOST]) + _ = await self.hass.async_add_executor_job(gethostbyname, config[CONF_HOST]) except gaierror: return self.async_abort(reason="cannot_connect") diff --git a/homeassistant/components/sonos/__init__.py b/homeassistant/components/sonos/__init__.py index 4b68030f843c9b061ec34c62b2a3c10b06e958db..c17e4b00829816496df1ec112c6f8a5158fd3eb0 100644 --- a/homeassistant/components/sonos/__init__.py +++ b/homeassistant/components/sonos/__init__.py @@ -48,6 +48,7 @@ from .const import ( ) from .exception import SonosUpdateError from .favorites import SonosFavorites +from .helpers import sync_get_visible_zones from .speaker import SonosSpeaker _LOGGER = logging.getLogger(__name__) @@ -338,19 +339,12 @@ class SonosDiscoveryManager: self, now: datetime.datetime | None = None ) -> None: """Add and maintain Sonos devices from a manual configuration.""" - - def get_sync_attributes(soco: SoCo) -> set[SoCo]: - """Ensure I/O attributes are cached and return visible zones.""" - _ = soco.household_id - _ = soco.uid - return soco.visible_zones - for host in self.hosts: - ip_addr = socket.gethostbyname(host) + ip_addr = await self.hass.async_add_executor_job(socket.gethostbyname, host) soco = SoCo(ip_addr) try: visible_zones = await self.hass.async_add_executor_job( - get_sync_attributes, + sync_get_visible_zones, soco, ) except (OSError, SoCoException, Timeout) as ex: @@ -382,7 +376,7 @@ class SonosDiscoveryManager: break for host in self.hosts.copy(): - ip_addr = socket.gethostbyname(host) + ip_addr = await self.hass.async_add_executor_job(socket.gethostbyname, host) if self.is_device_invisible(ip_addr): _LOGGER.debug("Discarding %s from manual hosts", ip_addr) self.hosts.discard(ip_addr) diff --git a/homeassistant/components/sonos/helpers.py b/homeassistant/components/sonos/helpers.py index 5f44b9bae6f698a4c6223e76d3e68c96a243de92..1005b6c7d6aa97726bfee77c64e7bc48b29e938c 100644 --- a/homeassistant/components/sonos/helpers.py +++ b/homeassistant/components/sonos/helpers.py @@ -117,3 +117,10 @@ def hostname_to_uid(hostname: str) -> str: else: raise ValueError(f"{hostname} is not a sonos device.") return f"{UID_PREFIX}{baseuid}{UID_POSTFIX}" + + +def sync_get_visible_zones(soco: SoCo) -> set[SoCo]: + """Ensure I/O attributes are cached and return visible zones.""" + _ = soco.household_id + _ = soco.uid + return soco.visible_zones diff --git a/tests/components/sonos/test_init.py b/tests/components/sonos/test_init.py index 6cc79e1b2f0fe8b863688c5e68c5d7eebf739d84..596946e9f8b3ac5a834a399d25486562f449eb8f 100644 --- a/tests/components/sonos/test_init.py +++ b/tests/components/sonos/test_init.py @@ -1,6 +1,6 @@ """Tests for the Sonos config flow.""" import logging -from unittest.mock import AsyncMock, patch +from unittest.mock import patch import pytest @@ -86,16 +86,16 @@ async def test_async_poll_manual_hosts_warnings( manager, "_async_handle_discovery_message" ), patch("homeassistant.components.sonos.async_call_later"), patch( "homeassistant.components.sonos.async_dispatcher_send" - ), patch.object( - hass, "async_add_executor_job", new=AsyncMock() - ) as mock_async_add_executor_job: - mock_async_add_executor_job.side_effect = [ + ), patch( + "homeassistant.components.sonos.sync_get_visible_zones", + side_effect=[ OSError(), OSError(), [], [], OSError(), - ] + ], + ): # First call fails, it should be logged as a WARNING message caplog.clear() await manager.async_poll_manual_hosts()