diff options
Diffstat (limited to 'venv/lib/python3.11/site-packages/litestar/utils/deprecation.py')
-rw-r--r-- | venv/lib/python3.11/site-packages/litestar/utils/deprecation.py | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/venv/lib/python3.11/site-packages/litestar/utils/deprecation.py b/venv/lib/python3.11/site-packages/litestar/utils/deprecation.py new file mode 100644 index 0000000..b1b8725 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/utils/deprecation.py @@ -0,0 +1,111 @@ +from __future__ import annotations + +import inspect +from functools import wraps +from typing import Callable, Literal, TypeVar +from warnings import warn + +from typing_extensions import ParamSpec + +__all__ = ("deprecated", "warn_deprecation") + + +T = TypeVar("T") +P = ParamSpec("P") +DeprecatedKind = Literal["function", "method", "classmethod", "attribute", "property", "class", "parameter", "import"] + + +def warn_deprecation( + version: str, + deprecated_name: str, + kind: DeprecatedKind, + *, + removal_in: str | None = None, + alternative: str | None = None, + info: str | None = None, + pending: bool = False, +) -> None: + """Warn about a call to a (soon to be) deprecated function. + + Args: + version: Litestar version where the deprecation will occur + deprecated_name: Name of the deprecated function + removal_in: Litestar version where the deprecated function will be removed + alternative: Name of a function that should be used instead + info: Additional information + pending: Use ``PendingDeprecationWarning`` instead of ``DeprecationWarning`` + kind: Type of the deprecated thing + """ + parts = [] + + if kind == "import": + access_type = "Import of" + elif kind in {"function", "method"}: + access_type = "Call to" + else: + access_type = "Use of" + + if pending: + parts.append(f"{access_type} {kind} awaiting deprecation {deprecated_name!r}") + else: + parts.append(f"{access_type} deprecated {kind} {deprecated_name!r}") + + parts.extend( + ( + f"Deprecated in litestar {version}", + f"This {kind} will be removed in {removal_in or 'the next major version'}", + ) + ) + if alternative: + parts.append(f"Use {alternative!r} instead") + + if info: + parts.append(info) + + text = ". ".join(parts) + warning_class = PendingDeprecationWarning if pending else DeprecationWarning + + warn(text, warning_class, stacklevel=2) + + +def deprecated( + version: str, + *, + removal_in: str | None = None, + alternative: str | None = None, + info: str | None = None, + pending: bool = False, + kind: Literal["function", "method", "classmethod", "property"] | None = None, +) -> Callable[[Callable[P, T]], Callable[P, T]]: + """Create a decorator wrapping a function, method or property with a warning call about a (pending) deprecation. + + Args: + version: Litestar version where the deprecation will occur + removal_in: Litestar version where the deprecated function will be removed + alternative: Name of a function that should be used instead + info: Additional information + pending: Use ``PendingDeprecationWarning`` instead of ``DeprecationWarning`` + kind: Type of the deprecated callable. If ``None``, will use ``inspect`` to figure + out if it's a function or method + + Returns: + A decorator wrapping the function call with a warning + """ + + def decorator(func: Callable[P, T]) -> Callable[P, T]: + @wraps(func) + def wrapped(*args: P.args, **kwargs: P.kwargs) -> T: + warn_deprecation( + version=version, + deprecated_name=func.__name__, + info=info, + alternative=alternative, + pending=pending, + removal_in=removal_in, + kind=kind or ("method" if inspect.ismethod(func) else "function"), + ) + return func(*args, **kwargs) + + return wrapped + + return decorator |