From 0cd668ec7708209a51027bdd47b7d3eb0604085b Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 5 Feb 2026 11:00:43 +0100 Subject: [PATCH] Fix typeguard errors by explicitly converting IP addresses to strings (#6531) * Fix environment variable type errors by converting IP addresses to strings Environment variables must be strings, but IPv4Address and IPv4Network objects were being passed directly to container environment dictionaries, causing typeguard validation errors. Changes: - Convert IPv4Address objects to strings in homeassistant.py for SUPERVISOR and HASSIO environment variables - Convert IPv4Network object to string in observer.py for NETWORK_MASK environment variable - Update tests to expect string values instead of IP objects in environment dictionaries - Remove unused ip_network import from test_observer.py Co-Authored-By: Claude Sonnet 4.5 * Use explicit string conversion for extra_hosts IP addresses Use the !s format specifier in the f-string to explicitly convert IPv4Address objects to strings when building the ExtraHosts list. While f-strings implicitly convert objects to strings, using !s makes the conversion explicit and consistent with the environment variable fixes in the previous commit. Co-Authored-By: Claude Sonnet 4.5 --------- Co-authored-by: Claude Sonnet 4.5 --- supervisor/docker/homeassistant.py | 4 ++-- supervisor/docker/manager.py | 2 +- supervisor/docker/observer.py | 2 +- tests/docker/test_homeassistant.py | 8 ++++---- tests/docker/test_observer.py | 6 ++---- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/supervisor/docker/homeassistant.py b/supervisor/docker/homeassistant.py index 807457a27..c82af5a7b 100644 --- a/supervisor/docker/homeassistant.py +++ b/supervisor/docker/homeassistant.py @@ -172,8 +172,8 @@ class DockerHomeAssistant(DockerInterface): async def run(self, *, restore_job_id: str | None = None) -> None: """Run Docker image.""" environment = { - "SUPERVISOR": self.sys_docker.network.supervisor, - "HASSIO": self.sys_docker.network.supervisor, + "SUPERVISOR": str(self.sys_docker.network.supervisor), + "HASSIO": str(self.sys_docker.network.supervisor), ENV_TIME: self.sys_timezone, ENV_TOKEN: self.sys_homeassistant.supervisor_token, ENV_TOKEN_OLD: self.sys_homeassistant.supervisor_token, diff --git a/supervisor/docker/manager.py b/supervisor/docker/manager.py index a887fa263..b3c73da47 100644 --- a/supervisor/docker/manager.py +++ b/supervisor/docker/manager.py @@ -398,7 +398,7 @@ class DockerAPI(CoreSysAttributes): if restart_policy: host_config["RestartPolicy"] = restart_policy if extra_hosts: - host_config["ExtraHosts"] = [f"{k}:{v}" for k, v in extra_hosts.items()] + host_config["ExtraHosts"] = [f"{k}:{v!s}" for k, v in extra_hosts.items()] if mounts: host_config["Mounts"] = [mount.to_dict() for mount in mounts] if oom_score_adj is not None: diff --git a/supervisor/docker/observer.py b/supervisor/docker/observer.py index 8f6344306..93a6b34b6 100644 --- a/supervisor/docker/observer.py +++ b/supervisor/docker/observer.py @@ -48,7 +48,7 @@ class DockerObserver(DockerInterface, CoreSysAttributes): environment={ ENV_TIME: self.sys_timezone, ENV_TOKEN: self.sys_plugins.observer.supervisor_token, - ENV_NETWORK_MASK: DOCKER_IPV4_NETWORK_MASK, + ENV_NETWORK_MASK: str(DOCKER_IPV4_NETWORK_MASK), }, mounts=[MOUNT_DOCKER], ports={"80/tcp": OBSERVER_PORT}, diff --git a/tests/docker/test_homeassistant.py b/tests/docker/test_homeassistant.py index 14b0f9642..c8a3e64d7 100644 --- a/tests/docker/test_homeassistant.py +++ b/tests/docker/test_homeassistant.py @@ -46,8 +46,8 @@ async def test_homeassistant_start(coresys: CoreSys, container: DockerContainer) "observer": IPv4Address("172.30.32.6"), } assert run.call_args.kwargs["environment"] == { - "SUPERVISOR": IPv4Address("172.30.32.2"), - "HASSIO": IPv4Address("172.30.32.2"), + "SUPERVISOR": "172.30.32.2", + "HASSIO": "172.30.32.2", "TZ": ANY, "SUPERVISOR_TOKEN": ANY, "HASSIO_TOKEN": ANY, @@ -166,8 +166,8 @@ async def test_landingpage_start(coresys: CoreSys, container: DockerContainer): "observer": IPv4Address("172.30.32.6"), } assert run.call_args.kwargs["environment"] == { - "SUPERVISOR": IPv4Address("172.30.32.2"), - "HASSIO": IPv4Address("172.30.32.2"), + "SUPERVISOR": "172.30.32.2", + "HASSIO": "172.30.32.2", "TZ": ANY, "SUPERVISOR_TOKEN": ANY, "HASSIO_TOKEN": ANY, diff --git a/tests/docker/test_observer.py b/tests/docker/test_observer.py index 2abf23770..d8752b009 100644 --- a/tests/docker/test_observer.py +++ b/tests/docker/test_observer.py @@ -1,6 +1,6 @@ """Test Observer plugin container.""" -from ipaddress import IPv4Address, ip_network +from ipaddress import IPv4Address from unittest.mock import patch from aiodocker.containers import DockerContainer @@ -26,9 +26,7 @@ async def test_start(coresys: CoreSys, container: DockerContainer): "supervisor": IPv4Address("172.30.32.2") } assert run.call_args.kwargs["oom_score_adj"] == -300 - assert run.call_args.kwargs["environment"]["NETWORK_MASK"] == ip_network( - "172.30.32.0/23" - ) + assert run.call_args.kwargs["environment"]["NETWORK_MASK"] == "172.30.32.0/23" assert run.call_args.kwargs["ports"] == {"80/tcp": 4357} assert run.call_args.kwargs["mounts"] == [ DockerMount(