Commit graph

957 commits

Author SHA1 Message Date
Charlie Marsh
facc60f3a8
Add graceful fallback for Artifactory indexes (#1574)
## Summary

There are more details in https://github.com/astral-sh/uv/issues/1370,
but it looks like Artifactory servers have incorrect behavior when it
comes to HTTP range requests, in that they return `Accept-Ranges:
bytes`, but then incorrectly return 200 requests when you actually ask
for a given range.

This PR ensures that we fallback gracefully in this case. It's built on
https://github.com/prefix-dev/async_http_range_reader/pull/5. Assuming
that gets merged upstream, we can then remove the Git dependency.

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

## Test Plan

`cargo run pip install requests -i
https://killjoyuvbug.jfrog.io/artifactory/api/pypi/pypi/simple
--verbose`
2024-02-17 14:37:06 +00:00
Charlie Marsh
12fea1d058
Always run get_requires_for_build_wheel (#1590)
## Summary

I want to revisit this as I think it's still skippable in some cases,
but for now, let's be more conservative.

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

## Test Plan

Cloned
`3aea423569/setup/mis_builder/setup.py (L4)`,
and ran `cargo run pip install -e mis_builder`.
2024-02-17 09:24:58 -05:00
Zanie Blue
563c636aa0
Improve tracing when encountering invalid requires-python values (#1568)
Unsure what the easiest way to test this is, it is hard to publish
invalid requires-python specifiers with hatchling
2024-02-17 07:40:13 -05:00
Shantanu
5d58d4fd2e
Better error messages on expect failures in resolver (#1583)
I ran into some (tricky to reproduce) panics while using uv, would be
useful to have a better error message to track down the source of the
problem
2024-02-17 07:39:10 -05:00
Zanie Blue
bb7c3e6b58
Avoid using white coloring in terminal output (#1576)
Closes https://github.com/astral-sh/uv/issues/1489
2024-02-17 01:59:20 -06:00
Charlie Marsh
340cb67a8b
Allow non-nested archives for hexdump and others (#1564)
## Summary#1562 

It turns out that `hexdump` uses an invalid source distribution format
whereby the contents aren't nested in a top-level directory -- instead,
they're all just flattened at the top-level. In looking at pip's source
(51de88ca64/src/pip/_internal/utils/unpacking.py (L62)),
it only strips the top-level directory if all entries have the same
directory prefix (i.e., if it's the only thing in the directory). This
PR accommodates these "invalid" distributions.

I can't find any history on this method in `pip`. It looks like it dates
back over 15 years ago, to before `pip` was even called `pip`.

Closes https://github.com/astral-sh/uv/issues/1376.
2024-02-16 23:17:36 -05:00
Charlie Marsh
4a09889c80
Enforce URL constraints for non-URL dependencies (#1565)
## Summary

This was just a missing line -- we have `dependencies.remove(&package);`
in the ~identical branch above, but it must've been an oversight to omit
it here.

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

## Test Plan

`cargo test`
2024-02-17 03:11:28 +00:00
Charlie Marsh
f897ee3f88
Allow repeated dependencies when installing (#1558)
## Summary

It turns out that it's not uncommon to end up with repeated packages in
requirements files when running `pip-sync`, e.g., you might have
`anyio==4.0.0` specified multiple times. This PR relaxes our assertions
in the install plan to allow such repeated packages, as long as the
requirement markers are exactly the same (i.e., they are truly
duplicates).

Closes https://github.com/astral-sh/uv/issues/1552.
2024-02-17 01:33:40 +00:00
Charlie Marsh
1110489c29
Bump version to v0.1.3 (#1557) 2024-02-16 19:45:29 -05:00
Charlie Marsh
c1eb6130e1
Support MD5 hashes (#1556)
## Summary

We can add other hashes if necessary, but I don't know that they're
really used in practice.

Closes https://github.com/astral-sh/uv/issues/1547.
2024-02-17 00:25:16 +00:00
Charlie Marsh
9e0336c28a
Remove URL encoding when determining file name (#1555)
## Summary

Closes https://github.com/astral-sh/uv/issues/1553.
2024-02-16 19:15:24 -05:00
Charlie Marsh
6392961f44
Add support for extras in editable requirements (#1531)
## Summary

If you're developing on a package like `attrs` locally, and it has a
recursive extra like `attrs[dev]`, it turns out that we then try to find
the `attrs` in `attrs[dev]` from the registry, rather than recognizing
that it's part of the editable.

This PR fixes the issue by making editables slightly more first-class
throughout the resolver. Instead of mocking metadata, we explicitly
check for extras in various places. Part of the problem here is that we
treated editables as URL dependencies, but when we saw an _extra_ like
`attrs[dev]`, we didn't map that back to the URL. So now, we treat them
as registry dependencies, but with the appropriate guardrails
throughout.

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

## Test Plan

- Cloned `attrs`.
- Ran `cargo run venv && cargo run pip install -e ".[dev]" -v`.
2024-02-16 18:48:35 -05:00
Charlie Marsh
4e0b6f8f84
Avoid attempting rename in copy fallback path (#1546)
## Summary

This _could_ fix https://github.com/astral-sh/uv/issues/1454, but I'm
not sure. I was able to replicate by forcing a bunch of error states.
But, in short, if we fail to hardlink on the initial copy due to a file
existing, and then fail _again_, we fallback to copying. But if we copy,
then the tempfile doesn't exist, and so the `fs_err::rename(&tempfile,
&out_path)?;` will fail with "File not found".

This PR just ensures that the cases are explicitly mutually exclusive:
we only attempt to rename if the hardlink succeeded.
2024-02-16 17:08:49 -05:00
David Szotten
8050370717
Fix trailing commas on Requires-Python in HTML indexes (#1507)
illustration and suggested fix for #1464
2024-02-16 22:05:28 +00:00
Charlie Marsh
4f216f3a74
Apply percent-decoding to filepaths in HTML find-links (#1544)
## Summary

Closes https://github.com/astral-sh/uv/issues/1542.
2024-02-16 16:47:04 -05:00
Andrew Gallant
3aa7a6b796
fix OS detection for Alpine Linux (#1545)
This PR fixes the OS detection for Alpine Linux such that the version
of musl available is correctly determined. The issue boiled down to
a regex that required 2 digits for each version component. But a
valid musl version is 1.2.4, which only has a single digit for each
component.

It's unclear how this was working for musl before this change. My
theory is that our other methods of OS detection were somehow working.

The first commit in this PR cleans up our Linux detection logic and adds
lots of tracing calls to make debugging issues like this easier in the
future. To do so, one can run:

    $ RUST_LOG=trace uv pip install -v whatever

The second commit has the actual fix.

Fixes #1427
2024-02-16 16:37:18 -05:00
Charlie Marsh
b4ea48955b
Use comparable representation for PackageId (#1543)
## Summary

By using the display representation of `Version` to form a `PackageId`,
we run the risk (as seen in the linked issue) of thinking that versions
like `2021.1` and `2021.1.0` are not equivalent.

Closes https://github.com/astral-sh/uv/issues/1536
2024-02-16 16:30:54 -05:00
Charlie Marsh
01ffc36520
Apply percent-decoding to file-based URLs (#1541)
## Summary

Closes https://github.com/astral-sh/uv/issues/1537.
2024-02-16 16:11:16 -05:00
Andrew Gallant
a97c207674
pypi-types: fix lenient requirement parsing (#1529)
This fixes a bug where `uv pip install` failed to install `polars`:

```
$ uv pip install polars==0.14.0
error: Failed to download: polars==0.14.0
  Caused by: Couldn't parse metadata of polars-0.14.0-cp37-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl from 749022b096/polars-0.14.0-cp37-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
  Caused by: Operator >= cannot be used with a wildcard version specifier
pyarrow>=4.0.*; extra == 'pyarrow'
       ^^^^^^^
```

Since `pyarrow>=4.0.*; extra == 'pyarrow'` is invalid *and* it comes
from the metadata of a dependency (that isn't under the control of the
end user), we actually attempt to "fix" it. Namely, wildcard
dependency specifications are only allowed with `==` and `!=`, as per
the [Version Specifiers spec]. (They aren't explicitly forbidden in
these cases, but instead only have specified behavior for the `==` and
`!=` operators.)

This is all fine, but it turns out that when we fix the `>=4.0.*`
component, we also strip the quotes around `pyarrow`. (Because some
dependency specifications include stray quotes.) We fix this by making
our quote stripping a bit more selective. (We require that it appear
adjacent to a digit or a `*`.)

Note that #1477 also reports this error:

```
$ uv pip install 'requests>=2.30.*'
error: Failed to parse `requests>=2.30.*`
  Caused by: Operator >= cannot be used with a wildcard version specifier
requests>=2.30.*
```

However, we specifically keep that error message since it's something
under the end user's control. And similarly for a dependency
specification in a `requirements.txt` file.

Fixes #1477

[Version Specifiers spec]:
https://packaging.python.org/en/latest/specifications/version-specifiers/
2024-02-16 15:52:44 -05:00
Zanie Blue
d5e8531ae3
Add support for UV_EXTRA_INDEX_URL (#1515)
Closes https://github.com/astral-sh/uv/issues/1450
2024-02-16 12:54:58 -06:00
Zanie Blue
2ea44d863a
Add warning for empty requirements files (#1519)
Also, improve tracing of requirements file parsing.

Per my confusion in #1334
2024-02-16 18:19:09 +00:00
Zanie Blue
89ad1c6fa1
Add pip install --constraint test coverage (#1334)
Exploring behavior reported in
https://github.com/astral-sh/uv/issues/1332
2024-02-16 17:39:39 +00:00
Charlie Marsh
f25781ff6c
Support recursive extras (#1435)
## Summary

We had a guard in the resolve to avoid "self-dependencies" (as in
`gps3==0.33.3`), but this guard was _unintentionally_ filtering out
recursive extras.

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

## Test Plan

Taken from https://github.com/astral-sh/uv/pull/1352.
2024-02-16 11:42:04 -05:00
Zanie Blue
e6c4c77ba1
Use string display instead of debug for url parse trace (#1498)
e.g. 

`uv_client::html::parse
url=https://download.pytorch.org/whl/torch_stable.html`

instead of

`uv_client::html::parse url=Url { scheme: "https", cannot_be_a_base:
false, username: "", password: None, host:
Some(Domain("download.pytorch.org")), port: None, path:
"/whl/torch_stable.html", query: None, fragment: None }`
2024-02-16 15:13:16 +00:00
Andrew Gallant
67cde15420
only parse /bin/sh (not /bin/ls) (#1493)
It turns out that /bin/ls can sometimes be plain text file. For
example, in Rocky Linux 9:

```
$ cat /bin/ls
#!/usr/bin/coreutils --coreutils-prog-shebang=ls
```

However, `/bin/sh` is an ELF binary:

```
$ file /bin/sh
/bin/sh: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=7acbb41bf6f1b7d977f1b44675bf3ed213776835, for GNU/Linux 3.2.0, stripped
```

In a related issue (#1433), @zanieb fixed #1395 where, on NixOS,
`/bin/ls` doesn't exist but `/bin/sh` does. However, the fix attempts
`/bin/ls` first and only tries `/bin/sh` if `/bin/ls` doesn't exist. If
`/bin/ls` exists but isn't a valid ELF file, then the entire enterprise
gives up and `uv` fails to detect the version of `libc` that is
installed.

Instead of tweaking the logic to keep trying `/bin/ls` and then
`/bin/sh` after even if parsing `/bin/ls` fails, we just switch over to
reading `/bin/sh` only. It seems like a more fundamental thing to sniff
and likely less error prone.

We can adjust this heuristic as needed if it provdes to be problematic.

I tested this fix manually on Rocky Linux 9 via Docker:

```
$ cross b -r -p uv --target x86_64-unknown-linux-musl
$ cp target/x86_64-unknown-linux-musl/release/uv ~/astral/issues/uv/i1486/uv
$ docker run --rm -it --mount type=bind,src=/home/andrew/astral/issues/uv/i1486,dst=/host rockylinux:9 bash
[root@df2baa65d2f8 /]# /host/uv venv
Using Python 3.9.18 interpreter at /usr/bin/python3.9
Creating virtualenv at: .venv
[root@df2baa65d2f8 /]#
```

Fixes #1486, Ref #1433
2024-02-16 09:44:47 -05:00
Micha Reiser
e913167849
Fix list rendering in venv --help output (#1459) 2024-02-16 15:36:36 +01:00
Aarni Koskela
3280562e3a
Loosen package script regexp to match spec (#1482)
Fixes #1479.
2024-02-16 09:25:32 -05:00
Zanie Blue
d99c4cacdf
Read from /bin/sh if /bin/ls cannot be found when determing libc path (#1433)
I'm not sure if we should just switch to _always_ reading from sh
instead? I don't love that all these errors are strings and I if
`/bin/ls` exists but can't be parsed we still won't try `/bin/sh`. We
may want to address these things in the future.

Closes https://github.com/astral-sh/uv/issues/1395
2024-02-16 07:51:34 -05:00
Charlie Marsh
c474370064
Allow empty fragments in HTML parser (#1443)
## Summary

It looks like `devpi` might add an empty fragment (`#`) at the end of
the URL. We expect it to contain the hash; this just makes
empty-fragment map to "no hash".

Closes https://github.com/astral-sh/uv/issues/1441.
2024-02-16 06:42:21 +00:00
Charlie Marsh
659327f24a
Bump version to v0.1.2 (#1439) 2024-02-16 01:17:19 -05:00
Charlie Marsh
0d005a2a71
Decode HTML escapes when extracting SHA (#1440)
## Summary

If a distribution contains a `+`, it'll be HTML-escaped; so when we try
to identify the `#`, we'll split in the wrong location.

Closes https://github.com/astral-sh/uv/issues/1338.
2024-02-16 06:15:51 +00:00
Charlie Marsh
958e88ddbf
Ignore invalid extra named .none (#1428)
## Summary

Some packages erroneously include an extra named `.none`. It turns out
that certain versions of `flit` included this by accident:
https://github.com/pypa/flit/issues/228/.

This PR adds leniency for that specific extra name.

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

Closes https://github.com/astral-sh/uv/issues/1399.
2024-02-16 05:01:21 +00:00
Zanie Blue
0bfce353fb
Fix broken URLs parsed from relative paths in registries (#1413)
Closes https://github.com/astral-sh/uv/issues/1388

Fixes incorrect handling of relative paths returned by indexes without
an explicit `<base>`.

`Url.join` will drop the last segment in an url e.g. `http://foo/bar` ->
`http://foo/baz` if there is not a trailing slash but what we want is
`http://foo/bar/baz`. We don't add the trailing `/` in
`base_url_join_relative` because flat indexes are `http://foo/bar.html`
and we _want_ `bar.html` to be replaced.
2024-02-15 22:37:09 -06:00
Charlie Marsh
e48edf02fa
Parse -r and -c entries as relative to containing file (#1421)
## Summary

In a `requirements.txt` file, it turns out that the `-c` and `-r`
entries should be interpreted as relative to the file in which they're
declared, while the `-e` entries should be interpreted as relative to
the current working directory, no matter where they're defined.

Previously, we always used the current working directory; now, we use
the declaring file's directory for `-c` and `-r`.

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

Closes https://github.com/astral-sh/uv/issues/1416.
2024-02-15 23:19:43 -05:00
Charlie Marsh
1837641138
Add fix-up for invalid star comparison with major-only version (#1410)
## Summary

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

## Test Plan

Ran `cargo run pip install junos-eznc==2.6.5`, which still fails for me,
but fails identically to `pip` (and not on the `requires-python`):

```
/private/var/folders/nt/6gf2v7_s3k13zq_t3944rwz40000gn/T/.tmp7mxT9L/built-wheels-v0/pypi/ncclient/0.6.13/4vvPwmDC_CL2OUXd68Zqb/ncclient-0.6.13.tar.gz/versioneer.py:421: SyntaxWarning: invalid escape sequence '\s'
  LONG_VERSION_PY['git'] = '''
Traceback (most recent call last):
  File "<string>", line 10, in <module>
  File "/private/var/folders/nt/6gf2v7_s3k13zq_t3944rwz40000gn/T/.tmplD5mMO/.venv/lib/python3.12/site-packages/setuptools/build_meta.py", line 366, in prepare_metadata_for_build_wheel
    self.run_setup()
  File "/private/var/folders/nt/6gf2v7_s3k13zq_t3944rwz40000gn/T/.tmplD5mMO/.venv/lib/python3.12/site-packages/setuptools/build_meta.py", line 480, in run_setup
    super().run_setup(setup_script=setup_script)
  File "/private/var/folders/nt/6gf2v7_s3k13zq_t3944rwz40000gn/T/.tmplD5mMO/.venv/lib/python3.12/site-packages/setuptools/build_meta.py", line 311, in run_setup
    exec(code, locals())
  File "<string>", line 45, in <module>
  File "/private/var/folders/nt/6gf2v7_s3k13zq_t3944rwz40000gn/T/.tmp7mxT9L/built-wheels-v0/pypi/ncclient/0.6.13/4vvPwmDC_CL2OUXd68Zqb/ncclient-0.6.13.tar.gz/versioneer.py", line 1480, in get_version
    return get_versions()["version"]
           ^^^^^^^^^^^^^^
  File "/private/var/folders/nt/6gf2v7_s3k13zq_t3944rwz40000gn/T/.tmp7mxT9L/built-wheels-v0/pypi/ncclient/0.6.13/4vvPwmDC_CL2OUXd68Zqb/ncclient-0.6.13.tar.gz/versioneer.py", line 1412, in get_versions
    cfg = get_config_from_root(root)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/private/var/folders/nt/6gf2v7_s3k13zq_t3944rwz40000gn/T/.tmp7mxT9L/built-wheels-v0/pypi/ncclient/0.6.13/4vvPwmDC_CL2OUXd68Zqb/ncclient-0.6.13.tar.gz/versioneer.py", line 342, in get_config_from_root
    parser = configparser.SafeConfigParser()
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'configparser' has no attribute 'SafeConfigParser'. Did you mean: 'RawConfigParser'?
```
2024-02-16 02:12:10 +00:00
Charlie Marsh
7994b68654
Add fix-up for trailing comma with trailing space (#1409)
## Summary

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

## Test Plan

```text
Resolved 3 packages in 243ms
Downloaded 3 packages in 193ms
Installed 3 packages in 6ms
 + et-xmlfile==1.1.0
 + jdcal==1.4.1
 + openpyxl==3.0.5
```
2024-02-16 02:08:05 +00:00
Zanie Blue
0f554b0913
Add -U/-P short flags for --upgrade/--upgrade-package (#1394)
Closes https://github.com/astral-sh/uv/issues/1340
2024-02-16 01:34:19 +00:00
Zanie Blue
896ab1c54f
Add --upgrade support to pip install (#1379)
Adds support for `--upgrade` — similar to `--reinstall`.

Closes https://github.com/astral-sh/uv/issues/1391
2024-02-15 19:25:28 -06:00
Shantanu
e9d82cf0fa
Avoid import contextlib in _virtualenv (#1406)
No need to pay 3ms on basically every Python invocation. I opened a PR
upstream last week: https://github.com/pypa/virtualenv/pull/2688
2024-02-15 20:23:05 -05:00
Robin Krahl
f9a9f53476
Improve error message for invalid sdist archives (#1389)
This PR improves the error message for the problem described in
https://github.com/astral-sh/uv/issues/1376. The original output
duplicates the actual error message and includes lots of noise
(`DirEntry { inner: DirEntry(...) }`).

```
$ uv pip install hexdump==3.3
error: Failed to download and build: hexdump==3.3
  Caused by: Failed to extract source distribution: The top level of the archive must only contain a list directory, but it contains: [DirEntry { inner: DirEntry("/home/robin/.cache/uv/.tmpgSvTCk/__main__.py") }, DirEntry { inner: DirEntry("/home/robin/.cache/uv/.tmpgSvTCk/hexdump.py") }, DirEntry { inner: DirEntry("/home/robin/.cache/uv/.tmpgSvTCk/data") }, DirEntry { inner: DirEntry("/home/robin/.cache/uv/.tmpgSvTCk/PKG-INFO") }, DirEntry { inner: DirEntry("/home/robin/.cache/uv/.tmpgSvTCk/setup.py") }, DirEntry { inner: DirEntry("/home/robin/.cache/uv/.tmpgSvTCk/README.txt") }]
  Caused by: The top level of the archive must only contain a list directory, but it contains: [DirEntry { inner: DirEntry("/home/robin/.cache/uv/.tmpgSvTCk/__main__.py") }, DirEntry { inner: DirEntry("/home/robin/.cache/uv/.tmpgSvTCk/hexdump.py") }, DirEntry { inner: DirEntry("/home/robin/.cache/uv/.tmpgSvTCk/data") }, DirEntry { inner: DirEntry("/home/robin/.cache/uv/.tmpgSvTCk/PKG-INFO") }, DirEntry { inner: DirEntry("/home/robin/.cache/uv/.tmpgSvTCk/setup.py") }, DirEntry { inner: DirEntry("/home/robin/.cache/uv/.tmpgSvTCk/README.txt") }]
```

This PR removes the duplication and `DirEntry` internals so that the
error message is easier to grasp:

```
$ uv pip install hexdump==3.3
error: Failed to download and build: hexdump==3.3
  Caused by: Failed to extract source distribution
  Caused by: The top level of the archive must only contain a list directory, but it contains: ["__main__.py", "hexdump.py", "data", "PKG-INFO", "setup.py", "README.txt"]
```
2024-02-15 18:03:23 -06:00
Zanie Blue
c6a43e92f9
Add UV_NO_CACHE environment variable (#1383)
It's a little picky about the value, but that seems okay.

```
❯ ./target/debug/uv pip install trio
Audited 1 package in 4ms
❯ UV_NO_CACHE=true ./target/debug/uv pip install trio
Audited 1 package in 50ms
```

Closes #1382
2024-02-15 23:34:42 +00:00
mikcl
fbd6d87214
uv-cache: Add hidden alias for --no-cache-dir (#1380)
This is for compatability with pip install --no-cache-dir

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

Signed-off-by: mikcl <mikesmikes400@gmail.com>
2024-02-15 23:26:16 +00:00
Zanie Blue
18a7c079de
Fix search for python.exe on Windows (#1381)
A la #1351
2024-02-15 17:25:20 -06:00
Zanie Blue
e0885b7c8e
Bump version to 0.1.1 (#1359) 2024-02-15 15:38:22 -06:00
Yannik Sander
36544e1678
Fix diagram alignment (#1354)
Drive by alignment PR for the trait structure diagram
2024-02-15 15:32:33 -06:00
Zanie Blue
102e5ddfbe
Fix bug where python3 is not found in the global path (#1351)
When we refactored handling for Windows tests, we accidentally dropped
`python3` from path searches.
2024-02-15 15:29:33 -06:00
Charlie Marsh
27177613d4
Bump version to v0.1.0 (#1325) 2024-02-15 14:12:23 -05:00
Zanie Blue
0780afff95
Rename PUFFIN environment variables to UV (#1319)
A couple of these are actually user-facing although undocumented
2024-02-15 12:49:27 -06:00
Charlie Marsh
0579a04014
Bump to v0.0.5 for pre-release (#1324)
This is easier than figuring out the version parsing.
2024-02-15 18:33:34 +00:00
Charlie Marsh
ad12d97e71
Set crate to prerelease (#1320) 2024-02-15 18:21:09 +00:00