uv
uv copied to clipboard
`uv pip compile` compiles requirements files with explicit `file:...` requirements into something which `pip` can't install
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
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.
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
.
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.
(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
.
Oh sorry, so you're saying it does support unnamed relative requirements?
Correct!
That's weird. Maybe we should add support over there? It seems like a bad thing to not track the name.
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.
I think we should consider always outputting without the name when it's a relative path.
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.
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.
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.