Source code for stouputils.decorators.deprecated
# Imports
from collections.abc import Callable
from functools import wraps
from traceback import format_exc
from typing import Any, overload
from ..print.message import error, warning
from .common import get_function_name, get_wrapper_name, set_wrapper_name
from .handle_error import LogLevels
# Decorator that marks a function as deprecated
@overload
def deprecated[T](
func: Callable[..., T],
*,
message: str = "",
version: str = "",
error_log: LogLevels = LogLevels.WARNING
) -> Callable[..., T]: ...
@overload
def deprecated[T](
func: None = None,
*,
message: str = "",
version: str = "",
error_log: LogLevels = LogLevels.WARNING
) -> Callable[[Callable[..., T]], Callable[..., T]]: ...
[docs]
def deprecated[T](
func: Callable[..., T] | None = None,
*,
message: str = "",
version: str = "",
error_log: LogLevels = LogLevels.WARNING
) -> Callable[..., T] | Callable[[Callable[..., T]], Callable[..., T]]:
""" Decorator that marks a function as deprecated.
Args:
func (Callable[..., T] | None): Function to mark as deprecated
message (str): Additional message to display with the deprecation warning
version (str): Version since when the function is deprecated (e.g. "v1.2.0")
error_log (LogLevels): Log level for the deprecation warning
- :attr:`LogLevels.NONE` - None
- :attr:`LogLevels.WARNING` - Show as warning
- :attr:`LogLevels.WARNING_TRACEBACK` - Show as warning with traceback
- :attr:`LogLevels.ERROR_TRACEBACK` - Show as error with traceback
- :attr:`LogLevels.RAISE_EXCEPTION` - Raise exception
Examples:
>>> @deprecated
... def old_function():
... pass
>>> @deprecated(message="Use 'new_function()' instead", error_log=LogLevels.WARNING)
... def another_old_function():
... pass
"""
def decorator(func: Callable[..., T]) -> Callable[..., T]:
@wraps(func)
def wrapper(*args: tuple[Any, ...], **kwargs: dict[str, Any]) -> Any:
# Build deprecation message
msg: str = f"Function '{get_function_name(func)}()' is deprecated"
if version:
msg += f" since {version}"
if message:
msg += f". {message}"
# Handle deprecation warning based on log level
if error_log == LogLevels.WARNING:
warning(msg)
elif error_log == LogLevels.WARNING_TRACEBACK:
warning(f"{msg}\n{format_exc()}")
elif error_log == LogLevels.ERROR_TRACEBACK:
error(f"{msg}\n{format_exc()}", exit=True)
elif error_log == LogLevels.RAISE_EXCEPTION:
raise DeprecationWarning(msg)
# Call the original function
return func(*args, **kwargs)
set_wrapper_name(wrapper, get_wrapper_name("stouputils.decorators.deprecated", func))
return wrapper
# Handle both @deprecated and @deprecated(message=..., error_log=...)
if func is None:
return decorator
return decorator(func)