Deprecations#

Changed in version 0.2: If you use this module, ensure you pin this version in the setup.py file (ploomber-core>=0.2)

The deprecated module contains utilities for marking code as deprecated, renaming and changing default values.

Important

When using this module, ensure you add unit tests, click here to see sample tests.

Tip

When introducing changes, we add some directives to the docstrings, consider adding them to the tutorials that use them as well.

Function deprecated#

To deprecate a function, use deprecated.function, and add the .. deprecated:: directive:

from ploomber_core import deprecated


@deprecated.function(deprecated_in="0.1", remove_in="0.2")
def add(x, y):
    """
    Notes
    -----
    .. deprecated:: 0.1
        ``add`` is deprecated, will be removed in version 0.2
    """
    return x + y

When a use calls the function, a warning is displayed:

add(21, 21)
/home/docs/checkouts/readthedocs.org/user_builds/ploomber-core/checkouts/latest/src/ploomber_core/deprecated.py:105: PloomberDeprecationWarning: Function 'add' was deprecated in version 0.1. 'add' will be removed in version 0.2. If you need help migrating, contact us: https://ploomber.io/community
  warnings.warn(
42

Function renamed#

If the function will not disappear but be renamed, pass name_new="new_name".

Furthermore, add the following directives to the docstrings (with the appropriate message):

  • .. versionadded:: {deprecated_in}: to the new function

  • .. deprecated:: {deprecated_in}: to the old function

from ploomber_core import deprecated


def sum(x, y):
    """
    Notes
    -----
    .. versionadded:: 0.1
        ``sum`` was renamed from ``add``. ``add`` removed in version 0.2
    """
    return x + y


@deprecated.function(deprecated_in="0.1", remove_in="0.2", new_name="sum")
def add(x, y):
    """
    Notes
    -----
    .. deprecated:: 0.1
        ``add`` renamed to ``sum``. ``add`` will be removed in version 0.2
    """
    return x + y

Using the old function shows a warning:

add(21, 21)
/home/docs/checkouts/readthedocs.org/user_builds/ploomber-core/checkouts/latest/src/ploomber_core/deprecated.py:105: PloomberDeprecationWarning: Function 'add' was renamed to 'sum' in version 0.1. 'add' will be removed in version 0.2. If you need help migrating, contact us: https://ploomber.io/community
  warnings.warn(
42

The new one doesn’t show warnings:

sum(21, 21)
42

Custom message#

If you need to customize the message, use custom_mesasge.

Furthermore, add the following directives to the docstrings (with the appropriate message):

  • .. versionadded:: {deprecated_in}: to the new function (include the custom message)

  • .. deprecated:: {deprecated_in}: to the old function

from ploomber_core import deprecated


def sum(a, b):
    """
    Notes
    -----
    .. versionadded:: 0.1
        ``sum`` was renamed from ``add``, and parameters renamed to ``a``, and ``b``.
        ``add`` removed in version 0.2
    """
    return a + b


@deprecated.function(
    deprecated_in="0.1",
    remove_in="0.3",
    new_name="sum",
    custom_message="Params renamed to a and b",
)
def add(x, y):
    """
    Notes
    -----
    .. deprecated:: 0.1
        ``add`` renamed to ``sum``. ``add`` will be removed in version 0.2
    """
    return x + y


add(21, 21)
/home/docs/checkouts/readthedocs.org/user_builds/ploomber-core/checkouts/latest/src/ploomber_core/deprecated.py:105: PloomberDeprecationWarning: Function 'add' was renamed to 'sum' in version 0.1. 'add' will be removed in version 0.3. Params renamed to a and b. If you need help migrating, contact us: https://ploomber.io/community
  warnings.warn(
42

Method deprecated#

To deprecate a method in a class, use deprecated.method, also add the .. deprecated:: directive.

from ploomber_core import deprecated


class SomeClass:
    @deprecated.method(deprecated_in="0.1", remove_in="0.3")
    def do_something(self):
        """
        Notes
        -----
        .. deprecated:: 0.1
            ``do_something`` is deprecated, and it will be removed in version 0.2
        """
        return 42


obj = SomeClass()

# calling a deprecated method shows a warning
obj.do_something()
/home/docs/checkouts/readthedocs.org/user_builds/ploomber-core/checkouts/latest/src/ploomber_core/deprecated.py:132: PloomberDeprecationWarning: 'do_something' from 'SomeClass' was deprecated in version 0.1. 'do_something' will be removed in version 0.3. If you need help migrating, contact us: https://ploomber.io/community
  warnings.warn(
42

Method renamed#

If a method is renamed, use deprecated.method.

Furthermore, add the following directives to the docstrings (with the appropriate message):

  • .. versionadded:: {deprecated_in}: to the new method

  • .. deprecated:: {deprecated_in}: to the old method

from ploomber_core import deprecated


class SomeClass:
    @deprecated.method(deprecated_in="0.1", remove_in="0.2", new_name="something_else")
    def do_something(self, *args, **kwargs):
        """
        Notes
        -----
        .. deprecated:: 0.1
            ``do_something`` renamed to ``do_something_else``. ``do_something`` will
            be removed in version 0.2
        """
        return self.do_something_else(*args, **kwargs)

    def do_something_else(self, a, b):
        """
        Notes
        -----
        .. versionadded:: 0.1
            ``do_something_else`` was renamed from ``do_something``. ``do_something``
            removed in version 0.2
        """
        return a + b


obj = SomeClass()
obj.do_something(1, 1)
/home/docs/checkouts/readthedocs.org/user_builds/ploomber-core/checkouts/latest/src/ploomber_core/deprecated.py:132: PloomberDeprecationWarning: 'do_something' from 'SomeClass' was renamed to 'something_else' in version 0.1. 'do_something' will be removed in version 0.2. If you need help migrating, contact us: https://ploomber.io/community
  warnings.warn(
2

Custom message#

If the method was renamed and any other behavior changed, use custom_message.

Furthermore, add the following directives to the docstrings (with the appropriate message):

  • .. versionadded:: {deprecated_in}: to the new method (include custom message)

  • .. deprecated:: {deprecated_in}: to the old method

from ploomber_core import deprecated


class SomeClass:
    @deprecated.method(
        deprecated_in="0.1",
        remove_in="0.2",
        new_name="something_else",
        custom_message="Parameters changed from x, y to a, b",
    )
    def do_something(self, x, y):
        """
        Notes
        -----
        .. deprecated:: 0.1
            ``do_something`` renamed to ``do_something_else``. ``do_something``
            will be removed in version 0.2
        """
        return self.do_something_else(x, y)

    def do_something_else(self, a, b):
        """
        Notes
        -----
        .. versionadded:: 0.1
            ``do_something_else`` was renamed from ``do_something``. Parameters
            changed from x, y to a, b ``do_something`` removed in version 0.2
        """
        return a + b


obj = SomeClass()
obj.do_something(1, 1)
/home/docs/checkouts/readthedocs.org/user_builds/ploomber-core/checkouts/latest/src/ploomber_core/deprecated.py:132: PloomberDeprecationWarning: 'do_something' from 'SomeClass' was renamed to 'something_else' in version 0.1. 'do_something' will be removed in version 0.2. Parameters changed from x, y to a, b. If you need help migrating, contact us: https://ploomber.io/community
  warnings.warn(
2

Attribute deprecated#

Use deprecated.method to deprecate attributes, and add the .. deprecated:: {deprecated_in} directive:

from ploomber_core import deprecated


class SomeClass:
    @property
    @deprecated.method(deprecated_in="0.1", remove_in="0.2")
    def some_attribute(self):
        """

        Notes
        -----
        .. deprecated:: 0.1
            ``some_attribute`` is deprecated, will be removed in version 0.2
        """
        return 42


obj = SomeClass()

obj.some_attribute
/home/docs/checkouts/readthedocs.org/user_builds/ploomber-core/checkouts/latest/src/ploomber_core/deprecated.py:132: PloomberDeprecationWarning: 'some_attribute' from 'SomeClass' was deprecated in version 0.1. 'some_attribute' will be removed in version 0.2. If you need help migrating, contact us: https://ploomber.io/community
  warnings.warn(
42

Attribute renamed#

If an attribute is renamed, use deprecated.method and pass the renamed argument.

Furthermore, add the following directives to the docstrings (with the appropriate message):

  • .. versionadded:: {deprecated_in}: to the new attribute

  • .. deprecated:: {deprecated_in}: to the old attribute

from ploomber_core import deprecated


class SomeClass:
    @property
    @deprecated.method(deprecated_in="0.1", remove_in="0.2", new_name="new_attribute")
    def some_attribute(self):
        """
        Notes
        -----
        .. deprecated:: 0.1
            ``some_attribute`` renamed to ``new_attribute``. ``some_attribute``
            will be removed in version 0.2
        """
        return self.new_attribute

    @property
    def new_attribute(self):
        """
        Notes
        -----
        .. versionadded:: 0.1
            ``new_attribute`` was renamed from ``some_attribute``. ``some_attribute``
            removed in version 0.2
        """
        return 42


obj = SomeClass()

obj.some_attribute
/home/docs/checkouts/readthedocs.org/user_builds/ploomber-core/checkouts/latest/src/ploomber_core/deprecated.py:132: PloomberDeprecationWarning: 'some_attribute' from 'SomeClass' was renamed to 'new_attribute' in version 0.1. 'some_attribute' will be removed in version 0.2. If you need help migrating, contact us: https://ploomber.io/community
  warnings.warn(
42

Parameter deprecated#

If a function/method argument is deprecated, set the default value "deprecated" and use the following recipe (remember to add the .. deprecated:: {deprecated_in} directive):

from ploomber_core import deprecated


def example_function(k="deprecated"):
    """
    Notes
    -----
    .. deprecated:: 0.1
        ``k`` argument is deprecated, will be removed in version 0.2
    """
    deprecated.parameter_deprecated(
        deprecated_in="0.1", remove_in="0.3", name_old="k", value_passed=k
    )

This will have no effect on calls that do not use such argument:

example_function()

But will warn users if they are passing such parameter:

example_function(k=1)
/home/docs/checkouts/readthedocs.org/user_builds/ploomber-core/checkouts/latest/src/ploomber_core/deprecated.py:49: PloomberDeprecationWarning: 'k' was deprecated in version 0.1. 'k' will be removed in 0.3. If you need help migrating, contact us: https://ploomber.io/community
  warnings.warn(

Parameter renamed#

If a parameter is renamed, follow these steps:

  • Add the new parameter in the same position as the old one

  • Set the old default value in the new parameter (if any)

  • Move the old parameter to the end

  • Set the default value of the old parameter to "deprecated"

  • Add the .. deprecated:: {removed_in} directive

Then, call deprecated.parameter_renamed. Example:

from ploomber_core import deprecated


def example_function(n_clusters=8, another=42, k="deprecated"):
    """

    Notes
    -----
    .. deprecated:: 0.1
        ``k`` was renamed to ``n_clusters``. ``k`` removed in 0.2
    """
    n_clusters = deprecated.parameter_renamed(
        deprecated_in="0.1",
        remove_in="0.2",
        old_name="k",
        old_value=k,
        new_name="n_clusters",
        new_value=n_clusters,
    )

    print(f"n_clusters={n_clusters!r}, k={k!r}")

    # ignore k and use n_clusters in the body of the function

If the user is not using the deprecated parameter (k), no warning is shown:

example_function()
n_clusters=8, k='deprecated'

If a user passes the deprecated argument (k), a warning is displayed and the value is assigned to the new argument n_clusters:

example_function(k=10)
n_clusters=10, k=10
/home/docs/checkouts/readthedocs.org/user_builds/ploomber-core/checkouts/latest/src/ploomber_core/deprecated.py:29: PloomberDeprecationWarning: 'k' was renamed to 'n_clusters' in version 0.1. 'k' will be removed in 0.2. If you need help migrating, contact us: https://ploomber.io/community
  warnings.warn(

Once the user migrates to the new one, no warning is displayed:

example_function(n_clusters=10)
n_clusters=10, k='deprecated'

Parameter with new default value#

If a default value is changed, set it to "warn", and use the .. versionchanged:: {removed_in} directive:

from ploomber_core import deprecated


def example_function(n_clusters="warn"):
    """

    Notes
    -----
    .. versionchanged:: 0.2
        'n_clusters' default value changed from 5 to 10
    """
    n_clusters = deprecated.parameter_default_changed(
        "0.2", name="n_clusters", old_default=5, new_default=10, value=n_clusters
    )

    print(f"n_clusters is {n_clusters}")

Functions that do not rely on the default value won’t show any warning:

example_function(n_clusters=3)
n_clusters is 3

But if a user relies on the default value, the old default value is used but a warning is shown:

example_function()
n_clusters is 5
/home/docs/checkouts/readthedocs.org/user_builds/ploomber-core/checkouts/latest/src/ploomber_core/deprecated.py:76: PloomberDeprecationWarning: The default value of n_clusters will change from 5 to 10 in 0.2.
  warnings.warn(

Parameter renamed and changed#

If the parameter is renamed and behavior changes:

  • Add the new parameter in the same position as the old one

  • Set the old default value in the new parameter (if any)

  • Move the old parameter to the end

  • Set the default value of the old parameter to "deprecated"

  • Add the .. deprecated:: {removed_in} directive

  • Include a message with the new default

from ploomber_core import deprecated


def example_function(n_clusters=10, another=42, k="deprecated"):
    """

    Notes
    -----
    .. deprecated:: 0.1
        ``k`` was renamed to ``n_clusters``. ``k`` removed in 0.2. Default n_clusters
        is 10
    """
    n_clusters = deprecated.parameter_renamed(
        "0.1",
        "0.2",
        old_name="k",
        old_value=k,
        new_name="n_clusters",
        new_value=n_clusters,
        custom_message="Default n_clusters is 10",
    )

    print(f"n_clusters={n_clusters!r}, k={k!r}")

    # ignore k and use n_clusters in the body of the function
example_function(k=10)
n_clusters=10, k=10
/home/docs/checkouts/readthedocs.org/user_builds/ploomber-core/checkouts/latest/src/ploomber_core/deprecated.py:29: PloomberDeprecationWarning: 'k' was renamed to 'n_clusters' in version 0.1. 'k' will be removed in 0.2. Default n_clusters is 10. If you need help migrating, contact us: https://ploomber.io/community
  warnings.warn(

Deprecation warning with logger#

deprecation_warning(telemetry, message) is designed to facilitate the logging of deprecated features in your codebase. It throws warning messages and log the information about the message, the current package name and version.

We need to provide telemetry instance and the message string:

Example#

In the jupysql project, we may import the existing telemetry instance and pass to deprecation_warning

from sql.telemetry import telemetry

def some_random_func():
    deprecation_warning(telemetry, "you are using old feature")

some_random_func()

The message you are using old feature and jupysql package info will be logged

Reference#

This is based on sklearn’s guidelines.