mirror of
https://github.com/home-assistant/core
synced 2024-10-05 15:22:20 +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 (
|
||||
DeprecatedConstantEnum,
|
||||
check_if_deprecated_constant,
|
||||
dir_with_deprecated_constants,
|
||||
)
|
||||
from homeassistant.helpers.entity import Entity, EntityDescription
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
|
@ -211,7 +212,9 @@ _DEPRECATED_DEVICE_CLASS_WINDOW = DeprecatedConstantEnum(
|
|||
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())
|
||||
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
|
||||
|
||||
# mypy: disallow-any-generics
|
||||
|
||||
|
|
|
@ -237,6 +237,9 @@ class DeprecatedConstantEnum(NamedTuple):
|
|||
breaks_in_ha_version: str | None
|
||||
|
||||
|
||||
_PREFIX_DEPRECATED = "_DEPRECATED_"
|
||||
|
||||
|
||||
def check_if_deprecated_constant(name: str, module_globals: dict[str, Any]) -> Any:
|
||||
"""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__")
|
||||
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}")
|
||||
if isinstance(deprecated_const, DeprecatedConstant):
|
||||
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
|
||||
else:
|
||||
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"
|
||||
)
|
||||
|
||||
|
@ -279,3 +282,12 @@ def check_if_deprecated_constant(name: str, module_globals: dict[str, Any]) -> A
|
|||
breaks_in_ha_version,
|
||||
)
|
||||
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 contextlib import contextmanager
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from enum import Enum
|
||||
import functools as ft
|
||||
from functools import lru_cache
|
||||
from io import StringIO
|
||||
|
@ -15,10 +16,12 @@ import os
|
|||
import pathlib
|
||||
import threading
|
||||
import time
|
||||
from types import ModuleType
|
||||
from typing import Any, NoReturn
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
from aiohttp.test_utils import unused_port as get_test_instance_port # noqa: F401
|
||||
import pytest
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import auth, bootstrap, config_entries, loader
|
||||
|
@ -1460,3 +1463,26 @@ def async_mock_cloud_connection_status(hass: HomeAssistant, connected: bool) ->
|
|||
else:
|
||||
state = CloudConnectionState.CLOUD_DISCONNECTED
|
||||
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."""
|
||||
from collections.abc import Generator
|
||||
import logging
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
@ -18,6 +17,7 @@ from tests.common import (
|
|||
mock_config_flow,
|
||||
mock_integration,
|
||||
mock_platform,
|
||||
validate_deprecated_constant,
|
||||
)
|
||||
from tests.testing_config.custom_components.test.binary_sensor import MockBinarySensor
|
||||
from tests.testing_config.custom_components.test_constant_deprecation.binary_sensor import (
|
||||
|
@ -210,14 +210,6 @@ def test_deprecated_constant_device_class(
|
|||
) -> None:
|
||||
"""Test deprecated binary sensor device classes."""
|
||||
import_deprecated(device_class)
|
||||
|
||||
assert (
|
||||
"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
|
||||
validate_deprecated_constant(
|
||||
caplog, binary_sensor, device_class, "DEVICE_CLASS_", "2025.1"
|
||||
)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Test deprecation helpers."""
|
||||
import logging
|
||||
import sys
|
||||
from typing import Any
|
||||
from unittest.mock import MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
|
@ -13,6 +14,7 @@ from homeassistant.helpers.deprecation import (
|
|||
deprecated_class,
|
||||
deprecated_function,
|
||||
deprecated_substitute,
|
||||
dir_with_deprecated_constants,
|
||||
get_deprecated,
|
||||
)
|
||||
|
||||
|
@ -341,3 +343,21 @@ def test_test_check_if_deprecated_constant_invalid(
|
|||
check_if_deprecated_constant(name, module_globals)
|
||||
|
||||
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…
Reference in a new issue