Minor improvements of deprecation helper (#104980)

This commit is contained in:
Erik Montnemery 2023-12-04 10:47:49 +01:00 committed by Franck Nijhof
parent 56e325a2b1
commit fd4a05fc7a
No known key found for this signature in database
GPG key ID: D62583BA8AB11CA3
2 changed files with 32 additions and 16 deletions

View file

@ -99,7 +99,11 @@ def get_deprecated(
def deprecated_class( def deprecated_class(
replacement: str, replacement: str,
) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]:
"""Mark class as deprecated and provide a replacement class to be used instead.""" """Mark class as deprecated and provide a replacement class to be used instead.
If the deprecated function was called from a custom integration, ask the user to
report an issue.
"""
def deprecated_decorator(cls: Callable[_P, _R]) -> Callable[_P, _R]: def deprecated_decorator(cls: Callable[_P, _R]) -> Callable[_P, _R]:
"""Decorate class as deprecated.""" """Decorate class as deprecated."""
@ -107,7 +111,7 @@ def deprecated_class(
@functools.wraps(cls) @functools.wraps(cls)
def deprecated_cls(*args: _P.args, **kwargs: _P.kwargs) -> _R: def deprecated_cls(*args: _P.args, **kwargs: _P.kwargs) -> _R:
"""Wrap for the original class.""" """Wrap for the original class."""
_print_deprecation_warning(cls, replacement, "class") _print_deprecation_warning(cls, replacement, "class", "instantiated")
return cls(*args, **kwargs) return cls(*args, **kwargs)
return deprecated_cls return deprecated_cls
@ -118,7 +122,11 @@ def deprecated_class(
def deprecated_function( def deprecated_function(
replacement: str, replacement: str,
) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]:
"""Mark function as deprecated and provide a replacement to be used instead.""" """Mark function as deprecated and provide a replacement to be used instead.
If the deprecated function was called from a custom integration, ask the user to
report an issue.
"""
def deprecated_decorator(func: Callable[_P, _R]) -> Callable[_P, _R]: def deprecated_decorator(func: Callable[_P, _R]) -> Callable[_P, _R]:
"""Decorate function as deprecated.""" """Decorate function as deprecated."""
@ -126,7 +134,7 @@ def deprecated_function(
@functools.wraps(func) @functools.wraps(func)
def deprecated_func(*args: _P.args, **kwargs: _P.kwargs) -> _R: def deprecated_func(*args: _P.args, **kwargs: _P.kwargs) -> _R:
"""Wrap for the original function.""" """Wrap for the original function."""
_print_deprecation_warning(func, replacement, "function") _print_deprecation_warning(func, replacement, "function", "called")
return func(*args, **kwargs) return func(*args, **kwargs)
return deprecated_func return deprecated_func
@ -134,10 +142,23 @@ def deprecated_function(
return deprecated_decorator return deprecated_decorator
def _print_deprecation_warning(obj: Any, replacement: str, description: str) -> None: def _print_deprecation_warning(
obj: Any,
replacement: str,
description: str,
verb: str,
) -> None:
logger = logging.getLogger(obj.__module__) logger = logging.getLogger(obj.__module__)
try: try:
integration_frame = get_integration_frame() integration_frame = get_integration_frame()
except MissingIntegrationFrame:
logger.warning(
"%s is a deprecated %s. Use %s instead",
obj.__name__,
description,
replacement,
)
else:
if integration_frame.custom_integration: if integration_frame.custom_integration:
hass: HomeAssistant | None = None hass: HomeAssistant | None = None
with suppress(HomeAssistantError): with suppress(HomeAssistantError):
@ -149,10 +170,11 @@ def _print_deprecation_warning(obj: Any, replacement: str, description: str) ->
) )
logger.warning( logger.warning(
( (
"%s was called from %s, this is a deprecated %s. Use %s instead," "%s was %s from %s, this is a deprecated %s. Use %s instead,"
" please %s" " please %s"
), ),
obj.__name__, obj.__name__,
verb,
integration_frame.integration, integration_frame.integration,
description, description,
replacement, replacement,
@ -160,16 +182,10 @@ def _print_deprecation_warning(obj: Any, replacement: str, description: str) ->
) )
else: else:
logger.warning( logger.warning(
"%s was called from %s, this is a deprecated %s. Use %s instead", "%s was %s from %s, this is a deprecated %s. Use %s instead",
obj.__name__, obj.__name__,
verb,
integration_frame.integration, integration_frame.integration,
description, description,
replacement, replacement,
) )
except MissingIntegrationFrame:
logger.warning(
"%s is a deprecated %s. Use %s instead",
obj.__name__,
description,
replacement,
)

View file

@ -636,8 +636,8 @@ async def test_deprecated_loaders(
): ):
loader_class() loader_class()
assert ( assert (
f"{loader_class.__name__} was called from hue, this is a deprecated class. " f"{loader_class.__name__} was instantiated from hue, this is a deprecated "
f"Use {new_class} instead" f"class. Use {new_class} instead"
) in caplog.text ) in caplog.text