Skip to content

Add support for pip install --only-deps.#13895

Open
shoeffner wants to merge 1 commit into
pypa:mainfrom
shoeffner:only-deps
Open

Add support for pip install --only-deps.#13895
shoeffner wants to merge 1 commit into
pypa:mainfrom
shoeffner:only-deps

Conversation

@shoeffner

Copy link
Copy Markdown

This commit follows the agreed interface in 1:

pip install --only-deps .  # project.dependencies
pip install --only-deps .[doc]  # project.dependencies and project.optional-dependencies

If --only-deps or its longform --only-dependencies is provided, neither the explicitly requested packages nor the build dependencies are installed, instead only the "runtime" dependencies are used.
--only-deps and --no-deps are mutually exclusive and pip will refuse to install anything if both are specified.

Because --only-deps does not install build dependencies, no implicit or dynamic dependencies can be managed this way, that means a build tool cannot automatically install more dependencies by executing additional code.

First part of #11440.

@shoeffner

Copy link
Copy Markdown
Author

Okay, looks like the legacy resolver requires a similar treatment or has to throw an error. I'll see what I can do :-)

@notatallshaw

notatallshaw commented Apr 7, 2026

Copy link
Copy Markdown
Member

FYI, it's completely fine to ban the user from providing only deps and use legacy resolver, if that makes things simpler.

Recently there is movement on dropping the legacy resolver.

@ichard26

This comment was marked as duplicate.

@shoeffner

shoeffner commented Apr 8, 2026

Copy link
Copy Markdown
Author

The main failure reason is that I missed the fact that the options-object does not always have the proper values (i.e., options.only_dependencies is not available unless specified). To make it work, I first considered getattr(options, 'only_dependencies', False), but after sleeping over it, the cleaner solution seems to be to also add the option to the commands download, lock, and wheel.

While the scope of the issue was to provide --only-deps for install, I believe adding it to the related commands is better than any workaround which would be replaced in the future again.

I will do that today after work.

@sbidoul sbidoul left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this!

A couple of comments/questions.

Comment thread src/pip/_internal/distributions/sdist.py Outdated
Comment thread src/pip/_internal/resolution/resolvelib/resolver.py
Comment thread src/pip/_internal/distributions/sdist.py Outdated
@shoeffner

Copy link
Copy Markdown
Author

I cannot reproduce the CI failures locally:

FAILED tests/unit/metadata/test_metadata.py::test_trailing_slash_directory_metadata[/path/to/foo.egg-info] - importlib.metadata.MetadataNotFound: No package metadata was found.
FAILED tests/unit/metadata/test_metadata.py::test_trailing_slash_directory_metadata[/path/to/foo.egg-info/] - importlib.metadata.MetadataNotFound: No package metadata was found.

But they seem to be failing on the main branch as well.

@shoeffner
shoeffner marked this pull request as draft April 8, 2026 20:24
Comment thread src/pip/_internal/cli/cmdoptions.py Outdated
@sbidoul

sbidoul commented Apr 9, 2026

Copy link
Copy Markdown
Member

also add the option to the commands download, lock, and wheel.

Absolutely, that has to be done at the same time.

@shoeffner

Copy link
Copy Markdown
Author

I rebased the branch on the current main, I hope that resolves then Python 3.15 issues of the CI pipeline.

I also added basic function tests to wheel, download, and lock for the feature.

@sbidoul sbidoul left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I did some tests and it works as expected. The implementation is simple and contained which is great!

A few comments to address, but this looks like it's almost ready.

Comment thread docs/html/user_guide.rst Outdated
Comment thread docs/html/user_guide.rst Outdated
Comment thread docs/html/user_guide.rst Outdated
Comment thread src/pip/_internal/cli/cmdoptions.py Outdated
Comment thread tests/functional/test_install_dependencies.py Outdated
Comment thread tests/functional/test_install_dependencies.py Outdated
Comment thread tests/functional/test_install_dependencies.py Outdated
@sbidoul sbidoul added this to the 26.2 milestone Jun 7, 2026
@shoeffner

Copy link
Copy Markdown
Author

Thanks for the thorough review, @sbidoul, your feedback was great and I believe it helped a lot to improve the PR!
Let me know if there is more to address or not :)

If not, I can rebase and squash the commits to be a bit more concise and mark the PR as ready.

@shoeffner
shoeffner force-pushed the only-deps branch 2 times, most recently from d7cdda6 to 261ccbf Compare June 9, 2026 19:30
@shoeffner
shoeffner marked this pull request as ready for review June 9, 2026 19:30
@shoeffner

shoeffner commented Jun 9, 2026

Copy link
Copy Markdown
Author

I have squashed and rebased the PR and marked it as "Ready for review". Let me know if there's more I can address :)

(P.S.: As mentioned in the issue, don't feel pressured, I am in no hurry :) )

@sbidoul

sbidoul commented Jun 10, 2026

Copy link
Copy Markdown
Member

@shoeffner I worry I sent you on a difficult track with assert_not_installed, as the original assert_installed is old and not super robust itself. A better way would be to test for the absence of site-package/{package}-*.dist-info (assuming the package name is normalized). Sorry about that.

Alternatively, examining the installation report of pip install --quiet --dry-run --report - is also a possibility.

@shoeffner

Copy link
Copy Markdown
Author

Haha, no need to worry. I will take a look into that, thanks for the suggestion!

@sbidoul

sbidoul commented Jun 28, 2026

Copy link
Copy Markdown
Member

@shoeffner a quick note that July and 26.2 is approaching. So if you find the time to have a last look at the tests in the coming couple of weeks, this can likely make it into 26.2.

@ichard26

Copy link
Copy Markdown
Member

I'd like to include this in pip 26.2 if it is ready by the end of the month. I still need to perform an in-depth review, but on the surface, the proposed UI looks good to me. I'll need to think about the UI a bit more since I haven't thought about this feature in ages (and we're growing a lot of complexity1 around requirements which makes me uneasy).

Footnotes

  1. To be clear, this isn't your fault. It's just inherent complexity from pip growing organically over the decades. pip's pylock support is also in the same boat.

@shoeffner
shoeffner force-pushed the only-deps branch 2 times, most recently from bcf66f4 to c434c9d Compare July 3, 2026 04:06
@shoeffner

Copy link
Copy Markdown
Author

Sorry for the slow response time!

  • I rebased the branch
  • I changed assert_not_installed to check for the relevant dist-info folder per @sbidoul's suggestion and adjusted the relevant tests (this way, there's no difference for editable / non-editable installs, thus they deliver the same error message)
  • I fixed the black formatting by using --target-version py314. Surprisingly, the pre-commit checks always passed, while the CI did not. I guess I borked a part of my local setup.

@sbidoul sbidoul left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of documentation suggestions but otherwise this looks good to me. Thanks for this work!

Comment thread docs/html/user_guide.rst Outdated
Comment thread src/pip/_internal/cli/cmdoptions.py Outdated
Comment thread src/pip/_internal/cli/cmdoptions.py Outdated
Comment thread src/pip/_internal/cli/cmdoptions.py Outdated
action="store_true",
default=False,
help=(
"Handle only the dependencies of the provided requirements, not the "

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"handle" sounds a little bit strange, but I see why you use this as this option is used for install, wheel, download and lock. I don't have a better idea.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a different sentence structure such as "Take only the dependencies ... into account" could work?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it accordingly, but am happy to change it to any other good wording.

This commit follows the agreed interface in [1]:

    pip install --only-deps .  # project.dependencies
    pip install --only-deps .[doc]  # project.dependencies and project.optional-dependencies

If --only-deps or its longform --only-dependencies is provided, neither the
explicitly requested packages nor the build dependencies are installed, instead
only the "runtime" dependencies are used. In other words, no user supplied
packages will be installed, only their dependencies.
--only-deps and --no-deps are mutually exclusive and pip will refuse to install
anything if both are specified. Similarly, --only-deps is mutually exclusive
to -r / --requirements, --use-deprecated legacy-resolver, and --group.
Relevant explanations can be found in the user guide, which now includes a
section regarding --only-deps.

Because --only-deps does not install build dependencies, no implicit or dynamic
dependencies can be managed this way, that means a build tool cannot
automatically install more dependencies by executing additional code.

This also adds the --only-deps flag to wheel, lock, and download, indicating
a user only wants to handle dependencies of a package.

To test the changes more easily, the commit adds
PipTestResult.assert_not_installed and tests for it.

First part of pypa#11440, which also specifies "build-only dependencies",
which are out of scope for this PR.

[1]: pypa#11440 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants