Rename UnitOfConductivity
enum members (#127919)
* Rename UnitOfConductivity enum members * Update test snapshots
This commit is contained in:
parent
0c0ff855b1
commit
0956dbb578
7 changed files with 331 additions and 15 deletions
|
@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Final
|
|||
from .helpers.deprecation import (
|
||||
DeprecatedConstant,
|
||||
DeprecatedConstantEnum,
|
||||
EnumWithDeprecatedMembers,
|
||||
all_with_deprecated_constants,
|
||||
check_if_deprecated_constant,
|
||||
dir_with_deprecated_constants,
|
||||
|
@ -1177,20 +1178,35 @@ _DEPRECATED_MASS_POUNDS: Final = DeprecatedConstantEnum(
|
|||
"""Deprecated: please use UnitOfMass.POUNDS"""
|
||||
|
||||
|
||||
# Conductivity units
|
||||
class UnitOfConductivity(StrEnum):
|
||||
class UnitOfConductivity(
|
||||
StrEnum,
|
||||
metaclass=EnumWithDeprecatedMembers,
|
||||
deprecated={
|
||||
"SIEMENS": ("SIEMENS_PER_CM", "2025.11.0"),
|
||||
"MICROSIEMENS": ("MICROSIEMENS_PER_CM", "2025.11.0"),
|
||||
"MILLISIEMENS": ("MILLISIEMENS_PER_CM", "2025.11.0"),
|
||||
},
|
||||
):
|
||||
"""Conductivity units."""
|
||||
|
||||
SIEMENS_PER_CM = "S/cm"
|
||||
MICROSIEMENS_PER_CM = "µS/cm"
|
||||
MILLISIEMENS_PER_CM = "mS/cm"
|
||||
|
||||
# Deprecated aliases
|
||||
SIEMENS = "S/cm"
|
||||
"""Deprecated: Please use UnitOfConductivity.SIEMENS_PER_CM"""
|
||||
MICROSIEMENS = "µS/cm"
|
||||
"""Deprecated: Please use UnitOfConductivity.MICROSIEMENS_PER_CM"""
|
||||
MILLISIEMENS = "mS/cm"
|
||||
"""Deprecated: Please use UnitOfConductivity.MILLISIEMENS_PER_CM"""
|
||||
|
||||
|
||||
_DEPRECATED_CONDUCTIVITY: Final = DeprecatedConstantEnum(
|
||||
UnitOfConductivity.MICROSIEMENS,
|
||||
"2025.6",
|
||||
UnitOfConductivity.MICROSIEMENS_PER_CM,
|
||||
"2025.11",
|
||||
)
|
||||
"""Deprecated: please use UnitOfConductivity.MICROSIEMENS"""
|
||||
"""Deprecated: please use UnitOfConductivity.MICROSIEMENS_PER_CM"""
|
||||
|
||||
# Light units
|
||||
LIGHT_LUX: Final = "lx"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from enum import Enum
|
||||
from enum import Enum, EnumType, _EnumDict
|
||||
import functools
|
||||
import inspect
|
||||
import logging
|
||||
|
@ -338,3 +338,35 @@ def all_with_deprecated_constants(module_globals: dict[str, Any]) -> list[str]:
|
|||
for name in module_globals_keys
|
||||
if name.startswith(_PREFIX_DEPRECATED)
|
||||
]
|
||||
|
||||
|
||||
class EnumWithDeprecatedMembers(EnumType):
|
||||
"""Enum with deprecated members."""
|
||||
|
||||
def __new__(
|
||||
mcs, # noqa: N804 ruff bug, ruff does not understand this is a metaclass
|
||||
cls: str,
|
||||
bases: tuple[type, ...],
|
||||
classdict: _EnumDict,
|
||||
*,
|
||||
deprecated: dict[str, tuple[str, str]],
|
||||
**kwds: Any,
|
||||
) -> Any:
|
||||
"""Create a new class."""
|
||||
classdict["__deprecated__"] = deprecated
|
||||
return super().__new__(mcs, cls, bases, classdict, **kwds)
|
||||
|
||||
def __getattribute__(cls, name: str) -> Any:
|
||||
"""Warn if accessing a deprecated member."""
|
||||
deprecated = super().__getattribute__("__deprecated__")
|
||||
if name in deprecated:
|
||||
_print_deprecation_warning_internal(
|
||||
f"{cls.__name__}.{name}",
|
||||
cls.__module__,
|
||||
f"{cls.__name__}.{deprecated[name][0]}",
|
||||
"enum member",
|
||||
"used",
|
||||
deprecated[name][1],
|
||||
log_when_no_integration_is_found=False,
|
||||
)
|
||||
return super().__getattribute__(name)
|
||||
|
|
|
@ -178,9 +178,9 @@ class ConductivityConverter(BaseUnitConverter):
|
|||
|
||||
UNIT_CLASS = "conductivity"
|
||||
_UNIT_CONVERSION: dict[str | None, float] = {
|
||||
UnitOfConductivity.MICROSIEMENS: 1,
|
||||
UnitOfConductivity.MILLISIEMENS: 1e-3,
|
||||
UnitOfConductivity.SIEMENS: 1e-6,
|
||||
UnitOfConductivity.MICROSIEMENS_PER_CM: 1,
|
||||
UnitOfConductivity.MILLISIEMENS_PER_CM: 1e-3,
|
||||
UnitOfConductivity.SIEMENS_PER_CM: 1e-6,
|
||||
}
|
||||
VALID_UNITS = set(UnitOfConductivity)
|
||||
|
||||
|
|
|
@ -421,7 +421,7 @@
|
|||
'supported_features': 0,
|
||||
'translation_key': 'salinity',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-0-salinity',
|
||||
'unit_of_measurement': <UnitOfConductivity.MILLISIEMENS: 'mS/cm'>,
|
||||
'unit_of_measurement': <UnitOfConductivity.MILLISIEMENS_PER_CM: 'mS/cm'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.gummibaum_salinity-state]
|
||||
|
@ -430,7 +430,7 @@
|
|||
'device_class': 'conductivity',
|
||||
'friendly_name': 'Gummibaum Salinity',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfConductivity.MILLISIEMENS: 'mS/cm'>,
|
||||
'unit_of_measurement': <UnitOfConductivity.MILLISIEMENS_PER_CM: 'mS/cm'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.gummibaum_salinity',
|
||||
|
@ -1087,7 +1087,7 @@
|
|||
'supported_features': 0,
|
||||
'translation_key': 'salinity',
|
||||
'unique_id': 'ce5f5431554d101905d31797e1232da8-1-salinity',
|
||||
'unit_of_measurement': <UnitOfConductivity.MILLISIEMENS: 'mS/cm'>,
|
||||
'unit_of_measurement': <UnitOfConductivity.MILLISIEMENS_PER_CM: 'mS/cm'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.kakaobaum_salinity-state]
|
||||
|
@ -1096,7 +1096,7 @@
|
|||
'device_class': 'conductivity',
|
||||
'friendly_name': 'Kakaobaum Salinity',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfConductivity.MILLISIEMENS: 'mS/cm'>,
|
||||
'unit_of_measurement': <UnitOfConductivity.MILLISIEMENS_PER_CM: 'mS/cm'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.kakaobaum_salinity',
|
||||
|
|
|
@ -13,6 +13,7 @@ from homeassistant.helpers.deprecation import (
|
|||
DeprecatedAlias,
|
||||
DeprecatedConstant,
|
||||
DeprecatedConstantEnum,
|
||||
EnumWithDeprecatedMembers,
|
||||
check_if_deprecated_constant,
|
||||
deprecated_class,
|
||||
deprecated_function,
|
||||
|
@ -520,3 +521,119 @@ def test_dir_with_deprecated_constants(
|
|||
) -> None:
|
||||
"""Test dir() with deprecated constants."""
|
||||
assert dir_with_deprecated_constants([*module_globals.keys()]) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("module_name", "extra_extra_msg"),
|
||||
[
|
||||
("homeassistant.components.hue.light", ""), # builtin integration
|
||||
(
|
||||
"config.custom_components.hue.light",
|
||||
", please report it to the author of the 'hue' custom integration",
|
||||
), # custom component integration
|
||||
],
|
||||
)
|
||||
def test_enum_with_deprecated_members(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
module_name: str,
|
||||
extra_extra_msg: str,
|
||||
) -> None:
|
||||
"""Test EnumWithDeprecatedMembers."""
|
||||
filename = f"/home/paulus/{module_name.replace('.', '/')}.py"
|
||||
|
||||
class TestEnum(
|
||||
StrEnum,
|
||||
metaclass=EnumWithDeprecatedMembers,
|
||||
deprecated={
|
||||
"CATS": ("CATS_PER_CM", "2025.11.0"),
|
||||
"DOGS": ("DOGS_PER_CM", None),
|
||||
},
|
||||
):
|
||||
"""Zoo units."""
|
||||
|
||||
CATS_PER_CM = "cats/cm"
|
||||
DOGS_PER_CM = "dogs/cm"
|
||||
CATS = "cats/cm"
|
||||
DOGS = "dogs/cm"
|
||||
|
||||
# mock sys.modules for homeassistant/helpers/frame.py#get_integration_frame
|
||||
with (
|
||||
patch.dict(sys.modules, {module_name: Mock(__file__=filename)}),
|
||||
patch(
|
||||
"homeassistant.helpers.frame.linecache.getline",
|
||||
return_value="await session.close()",
|
||||
),
|
||||
patch(
|
||||
"homeassistant.helpers.frame.get_current_frame",
|
||||
return_value=extract_stack_to_frame(
|
||||
[
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/core.py",
|
||||
lineno="23",
|
||||
line="do_something()",
|
||||
),
|
||||
Mock(
|
||||
filename=filename,
|
||||
lineno="23",
|
||||
line="await session.close()",
|
||||
),
|
||||
Mock(
|
||||
filename="/home/paulus/aiohue/lights.py",
|
||||
lineno="2",
|
||||
line="something()",
|
||||
),
|
||||
]
|
||||
),
|
||||
),
|
||||
):
|
||||
TestEnum.CATS # noqa: B018
|
||||
TestEnum.DOGS # noqa: B018
|
||||
|
||||
assert len(caplog.record_tuples) == 2
|
||||
assert (
|
||||
"tests.helpers.test_deprecation",
|
||||
logging.WARNING,
|
||||
(
|
||||
"TestEnum.CATS was used from hue, this is a deprecated enum member which "
|
||||
"will be removed in HA Core 2025.11.0. Use TestEnum.CATS_PER_CM instead"
|
||||
f"{extra_extra_msg}"
|
||||
),
|
||||
) in caplog.record_tuples
|
||||
assert (
|
||||
"tests.helpers.test_deprecation",
|
||||
logging.WARNING,
|
||||
(
|
||||
"TestEnum.DOGS was used from hue, this is a deprecated enum member. Use "
|
||||
f"TestEnum.DOGS_PER_CM instead{extra_extra_msg}"
|
||||
),
|
||||
) in caplog.record_tuples
|
||||
|
||||
|
||||
def test_enum_with_deprecated_members_integration_not_found(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test check_if_deprecated_constant."""
|
||||
|
||||
class TestEnum(
|
||||
StrEnum,
|
||||
metaclass=EnumWithDeprecatedMembers,
|
||||
deprecated={
|
||||
"CATS": ("CATS_PER_CM", "2025.11.0"),
|
||||
"DOGS": ("DOGS_PER_CM", None),
|
||||
},
|
||||
):
|
||||
"""Zoo units."""
|
||||
|
||||
CATS_PER_CM = "cats/cm"
|
||||
DOGS_PER_CM = "dogs/cm"
|
||||
CATS = "cats/cm"
|
||||
DOGS = "dogs/cm"
|
||||
|
||||
with patch(
|
||||
"homeassistant.helpers.frame.get_current_frame",
|
||||
side_effect=MissingIntegrationFrame,
|
||||
):
|
||||
TestEnum.CATS # noqa: B018
|
||||
TestEnum.DOGS # noqa: B018
|
||||
|
||||
assert len(caplog.record_tuples) == 0
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
"""Test const module."""
|
||||
|
||||
from enum import Enum
|
||||
import logging
|
||||
import sys
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
|
@ -8,6 +11,7 @@ from homeassistant import const
|
|||
from homeassistant.components import lock, sensor
|
||||
|
||||
from .common import (
|
||||
extract_stack_to_frame,
|
||||
help_test_all,
|
||||
import_and_test_deprecated_constant,
|
||||
import_and_test_deprecated_constant_enum,
|
||||
|
@ -212,3 +216,78 @@ def test_deprecated_constants_lock(
|
|||
import_and_test_deprecated_constant_enum(
|
||||
caplog, const, enum, constant_prefix, remove_in_version
|
||||
)
|
||||
|
||||
|
||||
def test_deprecated_unit_of_conductivity_alias() -> None:
|
||||
"""Test UnitOfConductivity deprecation."""
|
||||
|
||||
# Test the deprecated members are aliases
|
||||
assert set(const.UnitOfConductivity) == {"S/cm", "µS/cm", "mS/cm"}
|
||||
|
||||
|
||||
def test_deprecated_unit_of_conductivity_members(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test UnitOfConductivity deprecation."""
|
||||
|
||||
module_name = "config.custom_components.hue.light"
|
||||
filename = f"/home/paulus/{module_name.replace('.', '/')}.py"
|
||||
|
||||
with (
|
||||
patch.dict(sys.modules, {module_name: Mock(__file__=filename)}),
|
||||
patch(
|
||||
"homeassistant.helpers.frame.linecache.getline",
|
||||
return_value="await session.close()",
|
||||
),
|
||||
patch(
|
||||
"homeassistant.helpers.frame.get_current_frame",
|
||||
return_value=extract_stack_to_frame(
|
||||
[
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/core.py",
|
||||
lineno="23",
|
||||
line="do_something()",
|
||||
),
|
||||
Mock(
|
||||
filename=filename,
|
||||
lineno="23",
|
||||
line="await session.close()",
|
||||
),
|
||||
Mock(
|
||||
filename="/home/paulus/aiohue/lights.py",
|
||||
lineno="2",
|
||||
line="something()",
|
||||
),
|
||||
]
|
||||
),
|
||||
),
|
||||
):
|
||||
const.UnitOfConductivity.SIEMENS # noqa: B018
|
||||
const.UnitOfConductivity.MICROSIEMENS # noqa: B018
|
||||
const.UnitOfConductivity.MILLISIEMENS # noqa: B018
|
||||
|
||||
assert len(caplog.record_tuples) == 3
|
||||
|
||||
def deprecation_message(member: str, replacement: str) -> str:
|
||||
return (
|
||||
f"UnitOfConductivity.{member} was used from hue, this is a deprecated enum "
|
||||
"member which will be removed in HA Core 2025.11.0. Use UnitOfConductivity."
|
||||
f"{replacement} instead, please report it to the author of the 'hue' custom"
|
||||
" integration"
|
||||
)
|
||||
|
||||
assert (
|
||||
const.__name__,
|
||||
logging.WARNING,
|
||||
deprecation_message("SIEMENS", "SIEMENS_PER_CM"),
|
||||
) in caplog.record_tuples
|
||||
assert (
|
||||
const.__name__,
|
||||
logging.WARNING,
|
||||
deprecation_message("MICROSIEMENS", "MICROSIEMENS_PER_CM"),
|
||||
) in caplog.record_tuples
|
||||
assert (
|
||||
const.__name__,
|
||||
logging.WARNING,
|
||||
deprecation_message("MILLISIEMENS", "MILLISIEMENS_PER_CM"),
|
||||
) in caplog.record_tuples
|
||||
|
|
|
@ -81,8 +81,8 @@ _ALL_CONVERTERS: dict[type[BaseUnitConverter], list[str | None]] = {
|
|||
# Dict containing all converters with a corresponding unit ratio.
|
||||
_GET_UNIT_RATIO: dict[type[BaseUnitConverter], tuple[str | None, str | None, float]] = {
|
||||
ConductivityConverter: (
|
||||
UnitOfConductivity.MICROSIEMENS,
|
||||
UnitOfConductivity.MILLISIEMENS,
|
||||
UnitOfConductivity.MICROSIEMENS_PER_CM,
|
||||
UnitOfConductivity.MILLISIEMENS_PER_CM,
|
||||
1000,
|
||||
),
|
||||
DataRateConverter: (
|
||||
|
@ -131,12 +131,84 @@ _CONVERTED_VALUE: dict[
|
|||
type[BaseUnitConverter], list[tuple[float, str | None, float, str | None]]
|
||||
] = {
|
||||
ConductivityConverter: [
|
||||
# Deprecated to deprecated
|
||||
(5, UnitOfConductivity.SIEMENS, 5e3, UnitOfConductivity.MILLISIEMENS),
|
||||
(5, UnitOfConductivity.SIEMENS, 5e6, UnitOfConductivity.MICROSIEMENS),
|
||||
(5, UnitOfConductivity.MILLISIEMENS, 5e3, UnitOfConductivity.MICROSIEMENS),
|
||||
(5, UnitOfConductivity.MILLISIEMENS, 5e-3, UnitOfConductivity.SIEMENS),
|
||||
(5e6, UnitOfConductivity.MICROSIEMENS, 5e3, UnitOfConductivity.MILLISIEMENS),
|
||||
(5e6, UnitOfConductivity.MICROSIEMENS, 5, UnitOfConductivity.SIEMENS),
|
||||
# Deprecated to new
|
||||
(5, UnitOfConductivity.SIEMENS, 5e3, UnitOfConductivity.MILLISIEMENS_PER_CM),
|
||||
(5, UnitOfConductivity.SIEMENS, 5e6, UnitOfConductivity.MICROSIEMENS_PER_CM),
|
||||
(
|
||||
5,
|
||||
UnitOfConductivity.MILLISIEMENS,
|
||||
5e3,
|
||||
UnitOfConductivity.MICROSIEMENS_PER_CM,
|
||||
),
|
||||
(5, UnitOfConductivity.MILLISIEMENS, 5e-3, UnitOfConductivity.SIEMENS_PER_CM),
|
||||
(
|
||||
5e6,
|
||||
UnitOfConductivity.MICROSIEMENS,
|
||||
5e3,
|
||||
UnitOfConductivity.MILLISIEMENS_PER_CM,
|
||||
),
|
||||
(5e6, UnitOfConductivity.MICROSIEMENS, 5, UnitOfConductivity.SIEMENS_PER_CM),
|
||||
# New to deprecated
|
||||
(5, UnitOfConductivity.SIEMENS_PER_CM, 5e3, UnitOfConductivity.MILLISIEMENS),
|
||||
(5, UnitOfConductivity.SIEMENS_PER_CM, 5e6, UnitOfConductivity.MICROSIEMENS),
|
||||
(
|
||||
5,
|
||||
UnitOfConductivity.MILLISIEMENS_PER_CM,
|
||||
5e3,
|
||||
UnitOfConductivity.MICROSIEMENS,
|
||||
),
|
||||
(5, UnitOfConductivity.MILLISIEMENS_PER_CM, 5e-3, UnitOfConductivity.SIEMENS),
|
||||
(
|
||||
5e6,
|
||||
UnitOfConductivity.MICROSIEMENS_PER_CM,
|
||||
5e3,
|
||||
UnitOfConductivity.MILLISIEMENS,
|
||||
),
|
||||
(5e6, UnitOfConductivity.MICROSIEMENS_PER_CM, 5, UnitOfConductivity.SIEMENS),
|
||||
# New to new
|
||||
(
|
||||
5,
|
||||
UnitOfConductivity.SIEMENS_PER_CM,
|
||||
5e3,
|
||||
UnitOfConductivity.MILLISIEMENS_PER_CM,
|
||||
),
|
||||
(
|
||||
5,
|
||||
UnitOfConductivity.SIEMENS_PER_CM,
|
||||
5e6,
|
||||
UnitOfConductivity.MICROSIEMENS_PER_CM,
|
||||
),
|
||||
(
|
||||
5,
|
||||
UnitOfConductivity.MILLISIEMENS_PER_CM,
|
||||
5e3,
|
||||
UnitOfConductivity.MICROSIEMENS_PER_CM,
|
||||
),
|
||||
(
|
||||
5,
|
||||
UnitOfConductivity.MILLISIEMENS_PER_CM,
|
||||
5e-3,
|
||||
UnitOfConductivity.SIEMENS_PER_CM,
|
||||
),
|
||||
(
|
||||
5e6,
|
||||
UnitOfConductivity.MICROSIEMENS_PER_CM,
|
||||
5e3,
|
||||
UnitOfConductivity.MILLISIEMENS_PER_CM,
|
||||
),
|
||||
(
|
||||
5e6,
|
||||
UnitOfConductivity.MICROSIEMENS_PER_CM,
|
||||
5,
|
||||
UnitOfConductivity.SIEMENS_PER_CM,
|
||||
),
|
||||
],
|
||||
DataRateConverter: [
|
||||
(8e3, UnitOfDataRate.BITS_PER_SECOND, 8, UnitOfDataRate.KILOBITS_PER_SECOND),
|
||||
|
|
Loading…
Add table
Reference in a new issue