diff --git a/homeassistant/components/zeroconf/__init__.py b/homeassistant/components/zeroconf/__init__.py index 932c2dee377..33fe73de617 100644 --- a/homeassistant/components/zeroconf/__init__.py +++ b/homeassistant/components/zeroconf/__init__.py @@ -120,20 +120,38 @@ class ZeroconfServiceInfo(BaseServiceInfo): def __getitem__(self, name: str) -> Any: """ - Allow property access by name for compatibility reason. + Enable method for compatibility reason. Deprecated, and will be removed in version 2022.6. """ if not self._warning_logged: report( f"accessed discovery_info['{name}'] instead of discovery_info.{name}; this will fail in version 2022.6", - exclude_integrations={"zeroconf"}, + exclude_integrations={DOMAIN}, error_if_core=False, level=logging.DEBUG, ) self._warning_logged = True return getattr(self, name) + def get(self, name: str, default: Any = None) -> Any: + """ + Enable method for compatibility reason. + + Deprecated, and will be removed in version 2022.6. + """ + if not self._warning_logged: + report( + f"accessed discovery_info.get('{name}') instead of discovery_info.{name}; this will fail in version 2022.6", + exclude_integrations={DOMAIN}, + error_if_core=False, + level=logging.DEBUG, + ) + self._warning_logged = True + if hasattr(self, name): + return getattr(self, name) + return default + @bind_hass async def async_get_instance(hass: HomeAssistant) -> HaZeroconf: diff --git a/tests/components/zeroconf/test_init.py b/tests/components/zeroconf/test_init.py index d04ddd3dd4b..1bd96a306eb 100644 --- a/tests/components/zeroconf/test_init.py +++ b/tests/components/zeroconf/test_init.py @@ -1030,3 +1030,37 @@ async def test_no_name(hass, mock_async_zeroconf): register_call = mock_async_zeroconf.async_register_service.mock_calls[-1] info = register_call.args[0] assert info.name == "Home._home-assistant._tcp.local." + + +async def test_service_info_compatibility(hass, caplog): + """Test compatibility with old-style dict. + + To be removed in 2022.6 + """ + discovery_info = zeroconf.ZeroconfServiceInfo( + host="mock_host", + port=None, + hostname="mock_hostname", + type="mock_type", + name="mock_name", + properties={}, + ) + + # Ensure first call get logged + assert discovery_info["host"] == "mock_host" + assert discovery_info.get("host") == "mock_host" + assert discovery_info.get("host", "fallback_host") == "mock_host" + assert discovery_info.get("invalid_key", "fallback_host") == "fallback_host" + assert "Detected code that accessed discovery_info['host']" in caplog.text + assert "Detected code that accessed discovery_info.get('host')" not in caplog.text + + # Ensure second call doesn't get logged + caplog.clear() + assert discovery_info["host"] == "mock_host" + assert discovery_info.get("host") == "mock_host" + assert "Detected code that accessed discovery_info['host']" not in caplog.text + assert "Detected code that accessed discovery_info.get('host')" not in caplog.text + + discovery_info._warning_logged = False + assert discovery_info.get("host") == "mock_host" + assert "Detected code that accessed discovery_info.get('host')" in caplog.text