mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Add dir_with_deprecated_constants function to deprecation helper (#106059)
This commit is contained in:
parent
63136572a5
commit
0e0fd39603
@ -20,6 +20,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
|
|||||||
from homeassistant.helpers.deprecation import (
|
from homeassistant.helpers.deprecation import (
|
||||||
DeprecatedConstantEnum,
|
DeprecatedConstantEnum,
|
||||||
check_if_deprecated_constant,
|
check_if_deprecated_constant,
|
||||||
|
dir_with_deprecated_constants,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.entity import Entity, EntityDescription
|
from homeassistant.helpers.entity import Entity, EntityDescription
|
||||||
from homeassistant.helpers.entity_component import EntityComponent
|
from homeassistant.helpers.entity_component import EntityComponent
|
||||||
@ -211,7 +212,9 @@ _DEPRECATED_DEVICE_CLASS_WINDOW = DeprecatedConstantEnum(
|
|||||||
BinarySensorDeviceClass.WINDOW, "2025.1"
|
BinarySensorDeviceClass.WINDOW, "2025.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Both can be removed if no deprecated constant are in this module anymore
|
||||||
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
|
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
|
||||||
|
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
|
||||||
|
|
||||||
# mypy: disallow-any-generics
|
# mypy: disallow-any-generics
|
||||||
|
|
||||||
|
@ -237,6 +237,9 @@ class DeprecatedConstantEnum(NamedTuple):
|
|||||||
breaks_in_ha_version: str | None
|
breaks_in_ha_version: str | None
|
||||||
|
|
||||||
|
|
||||||
|
_PREFIX_DEPRECATED = "_DEPRECATED_"
|
||||||
|
|
||||||
|
|
||||||
def check_if_deprecated_constant(name: str, module_globals: dict[str, Any]) -> Any:
|
def check_if_deprecated_constant(name: str, module_globals: dict[str, Any]) -> Any:
|
||||||
"""Check if the not found name is a deprecated constant.
|
"""Check if the not found name is a deprecated constant.
|
||||||
|
|
||||||
@ -245,7 +248,7 @@ def check_if_deprecated_constant(name: str, module_globals: dict[str, Any]) -> A
|
|||||||
"""
|
"""
|
||||||
module_name = module_globals.get("__name__")
|
module_name = module_globals.get("__name__")
|
||||||
logger = logging.getLogger(module_name)
|
logger = logging.getLogger(module_name)
|
||||||
if (deprecated_const := module_globals.get(f"_DEPRECATED_{name}")) is None:
|
if (deprecated_const := module_globals.get(_PREFIX_DEPRECATED + name)) is None:
|
||||||
raise AttributeError(f"Module {module_name!r} has no attribute {name!r}")
|
raise AttributeError(f"Module {module_name!r} has no attribute {name!r}")
|
||||||
if isinstance(deprecated_const, DeprecatedConstant):
|
if isinstance(deprecated_const, DeprecatedConstant):
|
||||||
value = deprecated_const.value
|
value = deprecated_const.value
|
||||||
@ -259,7 +262,7 @@ def check_if_deprecated_constant(name: str, module_globals: dict[str, Any]) -> A
|
|||||||
breaks_in_ha_version = deprecated_const.breaks_in_ha_version
|
breaks_in_ha_version = deprecated_const.breaks_in_ha_version
|
||||||
else:
|
else:
|
||||||
msg = (
|
msg = (
|
||||||
f"Value of _DEPRECATED_{name!r} is an instance of {type(deprecated_const)} "
|
f"Value of {_PREFIX_DEPRECATED}{name!r} is an instance of {type(deprecated_const)} "
|
||||||
"but an instance of DeprecatedConstant or DeprecatedConstantEnum is required"
|
"but an instance of DeprecatedConstant or DeprecatedConstantEnum is required"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -279,3 +282,12 @@ def check_if_deprecated_constant(name: str, module_globals: dict[str, Any]) -> A
|
|||||||
breaks_in_ha_version,
|
breaks_in_ha_version,
|
||||||
)
|
)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def dir_with_deprecated_constants(module_globals: dict[str, Any]) -> list[str]:
|
||||||
|
"""Return dir() with deprecated constants."""
|
||||||
|
return list(module_globals) + [
|
||||||
|
name.removeprefix(_PREFIX_DEPRECATED)
|
||||||
|
for name in module_globals
|
||||||
|
if name.startswith(_PREFIX_DEPRECATED)
|
||||||
|
]
|
||||||
|
@ -6,6 +6,7 @@ from collections import OrderedDict
|
|||||||
from collections.abc import Generator, Mapping, Sequence
|
from collections.abc import Generator, Mapping, Sequence
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from datetime import UTC, datetime, timedelta
|
from datetime import UTC, datetime, timedelta
|
||||||
|
from enum import Enum
|
||||||
import functools as ft
|
import functools as ft
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
@ -15,10 +16,12 @@ import os
|
|||||||
import pathlib
|
import pathlib
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
from types import ModuleType
|
||||||
from typing import Any, NoReturn
|
from typing import Any, NoReturn
|
||||||
from unittest.mock import AsyncMock, Mock, patch
|
from unittest.mock import AsyncMock, Mock, patch
|
||||||
|
|
||||||
from aiohttp.test_utils import unused_port as get_test_instance_port # noqa: F401
|
from aiohttp.test_utils import unused_port as get_test_instance_port # noqa: F401
|
||||||
|
import pytest
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import auth, bootstrap, config_entries, loader
|
from homeassistant import auth, bootstrap, config_entries, loader
|
||||||
@ -1460,3 +1463,26 @@ def async_mock_cloud_connection_status(hass: HomeAssistant, connected: bool) ->
|
|||||||
else:
|
else:
|
||||||
state = CloudConnectionState.CLOUD_DISCONNECTED
|
state = CloudConnectionState.CLOUD_DISCONNECTED
|
||||||
async_dispatcher_send(hass, SIGNAL_CLOUD_CONNECTION_STATE, state)
|
async_dispatcher_send(hass, SIGNAL_CLOUD_CONNECTION_STATE, state)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_deprecated_constant(
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
module: ModuleType,
|
||||||
|
replacement: Enum,
|
||||||
|
constant_prefix: str,
|
||||||
|
breaks_in_ha_version: str,
|
||||||
|
) -> None:
|
||||||
|
"""Validate deprecated constant creates a log entry and is included in the modules.__dir__()."""
|
||||||
|
assert (
|
||||||
|
module.__name__,
|
||||||
|
logging.WARNING,
|
||||||
|
(
|
||||||
|
f"{constant_prefix}{replacement.name} was used from test_constant_deprecation,"
|
||||||
|
f" this is a deprecated constant which will be removed in HA Core {breaks_in_ha_version}. "
|
||||||
|
f"Use {replacement.__class__.__name__}.{replacement.name} instead, please report "
|
||||||
|
"it to the author of the 'test_constant_deprecation' custom integration"
|
||||||
|
),
|
||||||
|
) in caplog.record_tuples
|
||||||
|
|
||||||
|
# verify deprecated constant is included in dir()
|
||||||
|
assert f"{constant_prefix}{replacement.name}" in dir(module)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
"""The tests for the Binary sensor component."""
|
"""The tests for the Binary sensor component."""
|
||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
import logging
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@ -18,6 +17,7 @@ from tests.common import (
|
|||||||
mock_config_flow,
|
mock_config_flow,
|
||||||
mock_integration,
|
mock_integration,
|
||||||
mock_platform,
|
mock_platform,
|
||||||
|
validate_deprecated_constant,
|
||||||
)
|
)
|
||||||
from tests.testing_config.custom_components.test.binary_sensor import MockBinarySensor
|
from tests.testing_config.custom_components.test.binary_sensor import MockBinarySensor
|
||||||
from tests.testing_config.custom_components.test_constant_deprecation.binary_sensor import (
|
from tests.testing_config.custom_components.test_constant_deprecation.binary_sensor import (
|
||||||
@ -210,14 +210,6 @@ def test_deprecated_constant_device_class(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Test deprecated binary sensor device classes."""
|
"""Test deprecated binary sensor device classes."""
|
||||||
import_deprecated(device_class)
|
import_deprecated(device_class)
|
||||||
|
validate_deprecated_constant(
|
||||||
assert (
|
caplog, binary_sensor, device_class, "DEVICE_CLASS_", "2025.1"
|
||||||
"homeassistant.components.binary_sensor",
|
)
|
||||||
logging.WARNING,
|
|
||||||
(
|
|
||||||
f"DEVICE_CLASS_{device_class.name} was used from test_constant_deprecation,"
|
|
||||||
" this is a deprecated constant which will be removed in HA Core 2025.1. "
|
|
||||||
f"Use BinarySensorDeviceClass.{device_class.name} instead, please report "
|
|
||||||
"it to the author of the 'test_constant_deprecation' custom integration"
|
|
||||||
),
|
|
||||||
) in caplog.record_tuples
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""Test deprecation helpers."""
|
"""Test deprecation helpers."""
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
from typing import Any
|
||||||
from unittest.mock import MagicMock, Mock, patch
|
from unittest.mock import MagicMock, Mock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@ -13,6 +14,7 @@ from homeassistant.helpers.deprecation import (
|
|||||||
deprecated_class,
|
deprecated_class,
|
||||||
deprecated_function,
|
deprecated_function,
|
||||||
deprecated_substitute,
|
deprecated_substitute,
|
||||||
|
dir_with_deprecated_constants,
|
||||||
get_deprecated,
|
get_deprecated,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -341,3 +343,21 @@ def test_test_check_if_deprecated_constant_invalid(
|
|||||||
check_if_deprecated_constant(name, module_globals)
|
check_if_deprecated_constant(name, module_globals)
|
||||||
|
|
||||||
assert (module_name, logging.DEBUG, excepted_msg) in caplog.record_tuples
|
assert (module_name, logging.DEBUG, excepted_msg) in caplog.record_tuples
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("module_global", "expected"),
|
||||||
|
[
|
||||||
|
({"CONSTANT": 1}, ["CONSTANT"]),
|
||||||
|
({"_DEPRECATED_CONSTANT": 1}, ["_DEPRECATED_CONSTANT", "CONSTANT"]),
|
||||||
|
(
|
||||||
|
{"_DEPRECATED_CONSTANT": 1, "SOMETHING": 2},
|
||||||
|
["_DEPRECATED_CONSTANT", "SOMETHING", "CONSTANT"],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_dir_with_deprecated_constants(
|
||||||
|
module_global: dict[str, Any], expected: list[str]
|
||||||
|
) -> None:
|
||||||
|
"""Test dir() with deprecated constants."""
|
||||||
|
assert dir_with_deprecated_constants(module_global) == expected
|
||||||
|
Loading…
x
Reference in New Issue
Block a user