How to deprecate a feature

Since the 4.0.0 release, deprecation happens on a per-release basis. A functionality can be marked as deprecated using ~yt._maintenance.deprecation.issue_deprecation_warning, which takes a warning message and two version numbers, indicating the earliest release deprecating the feature and the one in which it will be removed completely.

The message should indicate a viable alternative to replace the deprecated feature at the user level. since and removal arguments should indicate in which release something was first deprecated, and when it’s expected to be removed. While since is required, removal is optional.

Here’s an example call.

If a whole function or class is marked as deprecated, it should be removed from doc/source/reference/api/api.rst.

Deprecating Derived Fields

Occasionally, one may want to deprecate a derived field in yt, normally because naming conventions for fields have changed, or simply because a field has outlived its usefulness. There are two ways to mark fields as deprecated in yt.

The first way is if you simply want to mark a specific derived field as deprecated. In that case, you call add_deprecated_field():

def _cylindrical_radial_absolute(field, data):
    """This field is deprecated and will be removed in a future version"""
    return np.abs(data[ftype, f"{basename}_cylindrical_radius"])


registry.add_deprecated_field(
    (ftype, f"cylindrical_radial_{basename}_absolute"),
    sampling_type="local",
    function=_cylindrical_radial_absolute,
    since="4.0",
    removal="4.1.0",
    units=field_units,
    validators=[ValidateParameter("normal")],
)

Note that the signature for add_deprecated_field() is the same as add_field(), with the exception of the since and removal arguments which indicate in what version the field was deprecated and in what version it will be removed. The effect is to add a warning to the logger when the field is first used:

import yt

ds = yt.load("GasSloshing/sloshing_nomag2_hdf5_plt_cnt_0100")
sp = ds.sphere("c", (100.0, "kpc"))
print(sp["gas", "cylindrical_radial_velocity_absolute"])
yt : [WARNING  ] 2021-03-09 16:30:47,460 The Derived Field
('gas', 'cylindrical_radial_velocity_absolute') is deprecated
as of yt v4.0.0 and will be removed in yt v4.1.0

The second way to deprecate a derived field is to take an existing field definition and change its name. In order to mark the original name as deprecated, use the alias() method and pass the since and removal arguments (see above) as a tuple in the deprecate keyword argument:

registry.alias(
    (ftype, "kinetic_energy"),
    (ftype, "kinetic_energy_density"),
    deprecate=("4.0.0", "4.1.0"),
)

Note that the old field name which is to be deprecated goes first, and the new, replacement field name goes second. In this case, the log message reports to the user what field they should use:

print(sp["gas", "kinetic_energy"])
yt : [WARNING  ] 2021-03-09 16:29:12,911 The Derived Field
('gas', 'kinetic_energy') is deprecated as of yt v4.0.0 and will be removed
in yt v4.1.0 Use ('gas', 'kinetic_energy_density') instead.

In most cases, the since and removal arguments should have a delta of one minor release, and that should be the minimum value. However, the developer is free to use their judgment about whether or not the delta should be multiple minor releases if the field has a long provenance.