-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Add dependency-group cli flags to uv pip install and uv pip compile (--group, --no-group, --only-group, --all-groups)
#10861
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
No description provided. |
| /// Include optional dependencies from the specified group; may be provided more than once. | ||
| /// | ||
| /// Only applies to `pyproject.toml`, `setup.py`, and `setup.cfg` sources. | ||
| #[option( | ||
| default = "[]", | ||
| value_type = "list[str]", | ||
| example = r#" | ||
| group = ["dev", "docs"] | ||
| "# | ||
| )] | ||
| pub group: Option<Vec<GroupName>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whether these were supposed to pass through the shared PipOptions and not a side-thing was an uncertainty for me. Overall I assumed they're equivalentish to the extra settings and those are here, so, seems fine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems right to me, though the option abstractions are not my forte.
| /// Returns `true` if the specification will have no effect. | ||
| pub fn is_empty(&self) -> bool { | ||
| let GroupsSpecification::Include { | ||
| include: IncludeGroups::Some(includes), | ||
| exclude, | ||
| } = self | ||
| else { | ||
| return false; | ||
| }; | ||
| includes.is_empty() && exclude.is_empty() | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not entirely sure about the correctness of this. Is this relying on some assumptions about the construction of GroupsSpecification?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is, but it's a relatively mundane assumption imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth a comment saying what the assumption is, but don't feel strongly.
| /// Include optional dependencies from the specified group; may be provided more than once. | ||
| /// | ||
| /// Only applies to `pyproject.toml`, `setup.py`, and `setup.cfg` sources. | ||
| #[option( | ||
| default = "[]", | ||
| value_type = "list[str]", | ||
| example = r#" | ||
| group = ["dev", "docs"] | ||
| "# | ||
| )] | ||
| pub group: Option<Vec<GroupName>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems right to me, though the option abstractions are not my forte.
crates/uv/tests/it/pip_install.rs
Outdated
| } | ||
|
|
||
| #[test] | ||
| fn install_group() -> Result<()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if multiple pyproject.toml files are provided? What happens if a group is present in one but not the other? If a group is present in both?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, what about uv pip install <dir> --group <name>?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe as currently implemented we:
- don't complain if we fail to find a group in the toml
- would independently match and include groups from every toml
This falls out of the implementation basically being "for each sourcefile, for each group in that sourcefile, if the selector built from cli flags matches the name of this group, append that group to the requirements".
not sure about the dir usecase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should fail (or at the very least, warn) if we cannot find a group.
I don't mind including groups from every toml, but we should have test coverage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We fail in uv sync fwiw
❯ uv sync --group test
error: Group `test` is not defined in the project's `dependency-group` table
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added warnings.
| #### [`all-groups`](#pip_all-groups) {: #pip_all-groups } | ||
| <span id="all-groups"></span> | ||
|
|
||
| Include all groups. | ||
|
|
||
| Only applies to `pyproject.toml`, `setup.py`, and `setup.cfg` sources. | ||
|
|
||
| **Default value**: `false` | ||
|
|
||
| **Type**: `bool` | ||
|
|
||
| **Example usage**: | ||
|
|
||
| === "pyproject.toml" | ||
|
|
||
| ```toml | ||
| [tool.uv.pip] | ||
| all-groups = true | ||
| ``` | ||
| === "uv.toml" | ||
|
|
||
| ```toml | ||
| [pip] | ||
| all-groups = true | ||
| ``` | ||
|
|
||
| --- | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly I'm not sure why we support requesting extras in settings file like this. It seems correct to match the extras options for groups though?
Perhaps @charliermarsh understands the use-case?
264867c to
15e22dc
Compare
uv pip install and uv pip compile (--group, --no-group, --no-default-groups, --only-group, --all-groups)uv pip install and uv pip compile (--group, --no-group, --only-group, --all-groups)
|
Thanks @Gankra |
|
Not that this is does not match the proposed API for |
|
Wow incredible timing. This won't get released in uv until we're happy with our interop story (will back this out if need be). |
|
This is intended to be compatible with the proposed |
|
Is there another way of compiling development groups dependencies into a requirements.txt if this is no longer planned? I don't see anything in the docs or issues so just wondering if it's possible. |
|
If you use |
|
And pypa/pip#13065 should be about ready to go in, it's already got an approval. You can also use |
…pile` (#11686) This is a minimal redux of #10861 to be compatible with `uv pip`. This implements the interface described in: pypa/pip#13065 (comment) for `uv pip install` and `uv pip compile`. Namely `--group <[path:]name>`, where `path` when not defined defaults to `pyproject.toml`. In that interface they add `--group` to `pip install`, `pip download`, and `pip wheel`. Notably we do not define `uv pip download` and `uv pip wheel`, so for parity we only need to implement `uv pip install`. However, we also support `uv pip compile` which is not part of pip itself, and `--group` makes sense there too. ---- The behaviour of `--group` for `uv pip` commands makes sense for the cases upstream pip supports, but has confusing meanings in cases that only we support (because reading pyproject.tomls is New Tech to them but heavily supported by us). **Specifically case (h) below is a concerning footgun, and case (e) below may get complaints from people who aren't well-versed in dependency-groups-as-they-pertain-to-wheels.** ## Only Group Flags Group flags on their own work reasonably and uncontroversially, except perhaps that they don't do very clever automatic project discovery. a) `uv pip install --group path/to/pyproject.toml:mygroup` pulls up `path/to/project.toml` and installs all the packages listed by its `mygroup` dependency-group (essentially treating it like another kind of requirements.txt). In this regard it functions similarly to `--only-group` in the rest of uv's interface. b) `uv pip install --group mygroup` is just sugar for `uv pip install --group pyproject.toml:mygroup` (**note that no project discovery occurs**, upstream pip simply hardcodes the path "pyproject.toml" here and we reproduce that.) c) `uv pip install --group a/pyproject.toml:groupx --group b/pyproject.toml:groupy`, and any other instance of multiple `--group` flags, can be understood as completely independent requests for the given groups at the given files. ## Groups With Named Packages Groups being mixed with named packages also work in a fairly unsurprising way, especially if you understand that things like dependency-groups are not really supposed to exist on pypi, they're just for local development. d) `uv pip install mypackage --group path/to/pyproject.toml:mygroup` much like multiple instances of `--group` the two requests here are essentially completely independent: pleases install `mypackage`, and please also install `path/to/pyproject.toml:mygroup`. e) `uv pip install mypackage --group mygroup` is exactly the same, but this is where it becomes possible for someone to be a little confused, as you might think `mygroup` is supposed to refer to `mypackage` in some way (it can't). But no, it's sourcing `pyproject.toml:mygroup` from the current working directory. ## Groups With Requirements/Sourcetrees/Editables Requirements and sourcetrees are where I expect users to get confused. It behaves *exactly* the same as it does in the previous sections but you would absolutely be forgiven for expecting a different behaviour. *Especially* because `--group` with the rest of uv *does* do something different. f) `uv pip install -r a/pyproject.toml --group b/pyproject.toml:mygroup` is again just two independent requests (install `a/pyproject.toml`'s dependencies, and `b/pyproject.toml`'s `mygroup`). g) `uv pip install -r pyproject.toml --group mygroup` is exactly like the previous case but *incidentally* the two requests refer to the same file. What the user wanted to happen is almost certainly happening, but they are likely getting "lucky" here that they're requesting something simple. h) `uv pip install -r a/pyproject.toml --group mygroup` is again exactly the same but the user is likely to get surprised and upset as this invocation actually sources two different files (install `a/pyproject.toml`'s dependencies, and `pyproject.toml`'s `mygroup`)! I would expect most people to assume the `--group` flag here is covering all applicable requirements/sourcetrees/editables, but no, it continues to be a totally independent reference to a file with a hardcoded relative path. ------ Fixes #8590 Fixes #8969
This PR switches from using optional-dependencies to dependency-groups for several development dependencies This depends on: - tox-dev/tox#3409 - astral-sh/uv#8272 - astral-sh/uv#8590 - astral-sh/uv#8969 - astral-sh/uv#10861 - astral-sh/uv#11686 (actually incorporated in uv 0.6.8) - readthedocs/readthedocs.org#11766, will be solved by readthedocs/readthedocs.org#11710
Ultimately this is a lot of settings plumbing and a couple minor pieces of Actual Logic (which are so simple I have to assume there's something missing, but maybe not!).
Note this "needlessly" use DevDependencyGroup since it costs nothing, is more futureproof, and lets us maintain one primary interface (we just pass
falsefor all the dev arguments).Fixes #8590
Fixes #8969