Skip to content

Deprecation Policy & Helpers

skyulf.core.deprecation provides a small, consistent way to retire public symbols without breaking callers overnight.

Policy

A public symbol marked deprecated in minor X.Y keeps working through X.(Y+1) and may be removed in X.(Y+2). Deprecating a symbol emits a DeprecationWarning — silent by default, but visible under python -W default and in test suites (pytest shows them in its warnings summary).

@deprecated — for callables

Wrap any function or method. Calling it emits a standardised warning while the original behaviour and return value are preserved.

from skyulf.core.deprecation import deprecated


@deprecated(since="0.5", removed_in="0.7", replacement="new_transform")
def old_transform(df):
    return new_transform(df)

Calling old_transform(df) emits:

DeprecationWarning: 'old_transform' is deprecated since v0.5 and is scheduled
for removal in v0.7. Use 'new_transform' instead.

warn_deprecated — for everything else

Use it directly when a decorator cannot wrap the thing being deprecated — for example a config key, an enum value, or a positional argument.

from skyulf.core.deprecation import warn_deprecated


def fit(self, df, config):
    if "old_key" in config:
        warn_deprecated(
            "config key 'old_key'",
            since="0.5",
            removed_in="0.7",
            replacement="new_key",
        )
        config["new_key"] = config.pop("old_key")
    ...

Verifying deprecations in tests

import pytest


def test_old_transform_warns():
    with pytest.warns(DeprecationWarning):
        old_transform(df)

API reference

skyulf.core.deprecation

Deprecation policy and helpers for skyulf-core.

Policy: a public symbol marked deprecated in minor X.Y keeps working through X.(Y+1) and may be removed in X.(Y+2). Deprecating a symbol emits a :class:DeprecationWarning (so it is silent by default but visible under python -W default and in test suites) describing the replacement and the version in which removal is planned.

Usage

from skyulf.core.deprecation import deprecated @deprecated(since="0.2", removed_in="0.4", replacement="new_func") ... def old_func(): ... ...

deprecated(*, since=None, removed_in=None, replacement=None)

Decorator that marks a callable as deprecated.

Wraps the callable so that calling it emits a :class:DeprecationWarning built from since / removed_in / replacement. The original behaviour and return value are preserved.

Source code in skyulf-core/skyulf/core/deprecation.py
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
def deprecated(
    *,
    since: Optional[str] = None,
    removed_in: Optional[str] = None,
    replacement: Optional[str] = None,
) -> Callable[[_F], _F]:
    """Decorator that marks a callable as deprecated.

    Wraps the callable so that calling it emits a :class:`DeprecationWarning`
    built from ``since`` / ``removed_in`` / ``replacement``. The original
    behaviour and return value are preserved.
    """

    def decorator(func: _F) -> _F:
        message = _build_message(
            getattr(func, "__qualname__", getattr(func, "__name__", "callable")),
            since,
            removed_in,
            replacement,
        )

        @functools.wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            warnings.warn(message, category=DeprecationWarning, stacklevel=2)
            return func(*args, **kwargs)

        return cast(_F, wrapper)

    return decorator

warn_deprecated(name, *, since=None, removed_in=None, replacement=None, stacklevel=2)

Emit a standardised DeprecationWarning for name.

Use directly for deprecating things a decorator can't wrap (e.g. a config key or a positional argument).

Source code in skyulf-core/skyulf/core/deprecation.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
def warn_deprecated(
    name: str,
    *,
    since: Optional[str] = None,
    removed_in: Optional[str] = None,
    replacement: Optional[str] = None,
    stacklevel: int = 2,
) -> None:
    """Emit a standardised ``DeprecationWarning`` for ``name``.

    Use directly for deprecating things a decorator can't wrap (e.g. a config
    key or a positional argument).
    """
    warnings.warn(
        _build_message(name, since, removed_in, replacement),
        category=DeprecationWarning,
        stacklevel=stacklevel,
    )