Commit graph

95 commits

Author SHA1 Message Date
renovate[bot]
e3ae876801
Update Rust crate itertools to 0.13.0 (#3664) 2024-05-20 00:49:42 +00:00
Ibraheem Ahmed
39af09f09b
Parallelize resolver (#3627)
## Summary

This PR introduces parallelism to the resolver. Specifically, we can
perform PubGrub resolution on a separate thread, while keeping all I/O
on the tokio thread. We already have the infrastructure set up for this
with the channel and `OnceMap`, which makes this change relatively
simple. The big change needed to make this possible is removing the
lifetimes on some of the types that need to be shared between the
resolver and pubgrub thread.

A related PR, https://github.com/astral-sh/uv/pull/1163, found that
adding `yield_now` calls improved throughput. With optimal scheduling we
might be able to get away with everything on the same thread here.
However, in the ideal pipeline with perfect prefetching, the resolution
and prefetching can run completely in parallel without depending on one
another. While this would be very difficult to achieve, even with our
current prefetching pattern we see a consistent performance improvement
from parallelism.

This does also require reverting a few of the changes from
https://github.com/astral-sh/uv/pull/3413, but not all of them. The
sharing is isolated to the resolver task.

## Test Plan

On smaller tasks performance is mixed with ~2% improvements/regressions
on both sides. However, on medium-large resolution tasks we see the
benefits of parallelism, with improvements anywhere from 10-50%.

```
./scripts/requirements/jupyter.in
Benchmark 1: ./target/profiling/baseline (resolve-warm)
  Time (mean ± σ):      29.2 ms ±   1.8 ms    [User: 20.3 ms, System: 29.8 ms]
  Range (min … max):    26.4 ms …  36.0 ms    91 runs
 
Benchmark 2: ./target/profiling/parallel (resolve-warm)
  Time (mean ± σ):      25.5 ms ±   1.0 ms    [User: 19.5 ms, System: 25.5 ms]
  Range (min … max):    23.6 ms …  27.8 ms    99 runs
 
Summary
  ./target/profiling/parallel (resolve-warm) ran
    1.15 ± 0.08 times faster than ./target/profiling/baseline (resolve-warm)
```
```
./scripts/requirements/boto3.in   
Benchmark 1: ./target/profiling/baseline (resolve-warm)
  Time (mean ± σ):     487.1 ms ±   6.2 ms    [User: 464.6 ms, System: 61.6 ms]
  Range (min … max):   480.0 ms … 497.3 ms    10 runs
 
Benchmark 2: ./target/profiling/parallel (resolve-warm)
  Time (mean ± σ):     430.8 ms ±   9.3 ms    [User: 529.0 ms, System: 77.2 ms]
  Range (min … max):   417.1 ms … 442.5 ms    10 runs
 
Summary
  ./target/profiling/parallel (resolve-warm) ran
    1.13 ± 0.03 times faster than ./target/profiling/baseline (resolve-warm)
```
```
./scripts/requirements/airflow.in 
Benchmark 1: ./target/profiling/baseline (resolve-warm)
  Time (mean ± σ):     478.1 ms ±  18.8 ms    [User: 482.6 ms, System: 205.0 ms]
  Range (min … max):   454.7 ms … 508.9 ms    10 runs
 
Benchmark 2: ./target/profiling/parallel (resolve-warm)
  Time (mean ± σ):     308.7 ms ±  11.7 ms    [User: 428.5 ms, System: 209.5 ms]
  Range (min … max):   287.8 ms … 323.1 ms    10 runs
 
Summary
  ./target/profiling/parallel (resolve-warm) ran
    1.55 ± 0.08 times faster than ./target/profiling/baseline (resolve-warm)
```
2024-05-17 11:47:30 -04:00
Charlie Marsh
55aedda379
Separate cache construction from initialization (#3607)
## Summary

Ensures that we only initialize the cache for commands that require it.

Closes https://github.com/astral-sh/uv/issues/3539.
2024-05-15 12:29:39 -04:00
Charlie Marsh
30a7475029
Create lib64 symlink for 64-bit, non-macOS, POSIX environments (#3584)
## Summary

Closes
https://github.com/astral-sh/uv/issues/3578#issuecomment-2110675382.

## Test Plan

Verified that in the OpenSUSE test, we create both, and they're
symlinks:

```text
INFO: Creating virtual environment with `venv`...
INFO: Installing into `venv` virtual environment...
DEBUG Found a virtualenv named .venv at: /tmp/tmp4nape29h/.venv
DEBUG Cached interpreter info for Python 3.10.14, skipping probing: .venv/bin/python
DEBUG Using Python 3.10.14 environment at .venv/bin/python
DEBUG Trying to lock if free: .venv/.lock
purelib: "/tmp/tmp4nape29h/.venv/lib/python3.10/site-packages"
platlib: "/tmp/tmp4nape29h/.venv/lib64/python3.10/site-packages"
is_same_file(purelib, platlib): Ok(true)
```
2024-05-14 14:33:44 -04:00
Charlie Marsh
732410f255
Reduce sensitivity of unknown option error (#3580)
Closes https://github.com/astral-sh/uv/issues/3579.
2024-05-14 14:40:02 +00:00
Charlie Marsh
835ebe60c6
Create virtualenv if it doesn't exist in project API (#3499)
## Summary

This doesn't yet respect `--python` or the `requires-python` in the
project itself.

Closes #3449.
2024-05-10 14:10:13 +00:00
Chan Kang
76a39c76f5
add sys_path to Interpreter struct (#3500)
<!--
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
likely necessary to resolve https://github.com/astral-sh/uv/issues/2500

made this a separate PR in an attempt to make the changes as small as
possible; let me know if it's preferred to keep them as a single PR.
<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan
- edited the test in `interpreter.rs`
- tested manually via `println!` 

```
$ cargo run --quiet pip show test
["/Users/chankang/Library/Caches/uv/.tmpKzNEPN", "/Users/chankang/.pyenv/versions/3.12.2/lib/python312.zip", "/Users/chankang/.pyenv/versions/3.12.2/lib/python3.12", "/Users/chankang/.pyenv/versions/3.12.2/lib/python3.12/lib-dynload", "/Users/chankang/repos/uv/.venv/lib/python3.12/site-packages"]
warning: Package(s) not found for: test
chankang@chans-Air ~/repos/uv -  (syspath)
$ git diff
diff --git a/crates/uv-interpreter/src/environment.rs b/crates/uv-interpreter/src/environment.rs
index 33b785ce..8ebf0864 100644
--- a/crates/uv-interpreter/src/environment.rs
+++ b/crates/uv-interpreter/src/environment.rs
@@ -106,6 +106,7 @@ impl PythonEnvironment {
     /// Some distributions also create symbolic links from `purelib` to `platlib`; in such cases, we
     /// still deduplicate the entries, returning a single path.
     pub fn site_packages(&self) -> impl Iterator<Item = &Path> {
+        println!("{:?}", self.interpreter.sys_path());
         if let Some(target) = self.interpreter.target() {
             Either::Left(std::iter::once(target.root()))
         } else {
chankang@chans-Air ~/repos/uv -  (syspath)
$ python -c "import sys; print(sys.path)"
['', '/Users/chankang/.pyenv/versions/3.12.2/lib/python312.zip', '/Users/chankang/.pyenv/versions/3.12.2/lib/python3.12', '/Users/chankang/.pyenv/versions/3.12.2/lib/python3.12/lib-dynload', '/Users/chankang/.pyenv/versions/3.12.2/lib/python3.12/site-packages']
chankang@chans-Air ~/repos/uv -  (syspath)
```

<!-- How was it tested? -->
2024-05-10 08:41:32 +02:00
Charlie Marsh
f342d39f8c
Change error value detection for glibc (#3487)
## Summary

See: #3486. This just fixes the error message, not the underlying bug.
2024-05-09 15:24:03 +00:00
Andrew Gallant
7d67b7bb49 pep508: un-export fields for MarkerEnvironment
We now use the getters and setters everywhere.

There were some places where we wanted to build a `MarkerEnvironment`
out of whole cloth, usually in tests. To facilitate those use cases, we
add a `MarkerEnvironmentBuilder` that provides a convenient constructor.
It's basically like a `MarkerEnvironment::new`, but with named
parameters. That's useful here because there are so many fields (and
they many have the same type).
2024-05-09 10:06:02 -04:00
Charlie Marsh
5ad373b2ec
Skip Python 2 versions when locating Python (#3476)
## Summary

Unfortunately, the `-I` flag was added in Python 3.4. So if we query a
Python version prior to 3.4 (e.g., Python 2.7), we can't run our script
at all, and lose the ability to match against our structured error.

This PR adds an additional check against the stderr output for these
cases.

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

## Test Plan

Installed Python 2.7, and verified that it was skipped (and that we
instead found my `python3`).
2024-05-09 03:25:21 +00:00
Charlie Marsh
7c6632114b
Improve JSON Schema and add export script (#3461)
## Summary

A few errors I noticed after generating the schema.
2024-05-08 16:15:16 +00:00
konsti
f8901e9989
Always activate non-pep508-extensions (#3428)
Avoid compilation errors when running partial tests due to that feature
being missing.
2024-05-07 16:13:09 +00:00
Charlie Marsh
ed27dde8a2
Revise comment on virtualenv discovery from cwd (#3406)
See:
37d229b2c2..cd53a28181 (r1590746360)
2024-05-06 14:07:11 +00:00
Shantanu
95f31f2266
Better error for unsupported Python version (#3398)
Fixes #3371

It seems like uv doesn't proactively enforce 3.8+ and in most cases just
issues a warning. This PR keeps that property, only adding the new check
when it is known to fail. I checked the imports in this file and the
other ones seem fine.
2024-05-06 11:12:36 +02:00
renovate[bot]
c1370cab1b
Update pre-commit dependencies (#3391) 2024-05-06 02:18:51 +00:00
Godefroid Chapelle
ef92c38486
Detect current venv when uv is invoked from within a virtualenv (#3379)
Fixes #3378.
2024-05-05 22:53:25 +00:00
Charlie Marsh
a63018591e
Unset target when creating virtual environments (#3362)
## Summary

We were writing the build dependencies into the `--target` directory,
which both made builds fail and led to them leaking into the user's
directory.

Closes https://github.com/astral-sh/uv/issues/3349.
2024-05-03 23:21:23 +00:00
Andrew Gallant
1089abda3f
require serde and rkyv everywhere; remove optional serde and rkyv features (#3345)
In *some* places in our crates, `serde` (and `rkyv`) are optional
dependencies. I believe this was done out of reasons of "good sense,"
that is, it follows a Rust ecosystem pattern where serde integration
tends to be an opt-in crate feature. (And similarly for `rkyv`.)

However, ultimately, `uv` itself requires `serde` and `rkyv` to
function. Since our crates are strictly internal, there are limited
consumers for our crates without `serde` (and `rkyv`) enabled. I think
one possibility is that optional `serde` (and `rkyv`) integration means
that someone can do this:

    cargo test -p pep440_rs

And this will run tests _without_ `serde` or `rkyv` enabled. That in
turn could lead to faster iteration time by reducing compile times. But,
I'm not sure this is worth supporting. The iterative compilation times
of
individual crates are probably fast enough in debug mode, even with
`serde` and `rkyv` enabled. Namely, `serde` and `rkyv` themselves
shouldn't need to be re-compiled in most cases. On `main`:

```
from-scratch: `cargo test -p pep440_rs --lib` 0.685
incremental: `cargo test -p pep440_rs --lib` 0.278s
from-scratch: `cargo test -p pep440_rs --features serde,rkyv --lib` 3.948s
incremental: `cargo test -p pep440_rs --features serde,rkyv --lib` 0.321s
```

So while a from-scratch build does take significantly longer, an
incremental build is about the same.

The benefit of doing this change is two-fold:

1. It brings out crates into alignment with "reality." In particular,
   some crates were _implicitly_ relying on `serde` being enabled
   without explicitly declaring it. This technically means that our
   `Cargo.toml`s were wrong in some cases, but it is hard to observe it
   because of feature unification in a Cargo workspace.
2. We no longer need to deal with the cognitive burden of writing
   `#[cfg_attr(feature = "serde", ...)]` everywhere.
2024-05-03 10:21:03 -04:00
Zanie Blue
49675558eb
Split virtual environment detection into a dedicated module (#3331)
Split out of https://github.com/astral-sh/uv/pull/3266
2024-05-02 06:58:48 -05:00
Zanie Blue
c28a2806b3
Separate interpreter selectors into implementation and platform modules (#3332)
Split out of #3266

The "selector" concept doesn't seem well enough defined as-is. For
example, `PythonVersion` belongs there but isn't present. Going for
smaller modules instead.
2024-05-02 11:55:01 +00:00
Zanie Blue
5048ccef3a
Update toolchain discovery to avoid runtime panic (#3330)
Split out of https://github.com/astral-sh/uv/pull/3266

If `UV_BOOTSTRAP_DIR` and `CARGO_MANIFEST_DIR` are both unset, we
currently panic. This isn't good once we start to use managed toolchains
in production. We'll need to change this more later once the toolchain
directory is more user-facing.
2024-05-02 06:44:16 -05:00
Zanie Blue
528bed5bed
Move py launcher handling into separate module (#3329)
Split out of #3266 

Mostly an organizational change, with some error handling
simplification.
2024-05-02 06:44:07 -05:00
Zanie Blue
630d3fde5c
Merge uv-toolchain and uv-interpreter (#3265)
Moves all of `uv-toolchain` into `uv-interpreter`. We may split these
out in the future, but the refactoring I want to do for interpreter
discovery is easier if I don't have to deal with entanglement. Includes
some restructuring of `uv-interpreter`.

Part of #2386
2024-04-30 17:49:46 +00:00
Charlie Marsh
cf55c715f8
Expose --python as an environment variable (#3284)
## Summary

This was requested offline, and seems reasonable to me.
2024-04-30 03:32:40 +00:00
Charlie Marsh
ad99e3af63
Create --target directories lazily (#3274)
## Summary

Based on feedback in
https://github.com/astral-sh/uv/pull/3257#issuecomment-2078560574.
2024-04-26 03:36:56 +00:00
Charlie Marsh
ed8f6e4556
Add --target support to sync and install (#3257)
## Summary

The approach taken here is to model `--target` as an install scheme in
which all the directories are just subdirectories of the `--target`.
From there, everything else... just works? Like, upgrade, uninstalls,
editables, etc. all "just work".

Closes #1517.
2024-04-25 19:15:39 -04:00
Zanie Blue
c22e15f07d
Warn when an unsupported Python version is encountered (#3250)
I rebased https://github.com/astral-sh/uv/pull/2757 then realized that
we want to implement this for more than `uv venv`.

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

```
❯ cargo run -q -- pip install -p /Users/mz/bin/python3.7 anyio
warning: uv is only compatible with Python 3.8+, found Python 3.7.17.
Audited 1 package in 84ms

❯ cargo run -q -- venv -p /Users/mz/bin/python3.7
warning: uv is only compatible with Python 3.8+, found Python 3.7.17.
Using Python 3.7.17 interpreter at: /Users/mz/bin/python3.7
Creating virtualenv at: .venv
Activate with: source .venv/bin/activate
```

---------

Co-authored-by: Stevie Gayet <stegayet@users.noreply.github.com>
2024-04-24 17:51:57 +00:00
Charlie Marsh
7688f464c8
Allow --python and --system on pip compile (#3115)
## Summary

I think these are useful to have for consistency, though the `--system`
variant requires some new threading.

Closes: https://github.com/astral-sh/uv/issues/2242.
2024-04-18 04:55:49 +00:00
Zanie Blue
dcc2c6865c
Create ephemeral virtual environments for uv run (#3075)
If a virtual environment does not exist, we will create one for the
duration of the invocation.

Adds an `--isolated` flag to force this behavior (ignoring an existing
virtual environment).
2024-04-17 16:32:04 +00:00
Paul Moore
8e37625005
Allow passing a venv to uv pip --python (#3064)
Fixes https://github.com/astral-sh/uv/issues/3060

## Summary

Allows passing a virtual environment (the path to the directory, rather
than the path to the Python interpreter within the directory) to the
`--python` option of the `uv pip` command.

## Test Plan

Tested manually to confirm that the expected new functionality works.
The test suite still passes after this change.

I don't know how to add tests for a new feature like this. I would be
happy to do so if someone can give me some pointers on how to do it.
2024-04-16 18:39:37 +00:00
Charlie Marsh
ab9cc78b7a
Deduplicate symbolic links between purelib and platlib (#3002)
## Summary

This PR adds system install tests to verify the behavior described in
#2798. It turns out this behavior _also_ affects Fedora and Amazon
Linux, we just didn't have the right conditions enabled (specifically,
you need to create the virtualenv with `python -m venv` to get these
symlinks), so the test suite was expanded to capture that.

The issue itself is also fixed by way of deduplicating the
`site-packages` entries.

Closes: https://github.com/astral-sh/uv/issues/2798
2024-04-12 17:08:56 -04:00
Charlie Marsh
c43757ad4c
Avoid calling normalize_path with relative paths that extend beyond the current directory (#3013)
## Summary

It turns out that `normalize_path` (sourced from Cargo) has a subtle
bug. If you pass it a relative path that traverses beyond the root, it
silently drops components. So, e.g., passing `../foo/bar`, it will just
drop the leading `..` and return `foo/bar`.

This PR encodes that behavior as a `Result` and avoids using it in such
cases.

Closes https://github.com/astral-sh/uv/issues/3012.
2024-04-12 14:48:03 -04:00
konsti
7f70849e3c
Support freethreading python (#2805)
freethreaded python reintroduces abiflags since it is incompatible with
regular native modules and abi3.

Tests: None yet! We're lacking cpython 3.13 no-gil builds we can use in
ci.

My test setup:

```
PYTHON_CONFIGURE_OPTS="--enable-shared --disable-gil" pyenv install 3.13.0a5
cargo run -q -- venv -q -p python3.13 .venv3.13 --no-cache-dir && cargo run -q -- pip install -v psutil --no-cache-dir && .venv3.13/bin/python -c "import psutil"
```

Fixes #2429
2024-04-12 09:39:47 +00:00
Zanie Blue
44e39bdca3
Replace Python bootstrapping script with Rust implementation (#2842)
See https://github.com/astral-sh/uv/issues/2617

Note this also includes:
- #2918 
- #2931 (pending)

A first step towards Python toolchain management in Rust.

First, we add a new crate to manage Python download metadata:

- Adds a new `uv-toolchain` crate
- Adds Rust structs for Python version download metadata
- Duplicates the script which downloads Python version metadata
- Adds a script to generate Rust code from the JSON metadata
- Adds a utility to download and extract the Python version

I explored some alternatives like a build script using things like
`serde` and `uneval` to automatically construct the code from our
structs but deemed it to heavy. Unlike Rye, I don't generate the Rust
directly from the web requests and have an intermediate JSON layer to
speed up iteration on the Rust types.

Next, we add add a `uv-dev` command `fetch-python` to download Python
versions per the bootstrapping script.

- Downloads a requested version or reads from `.python-versions`
- Extracts to `UV_BOOTSTRAP_DIR`
- Links executables for path extension

This command is not really intended to be user facing, but it's a good
PoC for the `uv-toolchain` API. Hash checking (via the sha256) isn't
implemented yet, we can do that in a follow-up.

Finally, we remove the `scripts/bootstrap` directory, update CI to use
the new command, and update the CONTRIBUTING docs.

<img width="1023" alt="Screenshot 2024-04-08 at 17 12 15"
src="57bd3cf1-7477-4bb8-a8e9-802a00d772cb">
2024-04-10 11:22:41 -05:00
Zander
4b2e67955f
fixed uv can't create .venv for cpython-x86 on Windows (#2707)
Adaptation to the win32 platform is added.

https://docs.python.org/3/library/sysconfig.html#sysconfig.get_platform


## Summary

fixed uv can't create .venv for cpython-x86 on Windows 

[uv can't create .venv for cpython-x86 on Windows
](https://github.com/astral-sh/rye/issues/952)

---------

Co-authored-by: Nashan <34827878+zhuang1234@users.noreply.github.com>
2024-04-02 20:45:53 -05:00
Wolf Vollprecht
7d285148b2
fix: do not error when there are warnings on stderr (#2599)
## Summary

We had some users report bugs because the Python querying failed due to
warnings in `stderr`. I don't think this should fail on any `stderr`
output.

E.g.

```
  × Querying Python at `USER/.pixi/envs/default/bin/python3.10` failed with status exit status: 0 with exit status: 0
  │ --- stdout:
  │ {"markers": {"implementation_name": "cpython", "implementation_version": "3.10.0", "os_name": "posix", "platform_machine": "x86_64", "platform_python_implementation": "CPython", "platform_release": "5.15.146.1-microsoft-standard-WSL2",
  │ "platform_system": "Linux", "platform_version": "#1 SMP Thu Jan 11 04:09:03 UTC 2024", "python_full_version": "3.10.0", "python_version": "3.10", "sys_platform": "linux"}, "base_prefix": "USER/.pixi/
  │ envs/default", "base_exec_prefix": "USER/.pixi/envs/default", "prefix": "USER/.pixi/envs/default", "base_executable": "USER/.pixi/envs/default/
  │ bin/python3.10", "sys_executable": "USER/.pixi/envs/default/bin/python3.10", "stdlib": "USER/.pixi/envs/default/lib/python3.10", "scheme": {"platlib": "/home/mvanniekerk/
  │ code/vice-python/.pixi/envs/default/lib/python3.10/site-packages", "purelib": "USER/.pixi/envs/default/lib/python3.10/site-packages", "include": "USER/.pixi/envs/default/
  │ include/python3.10", "scripts": "USER/.pixi/envs/default/bin", "data": "USER/.pixi/envs/default"}, "virtualenv": {"purelib": "lib/python3.10/site-packages", "platlib": "lib/
  │ python3.10/site-packages", "include": "include/site/python3.10", "scripts": "bin", "data": ""}}
  │ --- stderr:
  │ [03/21/24 15:59:48] WARNING  pyproject.toml does not contain a setuptools.py:119
  │                              tool.setuptools_scm section
  │ ---
```
2024-03-21 19:23:41 -04:00
konsti
70e0967dbd
Avoid repeating paths of workspace packages (#2573)
Scott schafer got me the idea: We can avoid repeating the path for
workspaces dependencies everywhere if we declare them in the virtual
package once and treat them as workspace dependencies from there on.
2024-03-20 16:16:02 -04:00
konsti
7111fdd637
VIRTUAL_ENV takes precedence over CONDA_PREFIX (#2574)
It is a common pattern to have an active conda base env (that sets
`CONDA_PREFIX`) and then create a venv on top of that (setting
`VIRTUAL_ENV`).

Previously, we would error when both `VIRTUAL_ENV` and `CONDA_PREFIX`
were set, now `VIRTUAL_ENV` takes precedence over `CONDA_PREFIX`.

Fixes #2028
2024-03-20 16:14:44 -04:00
Charlie Marsh
00fc44012c
Use relative paths for user display (#2559)
## Summary

This PR changes our user-facing representation for paths to use relative
paths, when the path is within the current working directory. This
mirrors what we do in Ruff. (If the path is _outside_ the current
working directory, we print an absolute path.)

Before:

```shell
❯ uv venv .venv2
Using Python 3.12.2 interpreter at: /Users/crmarsh/workspace/uv/.venv/bin/python3
Creating virtualenv at: .venv2
Activate with: source .venv2/bin/activate
```

After:

```shell
❯ cargo run venv .venv2
    Finished dev [unoptimized + debuginfo] target(s) in 0.15s
     Running `target/debug/uv venv .venv2`
Using Python 3.12.2 interpreter at: .venv/bin/python3
Creating virtualenv at: .venv2
Activate with: source .venv2/bin/activate
```

Note that we still want to use the existing `.simplified_display()`
anywhere that the path is being simplified, but _still_ intended for
machine consumption (e.g., when passing to `.current_dir()`).
2024-03-20 09:52:50 -04:00
Charlie Marsh
c180fedbce
Run interpreter discovery under -I mode (#2552)
## Summary

If you have a file `typing.py` in the current working directory, `python
-m` doesn't work in some Python versions:

```sh
❯ python -m foo
Could not import runpy module
Traceback (most recent call last):
  File "/Users/crmarsh/.local/share/rtx/installs/python/3.9.18/lib/python3.9/runpy.py", line 15, in <module>
    import importlib.util
  File "/Users/crmarsh/.local/share/rtx/installs/python/3.9.18/lib/python3.9/importlib/util.py", line 2, in <module>
    from . import abc
  File "/Users/crmarsh/.local/share/rtx/installs/python/3.9.18/lib/python3.9/importlib/abc.py", line 17, in <module>
    from typing import Protocol, runtime_checkable
ImportError: cannot import name 'Protocol' from 'typing' (/Users/crmarsh/workspace/uv/typing.py)
```

This did _not_ cause problems for us on Python 3.11 or later, because we
set `PYTHONSAFEPATH`, which avoids adding the current working directory
to `sys.path`. However, on earlier versions, we _were_ failing with the
above. (It's important that we run interpreter discovery in the current
working directory, since doing otherwise breaks pyenv shims.)

The fix implemented here uses `-I` to run Python in isolated mode, which
is even stricter. The downside of isolated mode is that we currently
rely on setting `PYTHONPATH` to find the "fake module" that we create on
disk, and `-I` means `PYTHONPATH` is totally ignored. So, instead, we
run a script directly, and that _script_ injects the path we care about
into `PYTHONSAFEPATH`.

Closes https://github.com/astral-sh/uv/issues/2547.
2024-03-19 20:19:46 -04:00
Micha Reiser
acbee166c0
Remove unused dependencies (#2543)
## Summary

I tried out `cargo shear` to see if there are any unused dependencies
that `cargo udeps` isn't reporting. It turned out, there are a few. This
PR removes those dependencies.

## Test Plan

`cargo build`
2024-03-19 13:10:10 -04:00
Charlie Marsh
ba14f69676
Search in both purelib and platlib for site-packages population (#2537)
## Summary

In reality, there's no such thing as the `site-packages` directory for a
given virtualenv. Rather, Python defines both `purelib` and `platlib`,
where the former is for pure-Python packages and the latter is for
packages that contain native code. These are almost always set to the
same thing... but they don't _have_ to be, and in fact of Fedora they
are not.

This PR changes the `site_packages` method to return an iterator of
directories.

Closes https://github.com/astral-sh/uv/issues/2527.
2024-03-19 03:06:16 +00:00
konsti
ecc46c5412
Fix operating system detection on *BSD (#2505)
For #2487, not closing since we still need confirmation that his fixes
*BSD.
2024-03-18 10:51:55 +00:00
Charlie Marsh
a07438f52f
Re-add support for pyenv shims (#2503)
## Summary

By running `get_interpreter_info.py` outside of the current working
directory, we seem to have broken pyenv shims.

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

## Test Plan

Without this change (resolving to the Homebrew Python, even though we
start with a shim):

```
DEBUG Starting interpreter discovery for Python @ `python3.11`
DEBUG Probing interpreter info for: /Users/crmarsh/.pyenv/shims/python3.11
DEBUG Found Python 3.11.7 for: /Users/crmarsh/.pyenv/shims/python3.11
Using Python 3.11.7 interpreter at: /opt/homebrew/opt/python@3.11/bin/python3.11
Creating virtualenv at: .venv
INFO Removing existing directory
Activate with: source .venv/bin/activate
```

With this change:

```
DEBUG Starting interpreter discovery for Python @ `python3.11`
DEBUG Probing interpreter info for: /Users/crmarsh/.pyenv/shims/python3.11
DEBUG Found Python 3.11.1 for: /Users/crmarsh/.pyenv/shims/python3.11
Using Python 3.11.1 interpreter at: /Users/crmarsh/.pyenv/versions/3.11.1/bin/python3.11
Creating virtualenv at: .venv
INFO Removing existing directory
Activate with: source .venv/bin/activate
```
2024-03-17 22:57:36 -04:00
konsti
b5d9014918
Fix mac os arch with platform.mac_ver() (#2454)
Fixes #2450, see
8280420121
2024-03-14 12:37:45 +00:00
konsti
7964bfbb2b
Move architecture and operating system probing to Python (#2381)
The architecture of uv does not necessarily match that of the python
interpreter (#2326). In cross compiling/testing scenarios the operating
system can also mismatch. To solve this, we move arch and os detection
to python, vendoring the relevant pypa/packaging code, preventing
mismatches between what the python interpreter was compiled for and what
uv was compiled for.

To make the scripts more manageable, they are now a directory in a
tempdir and we run them with `python -m` . I've simplified the
pypa/packaging code since we're still building the tags in rust. A
`Platform` is now instantiated by querying the python interpreter for
its platform. The pypa/packaging files are copied verbatim for easier
updates except a `lru_cache()` python 3.7 backport.

Error handling is done by a `"result": "success|error"` field that allow
passing error details to rust:

```console
$ uv venv --no-cache
  × Can't use Python at `/home/konsti/projects/uv/.venv/bin/python3`
  ╰─▶ Unknown operation system `linux`
```

I've used the [maturin sysconfig
collection](855f6d2cb1/sysconfig)
as reference. I'm unsure how to test these changes across the wide
variety of platforms.

Fixes #2326
2024-03-13 11:51:14 +00:00
Charlie Marsh
3799862f5d
Trim injected python_version marker to (major, minor) (#2395)
## Summary

Per [PEP 508](https://peps.python.org/pep-0508/), `python_version` is
just major and minor:

![Screenshot 2024-03-12 at 5 15
09 PM](cc3b8d65-dab3-4229-aed7-c6fe590b8da0)

Right now, we're using the provided version directly, so if it's, e.g.,
`-p 3.11.8`, we'll inject the wrong marker. This was causing `pandas` to
omit `numpy` when `-p 3.11.8` was provided, since its markers look like:

```
Requires-Dist: numpy<2,>=1.22.4; python_version < "3.11"
Requires-Dist: numpy<2,>=1.23.2; python_version == "3.11"
Requires-Dist: numpy<2,>=1.26.0; python_version >= "3.12"
```

Closes https://github.com/astral-sh/uv/issues/2392.
2024-03-13 00:11:50 +00:00
konsti
f70ae72874
Add a -vv log level and make -v more readable (#2301)
Behind error messages, the debug log is the second most important
resource to finding out what and why went wrong when there was a problem
with uv. It is important to see which paths it has found and how the
decisions in the resolver were made. I'm trying to improve the
experience interacting with the debug log.

The hierarchical layer is verbose and hard to follow, so it's moved to
the `-vv` extra verbose setting, while `-v` works like
`RUST_LOG=uv=debug`.

For installing jupyter with a warm cache:

* Default:
https://gist.github.com/konstin/4de6e466127311c5a5fc2f99c56a8e11
* `-v`: https://gist.github.com/konstin/e7bafe0ec7d07e47ba98a3865ae2ef3e
* `-vv`:
https://gist.github.com/konstin/3ee1aaff37f91cceb6275dd5525f180e
Ideally, we would have `-v`, `-vv` and `-vvv`, but we're lacking the the
`info!` layer for `-v`, so there's only two layers for now.

The `tracing_subcriber` formatter always print the current span, so i
replaced it with a custom formatter.


![image](75f5cfd1-da7b-432e-b090-2f3916930dd1)

Best read commit-by-commit.
2024-03-11 08:58:31 +01:00
konsti
262ca8b576
Rename and document venv discoveries (#2334)
Preparing for #2058, i found it hard to follow where which discovery
function gets called. I moved all the discovery functions to a
`find_python` module (some exposed through `PythonEnvironment`) and
documented which subcommand uses which python discovery strategy.

No functional changes.

![new uv-virtualenv docs
page](cd56df8a-754d-4640-9e7a-e1f9baf6441c)
2024-03-10 13:44:50 +00:00
Charlie Marsh
ff62fe2c0b
Avoid using setuptools shim of distutils (#2305)
## Summary

It turns out that setuptools includes a shim to patch distutils. I'll
admit that I don't fully understand why or how it's different, but this
is the trick `pip` uses to ensure that it gets the "original" distutils.

We actually use distutils in two places: once for the system Python
scheme, and once for virtual environments. In virtualenv, they _do_ use
the patched distutils, so this could deviate in ways I don't understand.

Closes #2302.
2024-03-08 14:53:49 -05:00