Commit graph

1332 commits

Author SHA1 Message Date
Charlie Marsh
34acfe4ac6
Respect py --list-paths fallback in --python python3 invocations (#2214)
## Summary

This makes `--python python3` and `--python 3.10` more consistent on
Windows.

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

## Test Plan

Ran `cargo run venv --python python3.12` with the Windows Store Python.
2024-03-05 19:28:24 +00:00
Charlie Marsh
aeb80e345b
HTML-decode URLs in HTML indexes (#2215)
## Summary

If the index lists a URL like
`https://buf.build/gen/python/hashb-foxglove-protocolbuffers-python/hashb_foxglove_protocolbuffers_python-25.3.0.1.20240226043130+465630478360-py3-none-any.whl`,
we need to decode that to
`https://buf.build/gen/python/hashb-foxglove-protocolbuffers-python/hashb_foxglove_protocolbuffers_python-25.3.0.1.20240226043130+465630478360-py3-none-any.whl`.

Closes https://github.com/astral-sh/uv/issues/2202.
2024-03-05 19:26:54 +00:00
Charlie Marsh
01ebaef4e7
Avoid Windows Store shims in --python python3-like invocations (#2212)
## Summary

We have logic in `python_query.rs` to filter out Windows Store shims
when you use invocations like `-p 3.10`, but not `--python python3`,
which is uncommon but allowed on Windows.

Closes #2211.
2024-03-05 13:47:38 -05:00
Charlie Marsh
cf94df7cb9
Expand Windows shim detection to include python3.12.exe (#2209)
## Summary

Our Windows shim detection wasn't catching shims like `python3.12.exe`.

Closes #2208.

## Test Plan

Installed Python 3.12 via the Windows Store; verified that `cargo run
venv --python 3.12` failed before but passes after this change.
2024-03-05 13:25:05 -05:00
Charlie Marsh
8620b5a52f
Make direct dependency detection respect markers (#2207)
## Summary

When determining "direct" dependencies, we need to ensure that we
respect markers. In the linked issue, the user had an optional
dependency like:

```toml
[project.optional-dependencies]
dev = [
  "setuptools>=64",
  "setuptools_scm>=8"
]
```

By not respecting markers, we tried to resolve `setuptools` to the
lowest-available version. However, since `setuptools>=64` _isn't_
enabled (since it's optional), we won't respect _that_ constraint.

To be consistent, we need to omit optional dependencies just as we will
at resolution time.

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

## Test Plan

`cargo test`
2024-03-05 17:25:06 +00:00
Charlie Marsh
7f07ada24c
Allow direct URLs in optional dependencies in editables (#2206)
See the additional test, which fails on `main`.
2024-03-05 11:57:55 -05:00
Charlie Marsh
fc55cb9a3c
Respect nested editable requirements in parser (#2204)
Closes https://github.com/astral-sh/uv/issues/2198.
2024-03-05 16:47:37 +00:00
konsti
0924185a7f
Only use compile timeout for critical section (#2199)
Follow-up to #2086: Don't use timeouts for the entire workers, but only
for the section that's about communicating with the (potentially broken)
`python` subprocess. I've also raised the timeout to 60s.
2024-03-05 17:20:04 +01:00
Charlie Marsh
0bc047866d
Error when editables don't match Requires-Python (#2194)
## Summary

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

## Test Plan

(Needs tests.)
2024-03-04 23:20:42 -05:00
konsti
2a53e789b0
Add an option to bytecode compile during installation (#2086)
Add a `--compile` option to `pip install` and `pip sync`.

I chose to implement this as a separate pass over the entire venv. If we
wanted to compile during installation, we'd have to make sure that
writing is exclusive, to avoid concurrent processes writing broken
`.pyc` files. Additionally, this ensures that the entire site-packages
are bytecode compiled, even if there are packages that aren't from this
`uv` invocation. The disadvantage is that we do not update RECORD and
rely on this comment from [PEP 491](https://peps.python.org/pep-0491/):

> Uninstallers should be smart enough to remove .pyc even if it is not
mentioned in RECORD.

If this is a problem we can change it to run during installation and
write RECORD entries.

Internally, this is implemented as an async work-stealing subprocess
worker pool. The producer is a directory traversal over site-packages,
sending each `.py` file to a bounded async FIFO queue/channel. Each
worker has a long-running python process. It pops the queue to get a
single path (or exists if the channel is closed), then sends it to
stdin, waits until it's informed that the compilation is done through a
line on stdout, and repeat. This is fast, e.g. installing `jupyter
plotly` on Python 3.12 it processes 15876 files in 319ms with 32 threads
(vs. 3.8s with a single core). The python processes internally calls
`compileall.compile_file`, the same as pip.

Like pip, we ignore and silence all compilation errors
(https://github.com/astral-sh/uv/issues/1559). There is a 10s timeout to
handle the case when the workers got stuck. For the reviewers, please
check if i missed any spots where we could deadlock, this is the hardest
part of this PR.

I've added `uv-dev compile <dir>` and `uv-dev clear-compile <dir>`
commands, mainly for my own benchmarking. I don't want to expose them in
`uv`, they almost certainly not the correct workflow and we don't want
to support them.

Fixes #1788
Closes #1559
Closes #1928
2024-03-05 03:35:24 +00:00
Charlie Marsh
93b1395daa
Fallback to non-range requests when HEAD returns 404 (#2186)
## Summary

We have at least one reported case of this happening. It's preferable
IMO to move on rather than fail hard despite sub-pbar registry behavior.

Closes https://github.com/astral-sh/uv/issues/2099.
2024-03-04 22:18:49 -05:00
Charlie Marsh
60a78812f9
Extend system-install.yml to include virtualenv operations (#2190)
Just basic stuff like: we can create a virtualenv, we can install into
it (and not affect the system Python).
2024-03-05 01:46:00 +00:00
Charlie Marsh
7e1f361bb3
Add system install test for PyPy (#2189) 2024-03-04 19:44:18 -05:00
Charlie Marsh
a3c24e7bea
Add system install test for choco (#2185)
Test installing Python via `choco`.
2024-03-04 19:37:07 -05:00
dependabot[bot]
e66afa8767
Bump insta from 1.35.1 to 1.36.1 (#2180) 2024-03-04 23:01:49 +00:00
dependabot[bot]
bc43f609b9
Bump http from 0.2.11 to 0.2.12 (#2179) 2024-03-04 22:22:45 +00:00
dependabot[bot]
5aedcffdf0
Bump log from 0.4.20 to 0.4.21 (#2178) 2024-03-04 16:16:20 -06:00
dependabot[bot]
9fcffae084
Bump anstream from 0.6.12 to 0.6.13 (#2177) 2024-03-04 16:16:10 -06:00
Charlie Marsh
fbe043b093
Respect markers on URL dependencies in editables (#2176)
Closes https://github.com/astral-sh/uv/issues/2172.
2024-03-04 22:09:08 +00:00
Charlie Marsh
70143b8626
Run Windows against Python 3.13 (#2171)
## Summary

In Python 3.13, at least in the current builds, there's no `python.exe`,
but there is `venvlauncher.exe`.

I've asked here about whether it's intended:
https://discuss.python.org/t/when-should-venv-scripts-nt-python-exe-be-present/47620.
But there's at least some evidence in CPython
[here](d457345bbc/Lib/venv/__init__.py (L270))
that we should fall back to these, and the tests pass.

Closes https://github.com/astral-sh/uv/issues/1636.
2024-03-04 21:49:17 +00:00
Charlie Marsh
14d968ac22
Set .metadata suffix on URL path (#2123)
## Summary

Ensures that we don't add the `.metadata` suffix after the fragment, if
it exists.
2024-03-04 20:51:07 +00:00
Charlie Marsh
5fed1f6259
Use simpler pip-like Scheme for install paths (#2173)
## Summary

This will make it easier to use the paths returned by `distutils.py`
(for some cases). No code or behavior changes; just removing some fields
we don't need.
2024-03-04 15:50:13 -05:00
samypr100
93f5609476
feat: add uv version to user agent (#2136)
## Summary

Closes #1977

This allows us to send uv's version in the `uv-client` User Agent
header.

Here's how request headers look like to a server now:
```
...
Accept: application/vnd.pypi.simple.v1+json, application/vnd.pypi.simple.v1+html;q=0.2, text/html;q=0.01
User-Agent: uv/0.1.13
...
```

~~I went for a mix of Option 1 and 2 from #1977.~~ Open to alternative
naming as well, not tied too strongly here to the names picked.

~~Another possibility for this new crate is that we can use it to
consolidate metadata that exists across crates to ultimately be able to
create linehaul information described in #1958, but I haven't looked
into what those changes might look like.~~

<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan

<!-- How was it tested? -->
Added initial tests in the new crate to exercise its public API and
added a new test to uv-client to validate the headers using a 1-time
disposable server.
2024-03-04 19:48:41 +00:00
Charlie Marsh
fda691401a
Respect local freshness when auditing installed environment (#2169)
## Summary

Ensures that local dependencies function similarly to editables, in that
if they're `uv pip install`ed, we invalidate them.

Closes https://github.com/astral-sh/uv/issues/1651.
2024-03-04 19:40:52 +00:00
Charlie Marsh
8c51b59298
Allow empty values in WHEEL files (#2170)
## Summary

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

## Test Plan

`cargo run pip install "openturns==1.22"`
2024-03-04 19:39:01 +00:00
Charlie Marsh
6f94dc3c77
Centralize up-to-date checking for path installations (#2168)
## Summary

Internal-only refactor to consolidate multiple codepaths we have for
checking whether a cached or installed entry is up-to-date with a local
requirement.
2024-03-04 14:10:51 -05:00
Zanie Blue
ffb69e3f48
Expose the --exclude-newer flag (#2166)
Closes https://github.com/astral-sh/uv/issues/2088
2024-03-04 17:51:19 +00:00
Charlie Marsh
c525fdf2b5
Bump version to v0.1.14 (#2157) 2024-03-04 15:42:33 +00:00
konsti
898c3f6bcf
Better offline error message (#2110)
Error for `uv pip compile scripts/requirements/jupyter.in` without
internet:

**Before**

```
error: error sending request for url (https://pypi.org/simple/jupyter/): error trying to connect: dns error: failed to lookup address information: No such host is known. (os error 11001)
  Caused by: error trying to connect: dns error: failed to lookup address information: No such host is known. (os error 11001)
  Caused by: dns error: failed to lookup address information: No such host is known. (os error 11001)
  Caused by: failed to lookup address information:  No such host is known. (os error 11001)
```

**After**

```
error: Could not connect, are you offline?
  Caused by: error sending request for url (https://pypi.org/simple/django/): error trying to connect: dns error: failed to lookup address information: Temporary failure in name resolution
  Caused by: error trying to connect: dns error: failed to lookup address information: Temporary failure in name resolution
  Caused by: dns error: failed to lookup address information: Temporary failure in name resolution
  Caused by: failed to lookup address information: Temporary failure in name resolution
```

On linux, it would be "Temporary failure in name resolution" instead of
"No such host is known. (os error 11001)".

The implementation checks for "dne error" stringly as hyper errors are
opaque. The danger is that this breaks with a hyper update. We still get
the complete error trace since reqwest eagerly inlines errors
(https://github.com/seanmonstar/reqwest/issues/2147).

No test since i wouldn't know how to simulate this in cargo test.

Fixes #1971
2024-03-04 15:47:40 +01:00
konsti
bc0345a1fd
Make WHEEL parsing error line numbers one indexed. (#2151)
Fixes an off-by-one from #2149. `enumerate` is zero-based, human line
numbers are one based.
2024-03-04 11:55:18 +00:00
Charlie Marsh
836b90c760
Expand environment variables in -r and -c subfile paths (#2143)
## Summary

This PR expands environment variables in `-r` and `-c` paths _within_
requirements files. We already do this for `@` URL references and
others.

Closes https://github.com/astral-sh/uv/issues/1473.
2024-03-03 18:47:04 -05:00
Charlie Marsh
bf07c7bb72
Add tests for empty index URL environment variable (#2141) 2024-03-03 21:01:41 +00:00
Taniguchi Yasufumi
13a6fc8575
Make an empty string behave like the default (#2137)
## Summary

Resolve  #2129

I changed the behavior to parse an empty string for `--index-url` to be
the same as the default.
2024-03-03 14:57:14 -05:00
Charlie Marsh
6fa88f9be0
Use space as delimiter for UV_EXTRA_INDEX_URL (#2140)
## Summary

I was looking at something unrelated and saw this in the Clap docs.

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

## Test Plan

```shell
❯ UV_EXTRA_INDEX_URL="https://google.com https://foo.com" cargo run pip compile -
    Finished dev [unoptimized + debuginfo] target(s) in 0.14s
     Running `target/debug/uv pip compile -`
index: None
extra_index_url: [Url(VerbatimUrl { url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("google.com")), port: None, path: "/", query: None, fragment: None }, given: Some("https://google.com") }), Url(VerbatimUrl { url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("foo.com")), port: None, path: "/", query: None, fragment: None }, given: Some("https://foo.com") })]
```
2024-03-03 14:01:07 -05:00
Charlie Marsh
6a5379834b
Add support for Python installed from Windows Store (#2122)
## Summary

After https://github.com/astral-sh/uv/pull/2121, the only remaining
issue is that calling `canonicalize` on these Pythons returns an error.

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

## Test Plan

Uninstalled all python.org Pythons on my Windows machine, then created a
virtualenv. The resulting config file:

```
Using Python 3.11.8 interpreter at: C:\Users\crmar\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\python.exe
Creating virtualenv at: .venv
Activate with: .venv\Scripts\activate
PS C:\Users\crmar\workspace\puffin> cat .\.venv\pyvenv.cfg
home = C:\Users\crmar\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0
implementation = CPython
version_info = 3.11.8
include-system-site-packages = false
uv = 0.1.13
prompt = puffin
```

Prior to this PR, it would fail with a canonicalization error.

Prior to #2121, it would leave a "bad" Python in the config file:

```
Using Python 3.11.8 interpreter at: C:\Users\crmar\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\python.exe
Creating virtualenv at: .venv
Activate with: .venv\Scripts\activate
PS C:\Users\crmar\workspace\puffin> cat .\.venv\pyvenv.cfg
home = C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2288.0_x64__qbz5n2kfra8p0
implementation = CPython
version_info = 3.11.8
include-system-site-packages = false
uv = 0.1.13
prompt = puffin
```

Which, once activated, would fail with:

```
(venv) PS C:\Users\crmar\workspace\puffin> python
No Python at '"C:\Users\crmar\AppData\Local\Programs\Python\Python312\python.exe'
```
2024-03-03 17:55:36 +00:00
Charlie Marsh
46265b711b
Adjust base Python lookup logic for Windows (#2121)
## Summary

When I install via the Windows Store, `interpreter.base_prefix` contains
a bunch of resolved information that leads to a broken environment.

Instead, we now use `sys._base_executable` on Windows by default,
falling back to `sys.base_prefix` if it doesn't exist. (There are some
issues with `sys.base_executable` that lead to complexity in
`virtualenv`, but they only affect POSIX.) Admittedly, I don't know when
`sys._base_executable` wouldn't exist. It exists in all the environments
I've tested.

Additionally, we use the system interpreter directly if we're outside of
a virtualenv.
2024-03-03 17:44:10 +00:00
Nyakku Shigure
d4f1973bdc
Allow empty extras in pep508-rs and add more corner case to tests (#2128)
## Summary

Fixes #2127, allow empty extras, and add more corner case to tests

## References

- [PEP 508 grammar](https://peps.python.org/pep-0508/#complete-grammar)
2024-03-02 20:36:28 +00:00
Charlie Marsh
782a862e92
Add caveats on --system support to the README (#2131)
## Summary

Covering some of the limitations from
https://github.com/astral-sh/uv/issues/2113.
2024-03-02 10:07:57 -05:00
Charlie Marsh
e7f336ac53
Preserve environment variables in resolved Git dependencies (#2125)
## Summary

Closes https://github.com/astral-sh/uv/issues/2116.
2024-03-01 20:38:34 -05:00
samypr100
5083f51d68
docs: add note about ssl_cert_file env var (#2124) 2024-03-02 01:37:27 +00:00
samypr100
c7c3affee0
feat: report line and column on requirements parser errors (#2100)
## Summary

Closes #2012

This changes `RequirementsTxtParserError::Parser` to take a line, column
instead of cursor location to improve reporting of parser errors. A new
function was added to compute the line and column based on the content
and cursor location when a parser error occurs for simplicity.

Given `uv pip compile .\requirements.txt` of below
```
numpy>=1,<2
  --borken
tqdm
```

Before:

``` 
error: Unexpected '-', expected '-c', '-e', '-r' or the start of a requirement in `.\requirements.txt` at position 14
```

After:

```
error: Unexpected '-', expected '-c', '-e', '-r' or the start of a requirement in `.\requirements.txt` at position 2:3
```

Open Question: Do we want to support `line:column` for other types of
errors? I didn't look dig other potential error types where this might
be desired.

## Test Plan

New test was added to `requirements-txt` crate with this example.
2024-03-01 21:50:11 +00:00
Charlie Marsh
0233a5771d
Remove base-prefix and friends from pyvenv.cfg (#2120)
## Summary

It looks like these have been included since the very first gourgeist
commit, but `virtualenv` and `venv` don't include them, and they only
add complexity AFAICT.
2024-03-01 16:17:30 -05:00
Charlie Marsh
6f54aacfea
Remove camino from uv-virtualenv (#2119)
## Summary

I think Camino is nice but it makes it much harder to work in
`uv-virtualenv`, since it's the _only_ crate that uses it. If we want to
use Camino, we should use it everywhere IMO.
2024-03-01 19:36:56 +00:00
Charlie Marsh
59c7a10c4b
Rename gourgeist to uv-virtualenv (#2118)
As agreed on Discord!
2024-03-01 14:02:40 -05:00
Charlie Marsh
b818199403
Use prefix instead of base_prefix for environment root (#2117)
Closes https://github.com/astral-sh/uv/issues/2107.
2024-03-01 13:12:49 -05:00
Charlie Marsh
72dc72496f
Consider editable dependencies to be 'direct' (#2114)
Closes https://github.com/astral-sh/uv/issues/2112.
2024-03-01 11:00:45 -05:00
Charlie Marsh
c9ffe976f9
Centralize virtualenv path construction (#2102)
## Summary

Right now, we have virtualenv construction encoded in a few different
places. Namely, it happens in both `gourgeist` and
`virtualenv_layout.rs` -- _and_ `interpreter.rs` also encodes some
knowledge about how they work, by way of reconstructing the
`SysconfigPaths`.

Instead, `gourgeist` now returns the complete layout, enumerating all
the directories it created. So, rather than returning a root directory,
and re-creating all those paths in `uv-interpreter`, we pass the data
directly back to it.
2024-03-01 15:52:48 +00:00
Charlie Marsh
c579e6f6bf
Add support for --system-site-packages in uv venv (#2101)
## Summary

Adds support for `--system-site-packages`. Unlike `pip`, we won't take
the system site packages into account in subsequent commands. I think
this is ok.

Closes https://github.com/astral-sh/uv/issues/1483.
2024-03-01 09:05:19 -05:00
konsti
d0ffabd1f2
Future-proof pip entrypoints special case (#1982)
Update #1918 to handle https://github.com/pypa/pip/pull/12536, where pip
removed their python minor entrypoint. The pip test is semi-functional
since it builds pip from source instead of using a wheel with the wrong
entrypoint, we have to update it when this pip version has a release.

Closes #1593.
2024-03-01 10:05:50 +01:00
Charlie Marsh
e811070ef1
Wrap unsafe script shebangs in /bin/sh (#2097)
## Summary

This is based on Pradyun's installer branch
(d01624e5f2/src/installer/scripts.py (L54)),
which is itself based on pip
(0ad4c94be7/src/pip/_vendor/distlib/scripts.py (L136)).

The gist of it is: on Posix platforms, if a path contains a space (or is
too long), we wrap the shebang in a `/bin/sh` invocation.

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

## Test Plan

```
❯ cargo run venv "foo"
    Finished dev [unoptimized + debuginfo] target(s) in 0.14s
     Running `target/debug/uv venv foo`
Using Python 3.12.0 interpreter at: /Users/crmarsh/.local/share/rtx/installs/python/3.12.0/bin/python3
Creating virtualenv at: foo
Activate with: source foo/bin/activate

❯ source "foo bar/bin/activate"

❯ which black
black not found

❯ cargo run pip install black
Resolved 6 packages in 177ms
Installed 6 packages in 17ms
 + black==24.2.0
 + click==8.1.7
 + mypy-extensions==1.0.0
 + packaging==23.2
 + pathspec==0.12.1
 + platformdirs==4.2.0

❯ which black
/Users/crmarsh/workspace/uv/foo bar/bin/black

❯ black
Usage: black [OPTIONS] SRC ...

One of 'SRC' or 'code' is required.

❯ cat "foo bar/bin/black"
#!/bin/sh
'''exec' '/Users/crmarsh/workspace/uv/foo bar/bin/python' "$0" "$@"
' '''
# -*- coding: utf-8 -*-
import re
import sys
from black import patched_main
if __name__ == "__main__":
    sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0])
    sys.exit(patched_main())
```
2024-02-29 23:19:06 +00:00