Commit graph

933 commits

Author SHA1 Message Date
Zanie
34f8999594 Add missing ref test
# Conflicts:
#	crates/uv/tests/pip_install.rs
2024-02-21 12:59:56 -06:00
Zanie
8395e8ee81 Lint 2024-02-21 12:56:25 -06:00
Zanie
54b4a9dabb Restore debug log 2024-02-21 12:56:25 -06:00
Zanie
d5b7a7c2d9 Reuse the discovered sucessful fetch strategy if feasible 2024-02-21 12:56:25 -06:00
Zanie
8b46579b9d Move fetch strategy retry deeper into internals
This avoids redoing the fast-path and such and only actually retries the fetch itself

# Conflicts:
#	crates/uv-git/src/git.rs

# Conflicts:
#	crates/uv-git/src/git.rs
2024-02-21 12:56:24 -06:00
Zanie
479864a942 Use libgit2 first then fallback to the git command on failure 2024-02-21 12:47:33 -06:00
Zanie Blue
71ec568d0f
Use git command to fetch repositories instead of libgit2 for robust SSH support (#1781)
Closes https://github.com/astral-sh/uv/issues/1775
Closes https://github.com/astral-sh/uv/issues/1452
Closes https://github.com/astral-sh/uv/issues/1514
Follows https://github.com/astral-sh/uv/pull/1717

libgit2 does not support host names with extra identifiers during SSH
lookup (e.g. [`github.com-some_identifier`](

https://docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys#using-multiple-repositories-on-one-server))
so we use the `git` command instead for fetching. This is required for
`pip` parity.

See the [Cargo
documentation](https://doc.rust-lang.org/nightly/cargo/reference/config.html#netgit-fetch-with-cli)
for more details on using the `git` CLI instead of libgit2. We may want
to try to use libgit2 first in the future, as it is more performant
(#1786).

We now support authentication with:

```
git+ssh://git@<hostname>/...
git+ssh://git@<hostname>-<identifier>/...
```

Tested with a deploy key e.g.

```
cargo run -- \
    pip install uv-private-pypackage@git+ssh://git@github.com-test-uv-private-pypackage/astral-test/uv-private-pypackage.git \
    --reinstall --no-cache -v
```

and

```
cargo run -- \
    pip install uv-private-pypackage@git+ssh://git@github.com/astral-test/uv-private-pypackage.git \
    --reinstall --no-cache -v     
```

with a ssh config like

```
Host github.com
        Hostname github.com
        IdentityFile=/Users/mz/.ssh/id_ed25519

Host github.com-test-uv-private-pypackage
        Hostname github.com
        IdentityFile=/Users/mz/.ssh/id_ed25519
```

It seems quite hard to add test coverage for this to the test suite, as
we'd need to add the SSH key and I don't know how to isolate that from
affecting other developer's machines.
2024-02-21 12:44:32 -06:00
Charlie Marsh
b4bc40627c
Sort output when installing seed packages (#1822)
This output is technically non-deterministic right now.
2024-02-21 18:33:06 +00:00
Micha Reiser
39ee3969d9
Upgrade to Rust 1.76 (#1820) 2024-02-21 17:53:41 +00:00
Andrew Gallant
deef6c102d
platform-host: check /bin/sh, then /bin/dash and then /bin/ls (#1818)
Previously, we were only checking /bin/sh. While that works in most
cases, it seems like there are still scenarios where /bin/sh isn't an
executable itself, and is instead just a shell script that calls
/bin/dash. (See #1810 for example.)

In this PR, we make the `ld` detection a bit more robust by trying
multiple paths. As with previous changes, we emit copious logs to help
debug this in the future.

It's not totally clear how to test this. I'm not sure how to reproduce
the environment mentions in #1810 specifically since it seems like an
internal variant of WSL Ubuntu.

Fixes #1810
2024-02-21 11:49:28 -05:00
Micha Reiser
fac9d843dc
Normalize VIRTUAL_ENV path in activation scripts (#1817) 2024-02-21 15:52:32 +00:00
Charlie Marsh
cff16f5736
Use redirected URL as base for relative paths (#1816)
## Summary

If you review the setup in https://github.com/astral-sh/uv/issues/1747,
when we fetch `http://localhost:8000/simple/wheel/`, it gets redirected
to `http://localhost:8000/index/wheel/`. So any relative paths returned
need to be resolved relative to `http://localhost:8000/index/wheel/`.

Closes https://github.com/astral-sh/uv/issues/1747.

## Test Plan

- Install `proxpi gunicorn pypiserver`
- `gunicorn proxpi.server:app --bind 0.0.0.0:8000`
- `pypi-server run -p 8080 ~/packages --fallback-url
"http://localhost:8000/index" --verbose`
- `echo "wheel" | cargo run pip compile - --index-url
http://localhost:8080/simple --verbose --no-cache`
2024-02-21 15:10:25 +00:00
Charlie Marsh
c2b75b64d2
Wait for distribution metadata with --no-deps (#1812)
## Summary

We still need to wait for the distribution metadata (for direct
dependencies), even when resolving with `--no-deps`, since we rely on it
to report diagnostics to the user.

Closes https://github.com/astral-sh/uv/issues/1801.
2024-02-21 14:45:09 +00:00
Charlie Marsh
19890feb77
Preserve executable bit when untarring archives (#1790)
## Summary

Closes https://github.com/astral-sh/uv/issues/1767.
2024-02-21 14:18:44 +00:00
Charlie Marsh
88a0c13865
Use async unzip for local source distributions (#1809)
## Summary

We currently maintain separate untar methods for sync and async, but we
only use the sync version when the user provides a local source
distribution. (Otherwise, we untar as we download the distribution.) In
my testing, this is actually slower anyway:

```
❯ python -m scripts.bench \
        --uv-path ./target/release/main \
        --uv-path ./target/release/uv \
        ./requirements.in --benchmark resolve-cold --min-runs 50
Benchmark 1: ./target/release/main (resolve-cold)
  Time (mean ± σ):     835.2 ms ± 107.4 ms    [User: 346.0 ms, System: 151.3 ms]
  Range (min … max):   639.2 ms … 1051.0 ms    50 runs

Benchmark 2: ./target/release/uv (resolve-cold)
  Time (mean ± σ):     750.7 ms ±  91.9 ms    [User: 345.7 ms, System: 149.4 ms]
  Range (min … max):   637.9 ms … 905.7 ms    50 runs

Summary
  './target/release/uv (resolve-cold)' ran
    1.11 ± 0.20 times faster than './target/release/main (resolve-cold)'
```
2024-02-21 14:11:37 +00:00
Charlie Marsh
a2a1b2fb0f
Avoid enforcing URL correctness for installed distributions (#1793)
## Summary

Allows the corresponding `pypi_types` struct to use any URL, since other
installers can put those into the environment, and Poetry seems to write
invalid URLs.

If we see a distribution with an invalid URL, we just treat it as a
registry distribution, which isn't ideal, but is better than (1)
erroring, and (2) changing `Url` to `String` everywhere internally. (I'm
torn on this second option.)

Closes https://github.com/astral-sh/uv/issues/1744.

## Test Plan

- Added `flask = { git = "git@github.com:pallets/flask.git", rev =
"b90a4f1f4a370e92054b9cc9db0efcb864f87ebe" }` to
`scripts/editable-installs/poetry_editable/pyproject.toml`.
- Ran `poetry install`.
- Ran `cargo pip freeze`. Verified that it errored on `main`, but passed
here.
- Ran `cargo run pip install "flask==3.0.0"`. Verified that it
uninstalled the existing Flask, and installed a new version from the
registry.
2024-02-21 09:06:31 -05:00
konsti
0f520d8716
Configurable bootstrap dir (#1772)
Add a `UV_BOOTSTRAP_DIR` option to configure the python bootstrap
directory. This is helpful when working across multiple platforms in a
single IDE session.
2024-02-21 13:46:23 +01:00
Charlie Marsh
5d53040465
Stream zip archive when fetching non-range-request metadata (#1792)
## Summary

If a registry doesn't support range requests, then today, we download
the entire wheel to disk and then read the metadata from the downloaded
archive. This PR instead modifies the registry client to stream the
zipfile and stop as soon as it's seen the metadata, which should be more
efficient.

Closes https://github.com/astral-sh/uv/issues/1596.

## Test Plan

Made this the _only_ path for downloading metadata; verified that the
test suite passed.
2024-02-20 22:12:21 -05:00
Evgeniy Dubovskoy
31752bf4be
feat: Implement --annotation-style parameter for uv pip compile (#1679)
## Summary

Hello there! The motivation for this feature is described here #1678 

## Test Plan

I've added unit tests and also tested this manually on my work project
by comparing it to the original `pip-compile` output - it looks much
like the `pip-compile` generated lock file.
2024-02-21 02:08:34 +00:00
Zanie Blue
3cd51ffc92
Support setting request timeout with UV_HTTP_TIMEOUT and HTTP_TIMEOUT (#1780)
Follow-up to #1694 matching Cargo's environment variable names


https://doc.rust-lang.org/nightly/cargo/reference/config.html#httptimeout
2024-02-20 18:48:18 -06:00
Zanie Blue
d07b587f3f
Retain passwords in Git URLs (#1717)
Fixes handling of GitHub PATs in HTTPS URLs, which were otherwise
dropped. We now supporting the following authentication schemes:

```
git+https://<user>:<token>/...
git+https://<token>/...
```

On Windows, the username is required. We can consider adding a
special-case for this in the future, but this just matches libgit2's
behavior.

I tested with fine-grained tokens, OAuth tokens, and "classic" tokens.
There's test coverage for fine-grained tokens in CI where we use a real
private repository and PAT. Yes, the PAT is committed to make this test
usable by anyone. It has read-only permissions to the single repository,
expires Feb 1 2025, and is in an isolated organization and GitHub
account.

Does not yet address SSH authentication.

Related:
- https://github.com/astral-sh/uv/issues/1514
- https://github.com/astral-sh/uv/issues/1452
2024-02-21 00:12:56 +00:00
Edgar Ramírez Mondragón
2e60c1d734
Use the right marker for the implementation field of pyvenv.cfg (#1785)
## Summary

The generated `pyvenv.cfg` file hardcodes `implementation = CPython`
even for PyPy venvs, created with `uv venv venv --python pypy3.10`, for
example.

```ini
home = /path/to/.pyenv/versions/pypy3.10-7.3.15/bin
implementation = CPython
version_info = 3.10
gourgeist = 0.0.4
include-system-site-packages = false
base-prefix = /path/to/.pyenv/versions/pypy3.10-7.3.15
base-exec-prefix = /path/to/.pyenv/versions/pypy3.10-7.3.15
base-executable = /path/to/.pyenv/versions/pypy3.10-7.3.15/bin/pypy3.10
```

## Test Plan

Manually verified that `pyvenv.cfg` now contains `implementation =
PyPy`. I can try refactoring `create_bare_venv` to make it more easily
testable, though.
2024-02-20 19:09:53 -05:00
Charlie Marsh
f13d0adbcd
Ensure that builds within the cache aren't considered Git repositories (#1782)
## Summary

Some packages encode logic to embed the current commit SHA in the
version tag, when built within a Git repo. This typically results in an
invalid (non-compliant) version. Here's an example from `pylzma`:
ccb0e7cff3/version.py (L45).

This PR adds a phony, empty `.git` to the cache root, to ensure that any
`git` commands fail.

Closes https://github.com/astral-sh/uv/issues/1768.

## Test Plan

- Create a tag on the current commit, like `v0.5.0`.
- Build `pylzma`, using a cache _within_ the repo:

```
rm -rf foo
cargo run venv
cargo run pip install "pylzma @ 10ef072c3c/pylzma-0.5.0.tar.gz" --verbose  --cache-dir bar
```
2024-02-20 15:37:05 -05:00
Charlie Marsh
d5a2a5fed3
Add support for >dev specifier (#1776)
## Summary

Not a fan of this one but we don't have a clear policy on it yet so
feels weird to discriminate.

Closes https://github.com/astral-sh/uv/issues/1686.
2024-02-20 20:27:30 +00:00
Charlie Marsh
8df48f035f
Fix pep508-rs tests without features (#1778) 2024-02-20 19:35:36 +00:00
konsti
2928c6e574
Backport changes from publish crates (#1739)
Backport of changes for the published new versions of pep440_rs and
pep508_rs to make it easier to keep them in sync.
2024-02-20 19:33:27 +01:00
Andrew Gallant
8480842d3e
strip trailing + from version number of local Python builds (#1771)
(This PR message is mostly copied from the comment in the code.)

For local builds of Python, at time of writing, the version numbers end
with
a `+`. This makes the version non-PEP-440 compatible since a `+`
indicates
the start of a local segment which must be non-empty. Thus, `uv` chokes
on it
and [spits out an error][1] when trying to create a venv using a "local"
build
of Python. Arguably, the right fix for this is for [CPython to use a
PEP-440
compatible version number][2].

However, as a work-around for now, [as suggested by pradyunsg][3] as one
possible direction forward, we strip the `+`.

This fix does unfortunately mean that one [cannot specify a Python
version
constraint that specifically selects a local version][4]. But at the
time of
writing, it seems reasonable to block such functionality on this being
fixed
upstream (in some way).

Another alternative would be to treat such invalid versions as strings
(which
is what PEP-508 suggests), but this leads to undesirable behavior in
this
case. For example, let's say you have a Python constraint of `>=3.9.1`
and
a local build of Python with a version `3.11.1+`. Using string
comparisons
would mean the constraint wouldn't be satisfied:

    >>> "3.9.1" < "3.11.1+"
    False

So in the end, we just strip the trailing `+`, as was done in the days
of old
for [legacy version numbers][5].

I tested this fix by manually confirming that

    uv venv --python local/python

failed before it and succeeded after it.

Fixes #1357

[1]: https://github.com/astral-sh/uv/issues/1357
[2]: https://github.com/python/cpython/issues/99968
[3]:
https://github.com/pypa/packaging/issues/678#issuecomment-1436033646
[4]: https://github.com/astral-sh/uv/issues/1357#issuecomment-1947645243
[5]:
085ff41692/packaging/version.py (L168-L193)
2024-02-20 12:57:28 -05:00
konsti
a269766c27
If-let instead of unwrap (PR #1746 follow-up) (#1770)
Solves: https://github.com/astral-sh/uv/pull/1746#discussion_r1496139629
2024-02-20 17:32:01 +00:00
Charlie Marsh
ede2828fde
Bump version to v0.1.6 (#1736) 2024-02-20 12:22:26 -05:00
Tim de Jager
8cbeab7107
feat: add installer to InstalledDist (#1762)
## Summary

Add `installer` method to `InstalledDist` to distinguish between
different installers. Might be nice to add an enum for all possible
installers, but this might be too hard to keep up to date :).

The `INSTALLER` file is a file that can be added to the `.dist-info`
folder with the installer name.

Closes: #1759 

## Test Plan

Not sure if there is a place I can automatically test it, if you have a
pointer I would be happy to add a test.
2024-02-20 17:07:08 +00:00
konsti
a7513f4644
Better error message for missing space before semicolon in requirements (#1746)
PEP 508 requires a space between a URL and the semicolon separating it
from the markers to disambiguate it from a url ending with a semicolon.
This is easy to get wrong because the space is not required after a
plain name of PEP 440 specifier. The new error message explicitly points
out the missing space.

Fixes #1637
2024-02-20 16:38:36 +00:00
konsti
db61d848a7
Skip compile_html test on musl (#1756)
The torch index has no musllinux wheel, so we need to skip the test on
alpine.
2024-02-20 16:36:03 +00:00
Bas Zalmstra
6ea49ef7bf
fix: expose DefaultResolverProvider (#1764)
## Summary

The `DefaultResolverProvider` struct was not public. This PR exposes it
so we can build our own and use this as a fallback.

## Test Plan

I did not explicitly test this trivial change.
2024-02-20 11:34:19 -05:00
Andrew Gallant
8bcb998af1 uv-extract: add regression test for a bunk zip file
This ensures we can install a source dist from a `zip`
file that has present but bunk permissions.

Fixes #1453
2024-02-20 10:57:51 -05:00
Andrew Gallant
d6aaf7be30 uv-extract: call target.as_ref() once
This is just a style thing.
2024-02-20 10:57:51 -05:00
Andrew Gallant
634d593127 uv-client: remove benign WARN log message
A WARN log was being emitted for a "broken cache entry" in the case
where the cache entry simply doesn't exist. But this is totally fine and
expected. So we detect the kind of error that occurred and emit a TRACE
if the file simply didn't exist.
2024-02-20 10:57:51 -05:00
konsti
9a720a87c8
Only preserve the executable bit (#1743)
A file in a zip can set arbitrary unix permissions, but we, like pip,
want to preserve only the executable bit and otherwise use the OS
defaults.

This should be faster for wheels with many files since we now avoid the
blocking fs call to set the permissions in most cases.

Fixes #1740.
2024-02-20 16:41:05 +01:00
konsti
f7722c02c1
Don't preserve timestamp in streaming unzip (#1749)
## Summary

Don't preserve mtime to work around alexcrichton/tar-rs#349. Same as
#634 except for the streaming unzip.

Fixes #1748.

## Test Plan

Added the tomli source dist as test case.
2024-02-20 14:54:28 +00:00
Viktor Szépe
c191a83c5e
Fix typos configuration (#1742)
## Summary

Narrow down excludes for `typos` and fix 2 additional misspellings.

BTW pre-commit can be run in CI:
2176061490
2024-02-20 09:53:07 -05:00
Bas Zalmstra
daf2800ddf
feat: allow passing in a custom reqwest Client (#1745)
## Summary

I am looking to instantiate a `RegistryClient`. However, when using the
`RegistryClientBuilder` a new reqwest client is always constructed. I
would like to pass in a custom `reqwest::Client` to be able to share the
http resources with other parts of my application.

## Test Plan

The uv codebase does not use my addition to the builder and all tests
still succeed. And in my code I can pass a custom Client.
2024-02-20 09:50:18 -05:00
Charlie Marsh
dd7d533411
Set index URLs for seeding venv (#1755)
Just an oversight due to builder pattern.

Closes https://github.com/astral-sh/uv/issues/1752.
2024-02-20 14:49:16 +00:00
обоо
7741e1c51a
Print activation instructions for a venv after one has been created (#1580) 2024-02-20 12:39:42 +00:00
Charlie Marsh
d05cb8464a
Allow -f alias for --find-links (#1735)
## Summary

`pip` supports this, and I keep expecting it to exist in my testing.
2024-02-20 00:56:26 -05:00
Di-Is
36edaeecf2
Control pip timeout duration via environment variable (#1694)
<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

Add the environment variable `UV_REQUEST_TIMEOUT` to allow control over
pip timeouts.

Closes #1549 

## Test Plan

I built uv in the repository top Dockerfile, set the timeout to 3
seconds, and ran `uv pip install torch`.
I measured the execution time with the time command and confirmed that
the process finished at a value close to the timeout we set.

```bash
root@037c69228cdc:~# time UV_REQUEST_TIMEOUT=3 /uv pip install torch
Resolved 22 packages in 25ms
error: Failed to download distributions
  Caused by: Failed to fetch wheel: nvidia-cusolver-cu12==11.4.5.107
  Caused by: Failed to extract source distribution
  Caused by: request or response body error: operation timed out
  Caused by: operation timed out

real    0m3.064s
user    0m0.225s
sys     0m0.240s
```
2024-02-19 22:37:56 -06:00
Charlie Marsh
692c00defe
Implement uv cache dir (#1734)
## Summary

Like `pip cache dir`, merely prints out the cache directory.

Closes https://github.com/astral-sh/uv/issues/1646.
2024-02-19 23:29:10 -05:00
Charlie Marsh
bb876d95ed
Move uv clean to uv cache clean (#1733)
## Summary

This opens up space to add other cache-related commands. (`uv clean`
continues to work for backwards compatibility but is hidden from the
CLI.)
2024-02-20 04:14:05 +00:00
Charlie Marsh
254a94c40a
Use httpx instead of anyio for reinstall test (#1732)
This works on Windows.
2024-02-19 23:08:19 -05:00
Charlie Marsh
4b5b9835fd
Ensure extras trigger an install (#1727)
## Summary

We weren't respecting extras when auditing the existing environment.

Closes https://github.com/astral-sh/uv/issues/1726.
2024-02-20 03:37:35 +00:00
Charlie Marsh
a5372d4e4d
Ignore invalid extras from PyPI (#1731)
## Summary

We don't control these, so it seems preferable _not_ to fail on them,
but rather, to just ignore them entirely. (I considered adding a long
allow-list, but then questioned the point of it? We'd end up having to
extend it if more invalid extras were published in the future.)

Closes https://github.com/astral-sh/uv/issues/1633.
2024-02-19 22:26:29 -05:00
Charlie Marsh
402edf1522
Improve Poetry warning (#1730)
Good feedback from:
https://github.com/astral-sh/uv/pull/1650#discussion_r1495140531
2024-02-19 22:08:49 -05:00