uv icon indicating copy to clipboard operation
uv copied to clipboard

`uv pip compile` compiles requirements files with explicit `file:...` requirements into something which `pip` can't install

Open Julian opened this issue 10 months ago • 10 comments

Given a requirements.in file containing either file:.#egg=foo or file:/Users/Julian/Desktop/foo/#egg=foo, uv pip compile emits a requirement which looks like a combination of the input and a PEP508 requirement, specifically foo @ file:/Users/Julian/Desktop/foo/#egg=foo -- but neither pip nor pip-compile can deal with such a requirement, they both blow up when seeing it.

E.g.:

⊙  python3.12 -m venv venv && venv/bin/python -m pip install -r <(uv pip compile <(printf 'file:/Users/Julian/Desktop/foo/#egg=foo\n'))                                                                                                                                       julian@Airm ●
Resolved 1 package in 17ms
ERROR: Invalid requirement: 'foo @ file:/Users/Julian/Desktop/foo/#egg=foo' (from line 3 of /dev/fd/11)
Hint: It looks like a path. File 'foo @ file:/Users/Julian/Desktop/foo/#egg=foo' does not exist.

~~Changing the input to instead be foo @ thepath obviously works correctly --~~ the history of relative paths and requirements files in pip is ... "interesting" I know, so I don't recall why I continue to use file:. everywhere in my packages, I'll have to see what breaks if I switch, but it seems like if uv pip compile is going to muck with the input anyhow that it likely should go further and change file:.#egg=foo to just . and emit foo @ .?

This is on macOS with:

⊙  uv --version                                                                                                                                                                                                                                                                 julian@Airm
uv 0.1.35

Julian avatar Apr 22 '24 07:04 Julian

Oh, I misspoke when I said foo @ file:. would work with pip, apparently it (still? or was reverted? I really can't follow) does not because PEP 508 only allows for "real" i.e. absolute file URIs, so even emitting that doesn't work with both tools.

I am still chasing https://github.com/pypa/pip/pull/4208 and some other tickets to remind myself what's expected to work, but I filed this at least to see if someone who already knows can tell me :)

EDIT: https://github.com/pypa/pip/issues/8035 and https://github.com/jazzband/pip-tools/pull/1650 seem relevant.

Julian avatar Apr 22 '24 07:04 Julian

I ran into the same issue, and it makes the transition from pip to uv harder. I have a requirements.in files which contains file://some-path-to-a-wheel.whl. The good news is that uv pip compile now supports compiling them, but the bad news is the requirements.txt file it compiles does not work with pip install -r requirements.txt because pip doesn't support the name @ file://some-path-to-a-wheel.whl syntax generated by uv pip compile. As a hacky workaround, I remove the name @ text in an extra step. The resulting requirements.txt works with both uv pip compile and pip install. Adopting uv will be easier if uv pip compile made it possible, perhaps with a flag, to omit the name @ prefix in requirements.txt .

john-g-g avatar Apr 22 '24 11:04 john-g-g

Yeah pip does not support relative paths in requirements.txt. We support reading them in requirements.txt (but not pyproject.toml, since that has to follow PEP 508). So if you leverage that feature, it will knowingly compile to something pip can't install.

You can instead use foo @ file://${PROJECT_ROOT} or use some other environment variable? That's typically how folks do relative paths in pip.

pip and uv both support relative paths for -e (editable) installs.

charliermarsh avatar Apr 22 '24 14:04 charliermarsh

(Thanks for the response!)

Yeah pip does not support relative paths in requirements.txt.

It does though doesn't it? Or do you mean to say "officially"? (I.e. it's hard to tell whether what works works intentionally).

Specifically, both of these work fine:

⊙  python3.12 -m venv venv && venv/bin/python -m pip install 'file:../Development/jsonschema#egg=jsonschema'

and

⊙  uv pip install --python venv/bin/python 'file:../Development/jsonschema#egg=jsonschema'

Where I've told both pip and uv to install a relative path to some package.

What doesn't work, or what I was trying to communicate in the issue, was basically if you have that in a requirements file, pip-compile leaves it alone, but uv pip compile will not, it will change it to something that only works with uv and not with pip install.

Julian avatar Apr 22 '24 14:04 Julian

Oh sorry, so you're saying it does support unnamed relative requirements?

charliermarsh avatar Apr 22 '24 15:04 charliermarsh

Correct!

Julian avatar Apr 22 '24 15:04 Julian

That's weird. Maybe we should add support over there? It seems like a bad thing to not track the name.

zanieb avatar Apr 22 '24 15:04 zanieb

That's weird. Maybe we should add support over there? It seems like a bad thing to not track the name.

That seems like the correct approach, but the requirements.txt incompatibility will force us to use uv everywhere we install dependencies, which is difficult. A compatible requirements syntax provides a nice abstraction layer to transition away from pip.

john-g-g avatar Apr 24 '24 00:04 john-g-g

I think we should consider always outputting without the name when it's a relative path.

charliermarsh avatar Apr 24 '24 17:04 charliermarsh

When relative paths are in the inputs and outputs, not everyone agrees on which path they ought to be relative to. My own opinion is that any relative path should be relative to the file it appears in. But that can be trouble when e.g. installing with pip from another working directory.

AndydeCleyre avatar Apr 26 '24 17:04 AndydeCleyre

perhaps a flag to include/exclude the name for relative paths?

my workaround right now is to remove the prefix after running compile, and re-add it when running it again.

Nomelas avatar May 14 '24 23:05 Nomelas

I believe this seems to have regressed (as of 0.2.2, but I see also in 0.2.5) -- but now it's uv generating something uv itself cannot deal with rather than pip. Will file a follow up with fuller details.

Julian avatar May 31 '24 09:05 Julian