astral-sh / uv

An extremely fast Python package and project manager, written in Rust.
https://docs.astral.sh/uv
Apache License 2.0
20.19k stars 599 forks source link

FR: add support for `uv pip install <PyPI package> --all-extras` #7295

Open neutrinoceros opened 6 days ago

neutrinoceros commented 6 days ago

I know of a couple packages with so many optional dependencies that they implement a shorthand to get all of them as, for instance pip install 'pkg[all]' or something similar. Problem is that this is hardly discoverable for end users, must be documented, and not every package chooses the same extra name so it's hard to remember.

uv pip install <PyPI package> --all-extras would seem like a natural solution here but currently (as of uv 0.4.9) doesn't support this:

$ uv pip install astropy --all-extras
error: Requesting extras requires a `pyproject.toml`, `setup.cfg`, or `setup.py` file.

Is it something that could be considered in the future ?

notatallshaw commented 6 days ago

Would --all-extras also apply to all the dependencies and transitive dependencies? Or would it be per-package?

neutrinoceros commented 6 days ago

I think per-package makes more sense.

neutrinoceros commented 6 days ago

Actually I'm not 100% I get what you mean by per-package. What I'd like to happen is that everything from the requested package's optional dependencies is installed, ignoring existing their extras. IIUC that would be the same behavior as installing a package from a path with --all-extras.

Does this make sense ?

notatallshaw commented 6 days ago

For example, let's say I had a requirements file:

Aaa
Bbb
Ccc

And a constraints file:

Ccc[extra]==1
Ddd==1

And I ran: uv pip install Eee -r requirements.txt -c constraints.txt --all-extras

Which packages out of Aaa, Bbb, Ccc, Ddd, Eee, should have requested all extras?

neutrinoceros commented 6 days ago

I'd say Eee for sure but not sure about the rest. I rarely ever encounter or use constraint files, I'm not sure how to interpret Ccc[extra]==1 as a constraint. I'm guessing it means that Ccc can only be installed at version 1 with extras [extra] or not at all ?

notatallshaw commented 6 days ago

Yeah, ignore the constraints, they don't work well with extras anyway, I was trying to think of unusual edge cases.

IMO the only sensible approach would be to include all user provided requirements, all those provided over the CLI, and all those provided in requirements file, having a flag depend on how you provided non-local requirements would be susprising and not fit with any existing flag I think?

I think --all-extras comes from the pip-tools and Poetry world, uv would make it need a decide if this consistently and logically works for them.

It might also be a breaking change with the way users currently use it currently? E.g. would this affect echo -e {local_package}\n{non_local_package} | pip compile - -all-extras?

A similiar topic has been on my mind this last week, hence the questions, my idea is about making this easier to define in the pyproject.toml.

neutrinoceros commented 5 days ago

IMO the only sensible approach would be to include all user provided requirements, all those provided over the CLI, and all those provided in requirements file, having a flag depend on how you provided non-local requirements would be susprising and not fit with any existing flag I think?

Agreed. Anything else would be both more surprising and less maintainable.

would this affect echo -e {local_package}\n{non_local_package} | pip compile - -all-extras?

Oof, this made me realize I don't know what --all-extras means for a requirement file. The only way I know how to define the code extras is through pyproject.toml, so, I really don't know.

my idea is about making this easier to define in the pyproject.toml

I didn't know self referential extras weren't documented. This is actually what the packages I have in mind (yt and astropy) already use !