mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Add enum util (#87082)
* Add enum helper * docstring * Move to util * Add use case
This commit is contained in:
parent
8efd01b2e8
commit
1225c5e97d
@ -3,7 +3,6 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
from contextlib import suppress
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import date, datetime, timedelta, timezone
|
from datetime import date, datetime, timedelta, timezone
|
||||||
from decimal import Decimal, InvalidOperation as DecimalInvalidOperation
|
from decimal import Decimal, InvalidOperation as DecimalInvalidOperation
|
||||||
@ -59,6 +58,7 @@ from homeassistant.helpers.entity_platform import EntityPlatform
|
|||||||
from homeassistant.helpers.restore_state import ExtraStoredData, RestoreEntity
|
from homeassistant.helpers.restore_state import ExtraStoredData, RestoreEntity
|
||||||
from homeassistant.helpers.typing import UNDEFINED, ConfigType, StateType, UndefinedType
|
from homeassistant.helpers.typing import UNDEFINED, ConfigType, StateType, UndefinedType
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
|
from homeassistant.util.enum import try_parse_enum
|
||||||
|
|
||||||
from .const import ( # noqa: F401
|
from .const import ( # noqa: F401
|
||||||
ATTR_LAST_RESET,
|
ATTR_LAST_RESET,
|
||||||
@ -464,11 +464,9 @@ class SensorEntity(Entity):
|
|||||||
native_unit_of_measurement = self.native_unit_of_measurement
|
native_unit_of_measurement = self.native_unit_of_measurement
|
||||||
unit_of_measurement = self.unit_of_measurement
|
unit_of_measurement = self.unit_of_measurement
|
||||||
value = self.native_value
|
value = self.native_value
|
||||||
device_class: SensorDeviceClass | None = None
|
# For the sake of validation, we can ignore custom device classes
|
||||||
with suppress(ValueError):
|
# (customization and legacy style translations)
|
||||||
# For the sake of validation, we can ignore custom device classes
|
device_class = try_parse_enum(SensorDeviceClass, self.device_class)
|
||||||
# (customization and legacy style translations)
|
|
||||||
device_class = SensorDeviceClass(str(self.device_class))
|
|
||||||
state_class = self.state_class
|
state_class = self.state_class
|
||||||
|
|
||||||
# Sensors with device classes indicating a non-numeric value
|
# Sensors with device classes indicating a non-numeric value
|
||||||
|
16
homeassistant/util/enum.py
Normal file
16
homeassistant/util/enum.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
"""Helpers for working with enums."""
|
||||||
|
import contextlib
|
||||||
|
from enum import Enum
|
||||||
|
from typing import Any, TypeVar
|
||||||
|
|
||||||
|
_EnumT = TypeVar("_EnumT", bound=Enum)
|
||||||
|
|
||||||
|
|
||||||
|
def try_parse_enum(cls: type[_EnumT], value: Any) -> _EnumT | None:
|
||||||
|
"""Try to parse the value into an Enum.
|
||||||
|
|
||||||
|
Return None if parsing fails.
|
||||||
|
"""
|
||||||
|
with contextlib.suppress(ValueError):
|
||||||
|
return cls(value)
|
||||||
|
return None
|
51
tests/util/test_enum.py
Normal file
51
tests/util/test_enum.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
"""Test enum helpers."""
|
||||||
|
from enum import Enum, IntEnum, IntFlag
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.backports.enum import StrEnum
|
||||||
|
from homeassistant.util.enum import try_parse_enum
|
||||||
|
|
||||||
|
|
||||||
|
class _AStrEnum(StrEnum):
|
||||||
|
VALUE = "value"
|
||||||
|
|
||||||
|
|
||||||
|
class _AnIntEnum(IntEnum):
|
||||||
|
VALUE = 1
|
||||||
|
|
||||||
|
|
||||||
|
class _AnIntFlag(IntFlag):
|
||||||
|
VALUE = 1
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"enum_type,value,expected",
|
||||||
|
[
|
||||||
|
# StrEnum valid checks
|
||||||
|
(_AStrEnum, _AStrEnum.VALUE, _AStrEnum.VALUE),
|
||||||
|
(_AStrEnum, "value", _AStrEnum.VALUE),
|
||||||
|
# StrEnum invalid checks
|
||||||
|
(_AStrEnum, "invalid", None),
|
||||||
|
(_AStrEnum, 1, None),
|
||||||
|
(_AStrEnum, None, None),
|
||||||
|
# IntEnum valid checks
|
||||||
|
(_AnIntEnum, _AnIntEnum.VALUE, _AnIntEnum.VALUE),
|
||||||
|
(_AnIntEnum, 1, _AnIntEnum.VALUE),
|
||||||
|
# IntEnum invalid checks
|
||||||
|
(_AnIntEnum, "value", None),
|
||||||
|
(_AnIntEnum, 2, None),
|
||||||
|
(_AnIntEnum, None, None),
|
||||||
|
# IntFlag valid checks
|
||||||
|
(_AnIntFlag, _AnIntFlag.VALUE, _AnIntFlag.VALUE),
|
||||||
|
(_AnIntFlag, 1, _AnIntFlag.VALUE),
|
||||||
|
(_AnIntFlag, 2, _AnIntFlag(2)),
|
||||||
|
# IntFlag invalid checks
|
||||||
|
(_AnIntFlag, "value", None),
|
||||||
|
(_AnIntFlag, None, None),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_try_parse(enum_type: type[Enum], value: Any, expected: Enum | None) -> None:
|
||||||
|
"""Test parsing of values into an Enum."""
|
||||||
|
assert try_parse_enum(enum_type, value) is expected
|
Loading…
x
Reference in New Issue
Block a user