Deprecate binary sensor device class constants (#105736)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Franck Nijhof <git@frenck.dev>
This commit is contained in:
parent
c64c1c8f08
commit
a4ccd6e13b
5 changed files with 302 additions and 33 deletions
|
@ -3,10 +3,11 @@ from __future__ import annotations
|
|||
|
||||
from collections.abc import Callable
|
||||
from contextlib import suppress
|
||||
from enum import Enum
|
||||
import functools
|
||||
import inspect
|
||||
import logging
|
||||
from typing import Any, ParamSpec, TypeVar
|
||||
from typing import Any, NamedTuple, ParamSpec, TypeVar
|
||||
|
||||
from homeassistant.core import HomeAssistant, async_get_hass
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
@ -153,7 +154,25 @@ def _print_deprecation_warning(
|
|||
verb: str,
|
||||
breaks_in_ha_version: str | None,
|
||||
) -> None:
|
||||
logger = logging.getLogger(obj.__module__)
|
||||
_print_deprecation_warning_internal(
|
||||
obj.__name__,
|
||||
obj.__module__,
|
||||
replacement,
|
||||
description,
|
||||
verb,
|
||||
breaks_in_ha_version,
|
||||
)
|
||||
|
||||
|
||||
def _print_deprecation_warning_internal(
|
||||
obj_name: str,
|
||||
module_name: str,
|
||||
replacement: str,
|
||||
description: str,
|
||||
verb: str,
|
||||
breaks_in_ha_version: str | None,
|
||||
) -> None:
|
||||
logger = logging.getLogger(module_name)
|
||||
if breaks_in_ha_version:
|
||||
breaks_in = f" which will be removed in HA Core {breaks_in_ha_version}"
|
||||
else:
|
||||
|
@ -163,7 +182,7 @@ def _print_deprecation_warning(
|
|||
except MissingIntegrationFrame:
|
||||
logger.warning(
|
||||
"%s is a deprecated %s%s. Use %s instead",
|
||||
obj.__name__,
|
||||
obj_name,
|
||||
description,
|
||||
breaks_in,
|
||||
replacement,
|
||||
|
@ -183,7 +202,7 @@ def _print_deprecation_warning(
|
|||
"%s was %s from %s, this is a deprecated %s%s. Use %s instead,"
|
||||
" please %s"
|
||||
),
|
||||
obj.__name__,
|
||||
obj_name,
|
||||
verb,
|
||||
integration_frame.integration,
|
||||
description,
|
||||
|
@ -194,10 +213,69 @@ def _print_deprecation_warning(
|
|||
else:
|
||||
logger.warning(
|
||||
"%s was %s from %s, this is a deprecated %s%s. Use %s instead",
|
||||
obj.__name__,
|
||||
obj_name,
|
||||
verb,
|
||||
integration_frame.integration,
|
||||
description,
|
||||
breaks_in,
|
||||
replacement,
|
||||
)
|
||||
|
||||
|
||||
class DeprecatedConstant(NamedTuple):
|
||||
"""Deprecated constant."""
|
||||
|
||||
value: Any
|
||||
replacement: str
|
||||
breaks_in_ha_version: str | None
|
||||
|
||||
|
||||
class DeprecatedConstantEnum(NamedTuple):
|
||||
"""Deprecated constant."""
|
||||
|
||||
enum: Enum
|
||||
breaks_in_ha_version: str | None
|
||||
|
||||
|
||||
def check_if_deprecated_constant(name: str, module_globals: dict[str, Any]) -> Any:
|
||||
"""Check if the not found name is a deprecated constant.
|
||||
|
||||
If it is, print a deprecation warning and return the value of the constant.
|
||||
Otherwise raise AttributeError.
|
||||
"""
|
||||
module_name = module_globals.get("__name__")
|
||||
logger = logging.getLogger(module_name)
|
||||
if (deprecated_const := module_globals.get(f"_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
|
||||
replacement = deprecated_const.replacement
|
||||
breaks_in_ha_version = deprecated_const.breaks_in_ha_version
|
||||
elif isinstance(deprecated_const, DeprecatedConstantEnum):
|
||||
value = deprecated_const.enum.value
|
||||
replacement = (
|
||||
f"{deprecated_const.enum.__class__.__name__}.{deprecated_const.enum.name}"
|
||||
)
|
||||
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)} "
|
||||
"but an instance of DeprecatedConstant or DeprecatedConstantEnum is required"
|
||||
)
|
||||
|
||||
logger.debug(msg)
|
||||
# PEP 562 -- Module __getattr__ and __dir__
|
||||
# specifies that __getattr__ should raise AttributeError if the attribute is not
|
||||
# found.
|
||||
# https://peps.python.org/pep-0562/#specification
|
||||
raise AttributeError(msg) # noqa: TRY004
|
||||
|
||||
_print_deprecation_warning_internal(
|
||||
name,
|
||||
module_name or __name__,
|
||||
replacement,
|
||||
"constant",
|
||||
"used",
|
||||
breaks_in_ha_version,
|
||||
)
|
||||
return value
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue