Deprecate deprecated automation constants (#106067)

This commit is contained in:
Robert Resch 2023-12-19 19:22:13 +01:00 committed by GitHub
parent 9275d35c0a
commit db985925c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 95 additions and 37 deletions

View File

@ -5,6 +5,7 @@ from abc import ABC, abstractmethod
import asyncio import asyncio
from collections.abc import Callable, Mapping from collections.abc import Callable, Mapping
from dataclasses import dataclass from dataclasses import dataclass
from functools import partial
import logging import logging
from typing import Any, Protocol, cast from typing import Any, Protocol, cast
@ -55,6 +56,11 @@ from homeassistant.exceptions import (
) )
from homeassistant.helpers import condition from homeassistant.helpers import condition
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.deprecation import (
DeprecatedConstant,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
from homeassistant.helpers.entity import ToggleEntity from homeassistant.helpers.entity import ToggleEntity
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
@ -130,9 +136,20 @@ class IfAction(Protocol):
# AutomationActionType, AutomationTriggerData, # AutomationActionType, AutomationTriggerData,
# and AutomationTriggerInfo are deprecated as of 2022.9. # and AutomationTriggerInfo are deprecated as of 2022.9.
AutomationActionType = TriggerActionType # Can be removed in 2025.1
AutomationTriggerData = TriggerData _DEPRECATED_AutomationActionType = DeprecatedConstant(
AutomationTriggerInfo = TriggerInfo TriggerActionType, "TriggerActionType", "2025.1"
)
_DEPRECATED_AutomationTriggerData = DeprecatedConstant(
TriggerData, "TriggerData", "2025.1"
)
_DEPRECATED_AutomationTriggerInfo = DeprecatedConstant(
TriggerInfo, "TriggerInfo", "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())
@bind_hass @bind_hass

View File

@ -91,6 +91,10 @@ from homeassistant.util.unit_system import METRIC_SYSTEM
import homeassistant.util.uuid as uuid_util import homeassistant.util.uuid as uuid_util
import homeassistant.util.yaml.loader as yaml_loader import homeassistant.util.yaml.loader as yaml_loader
from tests.testing_config.custom_components.test_constant_deprecation import (
import_deprecated_costant,
)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
INSTANCES = [] INSTANCES = []
CLIENT_ID = "https://example.com/app" CLIENT_ID = "https://example.com/app"
@ -1465,24 +1469,57 @@ def async_mock_cloud_connection_status(hass: HomeAssistant, connected: bool) ->
async_dispatcher_send(hass, SIGNAL_CLOUD_CONNECTION_STATE, state) async_dispatcher_send(hass, SIGNAL_CLOUD_CONNECTION_STATE, state)
def validate_deprecated_constant( def import_and_test_deprecated_constant_enum(
caplog: pytest.LogCaptureFixture, caplog: pytest.LogCaptureFixture,
module: ModuleType, module: ModuleType,
replacement: Enum, replacement: Enum,
constant_prefix: str, constant_prefix: str,
breaks_in_ha_version: str, breaks_in_ha_version: str,
) -> None: ) -> None:
"""Validate deprecated constant creates a log entry and is included in the modules.__dir__().""" """Import and test deprecated constant replaced by a enum.
- Import deprecated enum
- Assert value is the same as the replacement
- Assert a warning is logged
- Assert the deprecated constant is included in the modules.__dir__()
"""
import_and_test_deprecated_constant(
caplog,
module,
constant_prefix + replacement.name,
f"{replacement.__class__.__name__}.{replacement.name}",
replacement,
breaks_in_ha_version,
)
def import_and_test_deprecated_constant(
caplog: pytest.LogCaptureFixture,
module: ModuleType,
constant_name: str,
replacement_name: str,
replacement: Any,
breaks_in_ha_version: str,
) -> None:
"""Import and test deprecated constant replaced by a value.
- Import deprecated constant
- Assert value is the same as the replacement
- Assert a warning is logged
- Assert the deprecated constant is included in the modules.__dir__()
"""
value = import_deprecated_costant(module, constant_name)
assert value == replacement
assert ( assert (
module.__name__, module.__name__,
logging.WARNING, logging.WARNING,
( (
f"{constant_prefix}{replacement.name} was used from test_constant_deprecation," f"{constant_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" 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 " f"Use {replacement_name} instead, please report "
"it to the author of the 'test_constant_deprecation' custom integration" "it to the author of the 'test_constant_deprecation' custom integration"
), ),
) in caplog.record_tuples ) in caplog.record_tuples
# verify deprecated constant is included in dir() # verify deprecated constant is included in dir()
assert f"{constant_prefix}{replacement.name}" in dir(module) assert constant_name in dir(module)

View File

@ -2,6 +2,7 @@
import asyncio import asyncio
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import Any
from unittest.mock import Mock, patch from unittest.mock import Mock, patch
import pytest import pytest
@ -46,6 +47,7 @@ from homeassistant.helpers.script import (
SCRIPT_MODE_SINGLE, SCRIPT_MODE_SINGLE,
_async_stop_scripts_at_shutdown, _async_stop_scripts_at_shutdown,
) )
from homeassistant.helpers.trigger import TriggerActionType, TriggerData, TriggerInfo
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from homeassistant.util import yaml from homeassistant.util import yaml
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
@ -57,6 +59,7 @@ from tests.common import (
async_capture_events, async_capture_events,
async_fire_time_changed, async_fire_time_changed,
async_mock_service, async_mock_service,
import_and_test_deprecated_constant,
mock_restore_cache, mock_restore_cache,
) )
from tests.components.logbook.common import MockRow, mock_humanify from tests.components.logbook.common import MockRow, mock_humanify
@ -2564,3 +2567,22 @@ async def test_websocket_config(
msg = await client.receive_json() msg = await client.receive_json()
assert not msg["success"] assert not msg["success"]
assert msg["error"]["code"] == "not_found" assert msg["error"]["code"] == "not_found"
@pytest.mark.parametrize(
("constant_name", "replacement"),
[
("AutomationActionType", TriggerActionType),
("AutomationTriggerData", TriggerData),
("AutomationTriggerInfo", TriggerInfo),
],
)
def test_deprecated_constants(
caplog: pytest.LogCaptureFixture,
constant_name: str,
replacement: Any,
) -> None:
"""Test deprecated binary sensor device classes."""
import_and_test_deprecated_constant(
caplog, automation, constant_name, replacement.__name__, replacement, "2025.1"
)

View File

@ -14,15 +14,12 @@ from tests.common import (
MockConfigEntry, MockConfigEntry,
MockModule, MockModule,
MockPlatform, MockPlatform,
import_and_test_deprecated_constant_enum,
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 (
import_deprecated,
)
TEST_DOMAIN = "test" TEST_DOMAIN = "test"
@ -209,7 +206,6 @@ def test_deprecated_constant_device_class(
device_class: binary_sensor.BinarySensorDeviceClass, device_class: binary_sensor.BinarySensorDeviceClass,
) -> None: ) -> None:
"""Test deprecated binary sensor device classes.""" """Test deprecated binary sensor device classes."""
import_deprecated(device_class) import_and_test_deprecated_constant_enum(
validate_deprecated_constant(
caplog, binary_sensor, device_class, "DEVICE_CLASS_", "2025.1" caplog, binary_sensor, device_class, "DEVICE_CLASS_", "2025.1"
) )

View File

@ -0,0 +1,9 @@
"""Test deprecated constants custom integration."""
from types import ModuleType
from typing import Any
def import_deprecated_costant(module: ModuleType, constant_name: str) -> Any:
"""Import and return deprecated constant."""
return getattr(module, constant_name)

View File

@ -1,12 +0,0 @@
"""Test deprecated binary sensor device classes."""
from functools import partial
from homeassistant.components import binary_sensor
from .util import import_and_test_deprecated_costant
import_deprecated = partial(
import_and_test_deprecated_costant,
module=binary_sensor,
constant_prefix="DEVICE_CLASS_",
)

View File

@ -1,11 +0,0 @@
"""util module for test_constant_deprecation tests."""
from enum import Enum
from types import ModuleType
def import_and_test_deprecated_costant(
replacement: Enum, module: ModuleType, constant_prefix: str
) -> None:
"""Import and test deprecated constant."""
assert getattr(module, constant_prefix + replacement.name) == replacement