Deprecations#

Conda abides by the Deprecation Schedule defined in CEP-9. To help make deprecations as much of a no-brainer as possible we provide several helper decorators and functions to facilitate the correct deprecation process.

Functions, Methods, Properties, and Classes#

Warning

To deprecate Enums treat them like constants (see Constants and Enums).

The simplest use case is for deprecating any function, method, or property:

Example file, foo.py.#
from conda.deprecations import deprecated


@deprecated("23.9", "24.3")
def bar():
    ...
Example invocation.#
>>> import foo
>>> foo.bar()
<stdin>:1: PendingDeprecationWarning: foo.bar is pending deprecation and will be removed in 24.3.

As a minimum we must always specify two versions:

  1. the future deprecation release in which the function, method, or property will be marked as deprecated; prior to that the feature will show up as pending deprecation (which we treat as a commenting period), and

  2. the subsequent deprecation release in which the function, method, or property will be removed from the code base.

Additionally, you may provide an addendum to inform the user what they should do instead:

Example file, foo.py.#
from conda.deprecations import deprecated


@deprecated("23.9", "24.3", addendum="Use `qux` instead.")
def bar():
    ...
Example invocation.#
>>> import foo
>>> foo.bar()
<stdin>:1: PendingDeprecationWarning: foo.bar is pending deprecation and will be removed in 24.3. Use `qux` instead.

Keyword Arguments#

Warning

Deprecating or renaming a positional argument is unnecessarily complicated and is not supported. Instead, it is recommended to either (1) devise a custom way of detecting usage of a deprecated positional argument (e.g., type checking) and use the conda.deprecations.deprecated.topic function (see Topics) or (2) deprecate the function/method itself and define a new function/method without the deprecated argument.

Similarly to deprecating a function or method it is common to deprecate a keyword argument:

Example file, foo.py.#
from conda.deprecations import deprecated


# prior implementation
# def bar(is_true=True):
#     ...


@deprecated.argument("23.9", "24.3", "is_true")
def bar():
    ...
Example invocation.#
>>> import foo
>>> foo.bar(is_true=True)
<stdin>:1: PendingDeprecationWarning: foo.bar(is_true) is pending deprecation and will be removed in 24.3.

Or to rename the keyword argument:

Example file, foo.py.#
from conda.deprecations import deprecated


# prior implementation
# def bar(is_true=True):
#     ...


@deprecated.argument("23.9", "24.3", "is_true", rename="enabled")
def bar(enabled=True):
    ...
Example invocation.#
>>> import foo
>>> foo.bar(is_true=True)
<stdin>:1: PendingDeprecationWarning: foo.bar(is_true) is pending deprecation and will be removed in 24.3. Use 'enabled' instead.

argparse.Action#

Occasionally, there is a need to deprecate CLI arguments. For this, we provide a helper function to monkeypatch any argparse.Action:

Example file, foo.py.#
import argparse
from conda.deprecations import deprecated

parser = argparse.ArgumentParser()
parser.add_argument(
    "--force",
    dest="yes",
    action=deprecated.action(
        "23.9",
        "24.3",
        argparse._StoreTrueAction,
        addendum="Use `--yes` instead.",
    ),
    default=False,
)
parser.parse_args()
python foo.py --force
foo.py:16: PendingDeprecationWarning: `--force` is pending deprecation and will be removed in 24.3. Use `--yes` instead.

Constants and Enums#

We also offer a way to deprecate global variables or constants:

Example file, foo.py.#
from conda.deprecations import deprecated

deprecated.constant("23.9", "24.3", "ULTIMATE_CONSTANT", 42)
Example invocation.#
>>> import foo
>>> foo.ULTIMATE_CONSTANT
<stdin>:1: PendingDeprecationWarning: foo.ULTIMATE_CONSTANT is pending deprecation and will be removed in 24.3.

Enums work similarly:

Example file, foo.py.#
from enum import Enum
from conda.deprecations import deprecated

class Bar(Enum):
    ULTIMATE_CONSTANT = 42

deprecated.constant("23.9", "24.3", "Bar", Bar)
del Bar
Example invocation.#
>>> from foo import Bar
<stdin>:1: PendingDeprecationWarning: foo.Bar is pending deprecation and will be removed in 24.3.

Note

Constants deprecation relies on the module’s __getattr__ introduced in PEP-562.

Modules#

Entire modules can be also be deprecated:

Example file, foo.py.#
from conda.deprecations import deprecated

deprecated.module("23.9", "24.3")
Example invocation.#
>>> import foo
<stdin>:1: PendingDeprecationWarning: foo is pending deprecation and will be removed in 24.3.

Topics#

Finally, there are a multitude of other ways in which code may be run that also needs to be deprecated. To this end we offer a general purpose deprecation function:

Example file, foo.py.#
from conda.deprecations import deprecated

def bar(...):
    # some logic

    if ...:
        deprecated.topic("23.9", "24.3", topic="The <TOPIC>")

    # some more logic
Example invocation.#
>>> import foo
>>> foo.bar(...)
<stdin>:1: PendingDeprecationWarning: The <TOPIC> is pending deprecation and will be removed in 24.3.