diff --git a/homeassistant/core.py b/homeassistant/core.py index 01536f8ffdb..919e0adb758 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -36,7 +36,6 @@ from typing import ( TYPE_CHECKING, Any, Generic, - Literal, NotRequired, ParamSpec, Self, @@ -279,17 +278,24 @@ def async_get_hass() -> HomeAssistant: return _hass.hass +class ReleaseChannel(enum.StrEnum): + BETA = "beta" + DEV = "dev" + NIGHTLY = "nightly" + STABLE = "stable" + + @callback -def get_release_channel() -> Literal["beta", "dev", "nightly", "stable"]: +def get_release_channel() -> ReleaseChannel: """Find release channel based on version number.""" version = __version__ if "dev0" in version: - return "dev" + return ReleaseChannel.DEV if "dev" in version: - return "nightly" + return ReleaseChannel.NIGHTLY if "b" in version: - return "beta" - return "stable" + return ReleaseChannel.BETA + return ReleaseChannel.STABLE @enum.unique diff --git a/homeassistant/helpers/device_registry.py b/homeassistant/helpers/device_registry.py index 3a9d047810b..00d0a0ba62f 100644 --- a/homeassistant/helpers/device_registry.py +++ b/homeassistant/helpers/device_registry.py @@ -13,7 +13,13 @@ import attr from yarl import URL from homeassistant.const import EVENT_HOMEASSISTANT_STARTED, EVENT_HOMEASSISTANT_STOP -from homeassistant.core import Event, HomeAssistant, callback, get_release_channel +from homeassistant.core import ( + Event, + HomeAssistant, + ReleaseChannel, + callback, + get_release_channel, +) from homeassistant.exceptions import HomeAssistantError from homeassistant.loader import async_suggest_report_issue from homeassistant.util.event_type import EventType @@ -608,7 +614,7 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): try: return name.format(**translation_placeholders) except KeyError as err: - if get_release_channel() != "stable": + if get_release_channel() is not ReleaseChannel.STABLE: raise HomeAssistantError("Missing placeholder %s" % err) from err report_issue = async_suggest_report_issue( self.hass, integration_domain=domain @@ -963,12 +969,16 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]): tuple(conn) # type: ignore[misc] for conn in device["connections"] }, - disabled_by=DeviceEntryDisabler(device["disabled_by"]) - if device["disabled_by"] - else None, - entry_type=DeviceEntryType(device["entry_type"]) - if device["entry_type"] - else None, + disabled_by=( + DeviceEntryDisabler(device["disabled_by"]) + if device["disabled_by"] + else None + ), + entry_type=( + DeviceEntryType(device["entry_type"]) + if device["entry_type"] + else None + ), hw_version=device["hw_version"], id=device["id"], identifiers={ diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index 20948a7130a..086def8a8be 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -52,6 +52,7 @@ from homeassistant.core import ( Event, HassJobType, HomeAssistant, + ReleaseChannel, callback, get_hassjob_callable_job_type, get_release_channel, @@ -657,7 +658,7 @@ class Entity( return name.format(**self.translation_placeholders) except KeyError as err: if not self._name_translation_placeholders_reported: - if get_release_channel() != "stable": + if get_release_channel() is not ReleaseChannel.STABLE: raise HomeAssistantError("Missing placeholder %s" % err) from err report_issue = self._suggest_report_issue() _LOGGER.warning( diff --git a/tests/helpers/test_device_registry.py b/tests/helpers/test_device_registry.py index bed3dea4dc1..ee895e3fd3e 100644 --- a/tests/helpers/test_device_registry.py +++ b/tests/helpers/test_device_registry.py @@ -11,7 +11,7 @@ from yarl import URL from homeassistant import config_entries from homeassistant.const import EVENT_HOMEASSISTANT_STARTED -from homeassistant.core import CoreState, HomeAssistant +from homeassistant.core import CoreState, HomeAssistant, ReleaseChannel from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import ( area_registry as ar, @@ -2390,7 +2390,7 @@ async def test_device_name_translation_placeholders( }, }, {"placeholder": "special"}, - "stable", + ReleaseChannel.STABLE, nullcontext(), ( "has translation placeholders '{'placeholder': 'special'}' which do " @@ -2405,7 +2405,7 @@ async def test_device_name_translation_placeholders( }, }, {"placeholder": "special"}, - "beta", + ReleaseChannel.BETA, pytest.raises( HomeAssistantError, match="Missing placeholder '2ndplaceholder'" ), @@ -2419,7 +2419,7 @@ async def test_device_name_translation_placeholders( }, }, None, - "stable", + ReleaseChannel.STABLE, nullcontext(), ( "has translation placeholders '{}' which do " @@ -2434,7 +2434,7 @@ async def test_device_name_translation_placeholders_errors( translation_key: str | None, translations: dict[str, str] | None, placeholders: dict[str, str] | None, - release_channel: str, + release_channel: ReleaseChannel, expectation: AbstractContextManager, expected_error: str, caplog: pytest.LogCaptureFixture, diff --git a/tests/helpers/test_entity.py b/tests/helpers/test_entity.py index 70d917dbc7b..fb2793a75c7 100644 --- a/tests/helpers/test_entity.py +++ b/tests/helpers/test_entity.py @@ -28,6 +28,7 @@ from homeassistant.core import ( HassJobType, HomeAssistant, HomeAssistantError, + ReleaseChannel, callback, ) from homeassistant.helpers import device_registry as dr, entity, entity_registry as er @@ -1249,7 +1250,7 @@ async def test_entity_name_translation_placeholders( }, }, {"placeholder": "special"}, - "stable", + ReleaseChannel.STABLE, ( "has translation placeholders '{'placeholder': 'special'}' which do " "not match the name '{placeholder} English ent {2ndplaceholder}'" @@ -1263,7 +1264,7 @@ async def test_entity_name_translation_placeholders( }, }, {"placeholder": "special"}, - "beta", + ReleaseChannel.BETA, "HomeAssistantError: Missing placeholder '2ndplaceholder'", ), ( @@ -1274,7 +1275,7 @@ async def test_entity_name_translation_placeholders( }, }, None, - "stable", + ReleaseChannel.STABLE, ( "has translation placeholders '{}' which do " "not match the name '{placeholder} English ent'" @@ -1287,7 +1288,7 @@ async def test_entity_name_translation_placeholder_errors( translation_key: str | None, translations: dict[str, str] | None, placeholders: dict[str, str] | None, - release_channel: str, + release_channel: ReleaseChannel, expected_error: str, caplog: pytest.LogCaptureFixture, ) -> None: diff --git a/tests/test_core.py b/tests/test_core.py index 5d687d89833..8f0d7f53277 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -42,6 +42,7 @@ from homeassistant.core import ( CoreState, HassJob, HomeAssistant, + ReleaseChannel, ServiceCall, ServiceResponse, State, @@ -3060,13 +3061,15 @@ async def test_validate_state(hass: HomeAssistant) -> None: @pytest.mark.parametrize( ("version", "release_channel"), [ - ("0.115.0.dev20200815", "nightly"), - ("0.115.0", "stable"), - ("0.115.0b4", "beta"), - ("0.115.0dev0", "dev"), + ("0.115.0.dev20200815", ReleaseChannel.NIGHTLY), + ("0.115.0", ReleaseChannel.STABLE), + ("0.115.0b4", ReleaseChannel.BETA), + ("0.115.0dev0", ReleaseChannel.DEV), ], ) -async def test_get_release_channel(version: str, release_channel: str) -> None: +async def test_get_release_channel( + version: str, release_channel: ReleaseChannel +) -> None: """Test if release channel detection works from Home Assistant version number.""" with patch("homeassistant.core.__version__", f"{version}"): assert get_release_channel() == release_channel