Deprecation of package extras
It’s a common case for the package to rely on extras syntax to optionally install packages which are not required for the main functionality. For example, pip install 'black[jupyter]'
allows you to use black formatting utility with your Jupyter notebooks, but otherwise there is no need to bring new dependencies into your virtual environment especially if they are heavy to install.
With that premise sometimes you want to either completely deprecate extras or refactor them into a different name. As an aware package maintainer you should release an intermediate version with the warning about deprecation. That’s the case where you might want to consider adding package-extras package. It’s a simple hack that allows you to emit a warning only when package has been installed through extras syntax invocation.
How to use useless package
First step is to update your project’s configuration file pyproject.toml
and add package-extras
into the section we want to deprecate (databases
in the example below).
1 | [tool.poetry.dependencies] |
Same example as above, but for the case when you still maintain setup.py
file for your project.
1 | from setuptools import setup |
Then add this logic to your entrypoint or top-level __init__.py
file to raise deprecation warning
1 | import warnings |
You might wonder why don’t we just import some package from the list and make assertion based on its presence. First of all this package might be installed by some other dependency or just be present in your virtual environment. Secondly, you might end up with a huge import block in case you decided to check every package that belongs to extras (even this wouldn’t guarantee mitigation of the first case). In contrast, package_extras
is definitely present in the environment only if you have invoked installation using extra syntax, so this approach is the most resillient one.
Opposite scenario
There is an opposite case where you want to make sure that some extras were installed. Imagine your CI uses a lot of tools to bump version, update release notes, publish release to artifactory and upload wheel to the internal S3 bucket. You don’t need this tools neither for development, nor to be packaged by default with your project.
1 | [tool.poetry.dependencies] |
In the same time you might rely on the cli entrypoint that invokes all the mentioned steps within its code. So this check can warn you about missing pip install test_package[ci]
step or just fail fast after this step instead of having unexpected import error somewhere in the middle of your pipeline.
1 | import warnings |
NOTE:
ImportWarning
warnings are disabled by default, so if you want your users to actually see the error during the import it is better to useRuntimeWarning
instead. Alternatively, you can pass extra command line flagpython -Walways
on invocation.