Install requirements from pyproject
closes #11440 ?
This is more of a proof of concept, I can try improving it and adding tests if this approach is deemed to be ok.
Since actual --only-deps option opens up a lot of rabbit holes (when installing anything other than .) and installing only dependencies of some remote package for example doesn't seem to be useful to me, this PR just handles dependencies from pyproject.toml in -r, e.g. pip install -r pyproject.toml.
I guess this is technically a breaking change, but I don't know what kind of person keeps their requirements in non-toml format in a file named pyproject.toml. -r pyproject.toml is also apparently what uv already does.
Only main dependencies (the ones in project.dependencies) are handled (for now?). Trying to do install -r pyproject.toml on pyproject with dynamic dependencies results in an error.
As is, I believe this PR is enough to address at least my use case for this: it allows caching dependency layers in docker easily, without additional tools.
Hey @ja2142 thanks for opening a PR against pip.
There are some important design questions to consider on if this is the right choice of design from both a UX perspective (same flag or a different flag as -r?) and a technical perspective (should pip parse the dependencies or request them from the build backend?).
Please be aware all maintainers are currently volunteers, so we don't tend to have a lot of time to spend on pip, and it may be quite some time before any of weighs in on this.
Thanks for a response.
I lean slightly towards -r pyproject.toml, it's short, seems fairly self explanatory to me, and it's what uv uses, some consistency wouldn't hurt. But if there are reasons against it, something like --requirements-from-pyproject is fine by me (maybe it could be a bit shorter).
As far as I understand from discussion on #11440, there is no way to get dependencies from the build system with a guarantee that build (or part of build) won't be invoked, which would likely result in a failure when used in a container with just pyproject.toml. Reading comments on #11440, it seems that reading pyproject.toml directly is a reasonable solution for static dependencies.
Could you support optional-dependencies? like this:
pip install -r pyproject.toml[test,mypy]
With not only optional-dependencies but also dependency-groups, I feel this needs a separate flag than to overload -r.
With not only optional-dependencies but also dependency-groups, I feel this needs a separate flag than to overload -r.
I don't see why?
Optional dependencies can probably be easily and consistently supported like they are elsewhere, like in @rexzhang's example.
I'm not that familiar with dependency groups, but it seems like installing just a group is already possible, for example:
pip install --group somegroup
only installs somegroup, not the package itself. So it's unclear to me what would need to be done here.
One minor issue I see is that:
pip install -r dir/pyproject.toml --group somegroup
right now would install deps from dir/pyproject.toml, and somegroup dependency group from ./pyproject.toml, which might seem confusing. But this behaviour makes sense when -r and --group are considered independent of each other and can be easily fixed by specifying pyproject.toml path in --group. In any case, changing -r to something else doesn't help here (pip install --deps-from dir/pyproject.toml --group somegroup could also be misinterpreted as installing somegroup from dir/pyproject.toml).
#11440 also mentioned installing just build dependencies, but it sounds like it should just be a separate flag that works independently of -r (like --group), maybe something like:
pip install --build-deps-from pyproject.toml
Could you support optional-dependencies? like this:
pip install -r pyproject.toml[test,mypy]
By the way, judging by the names (test, mypy) these sound like development dependencies. If they are, these should probably be dependency groups instead of optional dependencies. Doesn't mean optional dependencies shouldn't be supported, I'm just nitpicking that a better example would be something like:
pip install -r pyproject.toml[gui,cli]