How to Deprecate a PyPI Package

This post is part of a collection on Code and Computers.

Sometimes you have a package on PyPI that you want people to stop using. There's no clear guidance from PyPI on how to do this, but there are a patterns you can use to deal with new installs; this is a guide to them.

Sometimes you just need to make the snakes go away. via OldBookIllustrations

Add Deprecation Warnings

If there's code in your module that shouldn't be used, but you aren't ready to disable completely, you can use deprecation warnings like this:

import warnings

warnings.warn("deprecated", DeprecationWarning)

There's not much detail but it is covered in the official Python docs.

Just Delete It

If you log in to PyPI, you can delete individual releases or an entire project. This is a good option for a single botched release, but when removing a package you make the name available for other users and leave no information for existing users, which can cause confusion.

Provide a Redirect

If you have a package you no longer maintain, but there's a fork or alternative that users of your package should install, you can create a redirect package. This is also useful if you want to change your package's name on PyPI, or if there's a different name that's often used by mistake. sklearn is a well-known example of this approach.

The way this works is you create a minimal that requires the package you want to redirect to without a version spec.

from setuptools import setup
setup(name = "deprecated-package",

Now when people install deprecated-package pip will automatically install the latest version of maintained-package instead.

If the name you're using has no releases 0.0.0 is a fine version number, but otherwise you can bump the major version by one to catch new installs while leaving old releases unchanged.

Intentionally Fail During Install

There's no standard way to show a warning message when installing a package via PyPI. However, if a package fails to install error output is shown, so you can fail on purpose to show a message that explains what the user should do instead. skimage does this to direct users to install scikit-image. Here's what that looks like:

import sys

# XXX This if statement lets you actually build the package
if not 'sdist' in sys.argv:
    sys.exit('\n*** Please install the `scikit-image` package '
            '(instead of `skimage`) ***\n')

# normal setup(...) follows

This is effective when a package stops working completely or the upgrade path isn't straightforward.

And that's it. If you know a better way to deprecate a package or found this useful I'd love to hear about it. Ψ