diff --git a/homeassistant/backports/__init__.py b/homeassistant/backports/__init__.py new file mode 100644 index 00000000000..e3dc736417a --- /dev/null +++ b/homeassistant/backports/__init__.py @@ -0,0 +1 @@ +"""Backports from newer Python versions.""" diff --git a/homeassistant/util/enum.py b/homeassistant/backports/enum.py similarity index 96% rename from homeassistant/util/enum.py rename to homeassistant/backports/enum.py index 2ebd1678138..3fa9a582f79 100644 --- a/homeassistant/util/enum.py +++ b/homeassistant/backports/enum.py @@ -1,4 +1,4 @@ -"""Enum related utilities.""" +"""Enum backports from standard lib.""" from __future__ import annotations from enum import Enum diff --git a/homeassistant/components/binary_sensor/__init__.py b/homeassistant/components/binary_sensor/__init__.py index c9301eb7978..0604d5da586 100644 --- a/homeassistant/components/binary_sensor/__init__.py +++ b/homeassistant/components/binary_sensor/__init__.py @@ -8,6 +8,7 @@ from typing import Any, final import voluptuous as vol +from homeassistant.backports.enum import StrEnum from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_OFF, STATE_ON from homeassistant.core import HomeAssistant @@ -18,7 +19,6 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType, StateType -from homeassistant.util.enum import StrEnum _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/button/__init__.py b/homeassistant/components/button/__init__.py index 49249baac61..2e9a8c05163 100644 --- a/homeassistant/components/button/__init__.py +++ b/homeassistant/components/button/__init__.py @@ -8,6 +8,7 @@ from typing import final import voluptuous as vol +from homeassistant.backports.enum import StrEnum from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.config_validation import ( # noqa: F401 @@ -19,7 +20,6 @@ from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import ConfigType from homeassistant.util import dt as dt_util -from homeassistant.util.enum import StrEnum from .const import DOMAIN, SERVICE_PRESS diff --git a/homeassistant/components/cover/__init__.py b/homeassistant/components/cover/__init__.py index 3b8558658eb..e654cf1a0d0 100644 --- a/homeassistant/components/cover/__init__.py +++ b/homeassistant/components/cover/__init__.py @@ -9,6 +9,7 @@ from typing import Any, final import voluptuous as vol +from homeassistant.backports.enum import StrEnum from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( SERVICE_CLOSE_COVER, @@ -34,7 +35,6 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.loader import bind_hass -from homeassistant.util.enum import StrEnum # mypy: allow-untyped-calls, allow-untyped-defs, no-check-untyped-defs diff --git a/homeassistant/components/humidifier/__init__.py b/homeassistant/components/humidifier/__init__.py index e6ec8dc72f2..bf3a45d6e91 100644 --- a/homeassistant/components/humidifier/__init__.py +++ b/homeassistant/components/humidifier/__init__.py @@ -8,6 +8,7 @@ from typing import Any, final import voluptuous as vol +from homeassistant.backports.enum import StrEnum from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( ATTR_MODE, @@ -26,7 +27,6 @@ from homeassistant.helpers.entity import ToggleEntity, ToggleEntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType from homeassistant.loader import bind_hass -from homeassistant.util.enum import StrEnum from .const import ( # noqa: F401 ATTR_AVAILABLE_MODES, diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index 12d0eae29d4..d1d51f525e4 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -22,6 +22,7 @@ import async_timeout import voluptuous as vol from yarl import URL +from homeassistant.backports.enum import StrEnum from homeassistant.components import websocket_api from homeassistant.components.http import KEY_AUTHENTICATED, HomeAssistantView from homeassistant.components.websocket_api.const import ( @@ -63,7 +64,6 @@ from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.network import get_url from homeassistant.loader import bind_hass -from homeassistant.util.enum import StrEnum from .const import ( ATTR_APP_ID, diff --git a/homeassistant/components/number/__init__.py b/homeassistant/components/number/__init__.py index 7e2f9093b80..af88b5c86b5 100644 --- a/homeassistant/components/number/__init__.py +++ b/homeassistant/components/number/__init__.py @@ -8,6 +8,7 @@ from typing import Any, final import voluptuous as vol +from homeassistant.backports.enum import StrEnum from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_MODE from homeassistant.core import HomeAssistant, ServiceCall @@ -18,7 +19,6 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType -from homeassistant.util.enum import StrEnum from .const import ( ATTR_MAX, diff --git a/homeassistant/components/sensor/__init__.py b/homeassistant/components/sensor/__init__.py index 972914a0c68..75db36b91b2 100644 --- a/homeassistant/components/sensor/__init__.py +++ b/homeassistant/components/sensor/__init__.py @@ -12,6 +12,7 @@ from typing import Any, Final, cast, final import ciso8601 import voluptuous as vol +from homeassistant.backports.enum import StrEnum from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( # noqa: F401 DEVICE_CLASS_AQI, @@ -53,7 +54,6 @@ from homeassistant.helpers.config_validation import ( # noqa: F401 from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType, StateType -from homeassistant.util.enum import StrEnum from .const import CONF_STATE_CLASS # noqa: F401 diff --git a/homeassistant/components/switch/__init__.py b/homeassistant/components/switch/__init__.py index fec5a58f414..ac29e99bb73 100644 --- a/homeassistant/components/switch/__init__.py +++ b/homeassistant/components/switch/__init__.py @@ -8,6 +8,7 @@ from typing import Any, final import voluptuous as vol +from homeassistant.backports.enum import StrEnum from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( SERVICE_TOGGLE, @@ -24,7 +25,6 @@ from homeassistant.helpers.entity import ToggleEntity, ToggleEntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType from homeassistant.loader import bind_hass -from homeassistant.util.enum import StrEnum DOMAIN = "switch" SCAN_INTERVAL = timedelta(seconds=30) diff --git a/homeassistant/components/wled/__init__.py b/homeassistant/components/wled/__init__.py index 0518bd736d0..659df1baad9 100644 --- a/homeassistant/components/wled/__init__.py +++ b/homeassistant/components/wled/__init__.py @@ -2,8 +2,8 @@ from __future__ import annotations from homeassistant.config_entries import ConfigEntry +from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity_platform import Platform from .const import DOMAIN from .coordinator import WLEDDataUpdateCoordinator diff --git a/homeassistant/const.py b/homeassistant/const.py index fb8dfc6089a..9da00de9a9a 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -3,6 +3,8 @@ from __future__ import annotations from typing import Final +from homeassistant.backports.enum import StrEnum + MAJOR_VERSION: Final = 2021 MINOR_VERSION: Final = 12 PATCH_VERSION: Final = "0.dev0" @@ -16,6 +18,42 @@ REQUIRED_NEXT_PYTHON_HA_RELEASE: Final = "2022.1" # Format for platform files PLATFORM_FORMAT: Final = "{platform}.{domain}" + +class Platform(StrEnum): + """Available entity platforms.""" + + AIR_QUALITY = "air_quality" + ALARM_CONTROL_PANEL = "alarm_control_panel" + BINARY_SENSOR = "binary_sensor" + BUTTON = "button" + CALENDAR = "calendar" + CAMERA = "camera" + CLIMATE = "climate" + COVER = "cover" + DEVICE_TRACKER = "device_tracker" + FAN = "fan" + GEO_LOCATION = "geo_location" + HUMIDIFIER = "humidifier" + IMAGE_PROCESSING = "image_processing" + LIGHT = "light" + LOCK = "lock" + MAILBOX = "mailbox" + MEDIA_PLAYER = "media_player" + NOTIFY = "notify" + NUMBER = "number" + REMOTE = "remote" + SCENE = "scene" + SELECT = "select" + SENSOR = "sensor" + SIREN = "siren" + STT = "stt" + SWITCH = "switch" + TTS = "tts" + VACUUM = "vacuum" + WATER_HEATER = "water_heater" + WEATHER = "weather" + + # Can be used to specify a catch all when registering state or event listeners. MATCH_ALL: Final = "*" diff --git a/homeassistant/helpers/device_registry.py b/homeassistant/helpers/device_registry.py index 7a78bf69ba7..c8ae7fd148c 100644 --- a/homeassistant/helpers/device_registry.py +++ b/homeassistant/helpers/device_registry.py @@ -8,13 +8,13 @@ from typing import TYPE_CHECKING, Any, NamedTuple, cast import attr +from homeassistant.backports.enum import StrEnum from homeassistant.const import EVENT_HOMEASSISTANT_STARTED from homeassistant.core import Event, HomeAssistant, callback from homeassistant.exceptions import RequiredParameterMissing from homeassistant.helpers import storage from homeassistant.helpers.frame import report from homeassistant.loader import bind_hass -from homeassistant.util.enum import StrEnum import homeassistant.util.uuid as uuid_util from .debounce import Debouncer diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index c303b97eb5f..86c8fa86af5 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -15,6 +15,7 @@ from typing import Any, Final, Literal, TypedDict, final import voluptuous as vol +from homeassistant.backports.enum import StrEnum from homeassistant.config import DATA_CUSTOMIZE from homeassistant.const import ( ATTR_ASSUMED_STATE, @@ -43,7 +44,6 @@ from homeassistant.helpers.event import Event, async_track_entity_registry_updat from homeassistant.helpers.typing import StateType from homeassistant.loader import bind_hass from homeassistant.util import dt as dt_util, ensure_unique_string, slugify -from homeassistant.util.enum import StrEnum _LOGGER = logging.getLogger(__name__) SLOW_UPDATE_WARNING = 10 diff --git a/homeassistant/helpers/entity_platform.py b/homeassistant/helpers/entity_platform.py index 45795a44c42..d8cb8477f11 100644 --- a/homeassistant/helpers/entity_platform.py +++ b/homeassistant/helpers/entity_platform.py @@ -34,7 +34,6 @@ from homeassistant.exceptions import ( ) from homeassistant.setup import async_start_setup from homeassistant.util.async_ import run_callback_threadsafe -from homeassistant.util.enum import StrEnum from . import ( config_validation as cv, @@ -63,41 +62,6 @@ PLATFORM_NOT_READY_BASE_WAIT_TIME = 30 # seconds _LOGGER = getLogger(__name__) -class Platform(StrEnum): - """Available platforms.""" - - AIR_QUALITY = "air_quality" - ALARM_CONTROL_PANEL = "alarm_control_panel" - BINARY_SENSOR = "binary_sensor" - BUTTON = "button" - CALENDAR = "calendar" - CAMERA = "camera" - CLIMATE = "climate" - COVER = "cover" - DEVICE_TRACKER = "device_tracker" - FAN = "fan" - GEO_LOCATION = "geo_location" - HUMIDIFIER = "humidifier" - IMAGE_PROCESSING = "image_processing" - LIGHT = "light" - LOCK = "lock" - MAILBOX = "mailbox" - MEDIA_PLAYER = "media_player" - NOTIFY = "notify" - NUMBER = "number" - REMOTE = "remote" - SCENE = "scene" - SELECT = "select" - SENSOR = "sensor" - SIREN = "siren" - SST = "sst" - SWITCH = "switch" - TTS = "tts" - VACUUM = "vacuum" - WATER_HEATER = "water_heater" - WEATHER = "weather" - - class AddEntitiesCallback(Protocol): """Protocol type for EntityPlatform.add_entities callback.""" diff --git a/homeassistant/helpers/entity_registry.py b/homeassistant/helpers/entity_registry.py index 6614091341f..b79e9af209e 100644 --- a/homeassistant/helpers/entity_registry.py +++ b/homeassistant/helpers/entity_registry.py @@ -17,6 +17,7 @@ from typing import TYPE_CHECKING, Any, cast import attr import voluptuous as vol +from homeassistant.backports.enum import StrEnum from homeassistant.const import ( ATTR_DEVICE_CLASS, ATTR_FRIENDLY_NAME, @@ -42,7 +43,6 @@ from homeassistant.helpers.device_registry import EVENT_DEVICE_REGISTRY_UPDATED from homeassistant.helpers.frame import report from homeassistant.loader import bind_hass from homeassistant.util import slugify, uuid as uuid_util -from homeassistant.util.enum import StrEnum from homeassistant.util.yaml import load_yaml from .typing import UNDEFINED, UndefinedType diff --git a/homeassistant/setup.py b/homeassistant/setup.py index 67740c54254..3e6db28a194 100644 --- a/homeassistant/setup.py +++ b/homeassistant/setup.py @@ -14,6 +14,7 @@ from homeassistant.const import ( EVENT_COMPONENT_LOADED, EVENT_HOMEASSISTANT_START, PLATFORM_FORMAT, + Platform, ) from homeassistant.core import CALLBACK_TYPE from homeassistant.exceptions import HomeAssistantError @@ -26,34 +27,7 @@ _LOGGER = logging.getLogger(__name__) ATTR_COMPONENT = "component" -BASE_PLATFORMS = { - "air_quality", - "alarm_control_panel", - "binary_sensor", - "camera", - "calendar", - "climate", - "cover", - "device_tracker", - "fan", - "humidifier", - "image_processing", - "light", - "lock", - "media_player", - "notify", - "number", - "remote", - "scene", - "select", - "sensor", - "siren", - "switch", - "tts", - "vacuum", - "water_heater", - "weather", -} +BASE_PLATFORMS = {platform.value for platform in Platform} DATA_SETUP_DONE = "setup_done" DATA_SETUP_STARTED = "setup_started" diff --git a/homeassistant/util/dt.py b/homeassistant/util/dt.py index 39f8a63e53f..0c8a1cd9aad 100644 --- a/homeassistant/util/dt.py +++ b/homeassistant/util/dt.py @@ -10,8 +10,6 @@ from typing import Any, cast import ciso8601 -from homeassistant.const import MATCH_ALL - if sys.version_info[:2] >= (3, 9): import zoneinfo else: @@ -215,7 +213,7 @@ def get_age(date: dt.datetime) -> str: def parse_time_expression(parameter: Any, min_value: int, max_value: int) -> list[int]: """Parse the time expression part and return a list of times to match.""" - if parameter is None or parameter == MATCH_ALL: + if parameter is None or parameter == "*": res = list(range(min_value, max_value + 1)) elif isinstance(parameter, str): if parameter.startswith("/"): diff --git a/script/hassfest/dependencies.py b/script/hassfest/dependencies.py index 3f0bd9c1236..c52a926e4e1 100644 --- a/script/hassfest/dependencies.py +++ b/script/hassfest/dependencies.py @@ -4,8 +4,8 @@ from __future__ import annotations import ast from pathlib import Path +from homeassistant.const import Platform from homeassistant.requirements import DISCOVERY_INTEGRATIONS -from homeassistant.setup import BASE_PLATFORMS from .model import Integration @@ -91,12 +91,11 @@ class ImportCollector(ast.NodeVisitor): ALLOWED_USED_COMPONENTS = { + *{platform.value for platform in Platform}, # Internal integrations "alert", "automation", - "button", "conversation", - "button", "device_automation", "frontend", "group", @@ -119,8 +118,6 @@ ALLOWED_USED_COMPONENTS = { "webhook", "websocket_api", "zone", - # Entity integrations with platforms - *BASE_PLATFORMS, # Other "mjpeg", # base class, has no reqs or component to load. "stream", # Stream cannot install on all systems, can be imported without reqs. diff --git a/tests/backports/__init__.py b/tests/backports/__init__.py new file mode 100644 index 00000000000..3f701810a5d --- /dev/null +++ b/tests/backports/__init__.py @@ -0,0 +1 @@ +"""The tests for the backports.""" diff --git a/tests/util/test_enum.py b/tests/backports/test_enum.py similarity index 93% rename from tests/util/test_enum.py rename to tests/backports/test_enum.py index 8fb2091bd11..645db2bd7ca 100644 --- a/tests/util/test_enum.py +++ b/tests/backports/test_enum.py @@ -4,7 +4,7 @@ from enum import auto import pytest -from homeassistant.util.enum import StrEnum +from homeassistant.backports.enum import StrEnum def test_strenum():