Description
A not entirely documented (pypa/pip#11296) but extremely useful feature of pip
since version 21.2 is that optional-dependencies
groups can depend on each other: https://hynek.me/articles/python-recursive-optional-dependencies/
For example if your package is mypkg
and it has an optional REST API which you could run with uvicorn
or some other server, which you run from the uvicorn
environment in hatch, and for which you'd like to lock dependencies, you could do this:
[project.optional-dependencies]
api = [
"fastapi"
]
uvicorn = [
"mypkg[api]",
"uvicorn",
]
[tool.hatch.envs.uvicorn]
features = [ "uvicorn" ]
type = "pip-compile"
Unfortunately this doesn't really work with pip-compile
or hatch-pip-compile
, because you will end up with this in requirements/requirements-uvicorn.txt
:
mypkg==1.0.0
# via hatch.envs.uvicorn
Oh noes! It went off to PyPI and found that yes, indeed, there is a package there already called mypkg
and proceeded to add it as a dependency to the requirements file. That's definitely not what you want!
Note that if you run pip-compile --extra uvicorn
in the environment you'll get this instead:
mypkg[api] @ file:///my/local/path/to/mypkg
# via file:///my/local/path/to/mypkg
Which is not what you want either, but definitely better than pulling in some possibly unrelated or out-of-date package from PyPI. In this case it would be easy to post-process the output of pip-compile
to remove editable installs of recursive optional dependencies, for instance.
Responsibility for fixing this might be partly in pip-tools
if there isn't a way for hatch-pip-compile
to get it to do the right thing...