To explain the context of this question, to justify why I would want to do such a thing:
I’m writing a utility library for a library written & maintained by someone else, as well as a library that uses my utility library. let’s call them my.util, my.master and my.user.
It would be nice if I could use automated tests to detect whether my.util is working correctly.
But I would prefer my util library to impose a version of my.master on my user libraries. That could make it too inflexible.
At the same time, it’s not possible to write a test (or any code for that matter) that will succeed regardless of which version of my.master is used, because the master library requires the use of an api_checksum to verify you’ve read the proper version of their documentation. (They’ve got their reasons.)
So is it possible to specify in pyproject.toml or setup.py that certain packages are necessary for some tests, but should not be imposed on all python environments that use a library? Or is there another, better approach?
You can specify optional dependencies in pyproject.toml, e.g.
[project.optional-dependencies]
test = [ # 'test' is the name of this group of optional dependencies.
"pytest",
"coverage",
]
extra = [ # You may specify multiple groups of optional dependencies.
...
The optional dependencies can be installed with pip install mypackage[test]. If the package is installed with pip install mypackage, the optional dependencies will not be installed.
Another option it to just create a pip requirements file with your
test dependencies listed in it. Name it something like
test-requirements.txt, and then set up your test frontend (tox, nox,
whatever) to automatically pip install -r test-requirements.txt
into any venv it creates. Examples:
Note that using “extras” for this is a misuse. It is a very common technique, there are virtually no drawbacks, so no one will complain, but still it is not exactly what extras are for.
Tools like Pipenv, Poetry, PDM, Hatch and so on introduced similar concepts of “dependency groups”. Those are in the process of getting merged into a common standardized specification with PEP 735. The main difference between “extras” and those upcoming “dependency groups”, is that extras are part of the packaging metadata – they are listed in the wheels – but not dependency groups.