Commit Graph

120 Commits

Author SHA1 Message Date
Aria Desires e2c5526fbb
replace backoff with backon (#10442)
This should be essentially the exact same behaviour, but backon is a
total API redesign, so things had to be expressed slightly differently.
Overall I think the code is more readable, which is nice.

Fixes #10001
2025-01-09 16:01:23 -05:00
Charlie Marsh 9128fe1866
Use portable path instead of string for subdirectory (#10069)
## Summary

A few places where there are extra conversions to and from string that
seem unnecessary; a few places where we're using `PathBuf` instead of
`PortablePathBuf`.
2024-12-21 00:28:36 +00:00
Jp dd442450b0
Retry mechanisms on Windows for copy_atomic and write_atomic (#10026)
Hello! 🙂 


## Summary

After submitting retry mechanisms on scripts installation for windows:
#9543 , I noticed that some other functions were using the same
`persist` features of temporary files. This could lead to the same issue
spotted before (temporary lock by AV/EDR software). I validated that it
was possible.

So I updated them to go through the same function on Windows, which is
using the retry mechanisms if needed.
In order to do so, I add to add an async version of the
`persist_with_retry`.

There is a little trick to make the borrow-checker happy line 306,
curious of your opinion on it? This is just a pointer move so it should
not induce some performance regression if I'm not mistaking.

I also updated them to use `fs_err` on Unix for better error messages.

Also, one of the error messages I introduced was badly formatted, I
fixed it. 🙂

## Test Plan

The changes should be iso functional and covered with the existing
test-suite.
2024-12-19 08:43:57 -05:00
Ben Beasley 45b9aa8f41
Make the backoff crate dependency Windows-only (#10002)
<!--
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

Since the `backoff` dependency is only *used* on Windows in practice,
this PR would ensure that it is only *compiled* on Windows, too. This is
helpful because it appears to be unmaintained upstream,
https://github.com/astral-sh/uv/issues/10001, and it would be nice to be
able to [drop it from
Fedora](https://bugzilla.redhat.com/show_bug.cgi?id=2329729).
<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan

<!-- How was it tested? -->
```
$ cargo run python install
$ cargo test
```
2024-12-18 10:04:54 -05:00
Imani Pelton 40a2a6a959
Avoid `panic!()` when current directory does not exist (#9876)
## Summary

If the shell is currently in a directory that no longer exists, uv will
panic from any command. Panicking is a confusing behavior to those
unfamiliar with Rust and can sometimes make it hard to determine the
true issue.

Closes #9875 

## Test Plan

The reproduction steps in the issue report were followed and uv no
longer panics. `uv version` can still successfully print the version if
the directory does exist.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-12-13 21:39:46 +00:00
Charlie Marsh 7df16af764
Use copy-on-write when normalizing paths (#9710) 2024-12-07 15:52:41 -05:00
Charlie Marsh f8e6a94893
Normalize relative paths when `--project` is specified (#9709)
## Summary

In the end, the problem is that `relative_to` has incorrect behavior if
either path is non-normalize (e.g., `foo/bar/../project`). So I've fixed
that method, but we _also_ now normalize `project` upfront, which _also_
fixes the issue.

Closes https://github.com/astral-sh/uv/issues/9692.
2024-12-07 15:16:13 -05:00
Jp 03f8808d11
Handle Windows AV/EDR file locks during script installations (#9543)
Fixes #9531


## Context

While working with [uv](https://github.com/astral-sh/uv), I encountered
issues with a python dependency, [httpx](https://www.python-httpx.org/)
unable to be installed because of a **os error 5 permission denied**.
The error occur when we try to persist a **.exe file** from a temporary
folder into a persistent one.
I only reproduce the issue in an enterprise **Windows** Jenkins Runner.
In my virtual machines, I don't have any issues. So I think this is most
probably coming from the system configuration. This windows runner
**contains an AV/EDR**. And the fact that the file locked occured only
once for an executable make me think that it's most probably the cause.

While doing some research and speaking with some colleagues (hi
@vmeurisse), it seems that the issue is a very recurrent one on Windows.
In the Javascript ecosystem, there is this package, created by the
@isaacs, `npm` inventor: https://www.npmjs.com/package/graceful-fs, used
inside `npm`, allowing its package installations to be more resilient to
filesystem errors:
> The improvements are meant to normalize behavior across different
platforms and environments, and to make filesystem access more resilient
to errors.
One of its core feature is this one:
> On Windows, it retries renaming a file for up to one second if EACCESS
or EPERM error occurs, likely because antivirus software has locked the
directory.

So I tried to implement the same algorithm on `uv`, **and it fixed my
issue**! I can finally install `httpx`.

Then, [as I mentionned in this
issue](https://github.com/astral-sh/uv/issues/9531#issuecomment-2508981316),
I saw that you already implemented exactly the same algorithm in an
asynchronous function for renames 😄

22fd9f7ff1/crates/uv-fs/src/lib.rs (L221)

## Summary of changes 
- I added a similar function for `persist` (was not easy to have the
benediction of the borrow checker 😄)
- I added a `sync` variant of `rename_with_retry`
- I edited `install_script` to use the function including retries on
Windows

Let me know if I should change anything 🙂 

Thanks!!

## Test Plan
This pull-request should be totally iso-functional, so I think it should
be covered by existing tests in case of regression.
All tests are still passing on my side.
Also, of course validated that my windows machines (windows 10 & windows
11) containing AV/EDR software are now able to install `httpx.exe`
script.
However, if you think any additional test is needed, feel free to tell
me!
2024-12-01 17:57:09 -05:00
konsti 55148c214e
Avoid empty user display paths (#9312)
Currently, user display returns an empty path if the current dir is the
directory we are printing. This leads to odd messages such as

 > Including project.license-files at `` with `LICENSE*`

or

> Not a license files match: ``

Instead, we display the current path as a dot.
2024-11-21 14:56:50 -05:00
Charlie Marsh d08bfee718
Remove separate test files in favor of same-file `mod tests` (#9199)
## Summary

These were moved as part of a broader refactor to create a single
integration test module. That "single integration test module" did
indeed have a big impact on compile times, which is great! But we aren't
seeing any benefit from moving these tests into their own files (despite
the claim in [this blog
post](https://matklad.github.io/2021/02/27/delete-cargo-integration-tests.html),
I see the same compilation pattern regardless of where the tests are
located). Plus, we don't have many of these, and same-file tests is such
a strong Rust convention.
2024-11-18 20:11:46 +00:00
konsti c2ccc2c5dc
Support `copy_dir_all` in unit tests too (#9124)
Refactoring for https://github.com/astral-sh/uv/pull/9091
2024-11-14 18:05:15 +00:00
Zanie Blue 8d3408fe39
Add support for installing versioned Python executables on Windows (#8663)
Incorporating #8637 into #8458 

- Adds `python-managed` feature selection to Windows CI for `python
install` tests
- Adds trampoline sniffing utilities to `uv-trampoline-builder`
- Uses a trampoline to install Python executables into the `PATH` on
Windows
2024-10-31 15:58:35 +00:00
Zanie Blue c8cbd62a30
Patch Python executable name for Windows free-threaded builds (#8310)
A temporary fix for https://github.com/astral-sh/uv/issues/8298 while we
wait for my slower upstream fix at
https://github.com/indygreg/python-build-standalone/pull/373

I think we'll want this machinery anyway to ensure that the various
executable names are available? Otherwise we need to special-case all
the `python` names in `uv run`?

We don't have unit test coverage of managed downloads, so I added an
[integration
test](https://github.com/astral-sh/uv/actions/runs/11394150653/job/31703956805?pr=8310)
similar to what we have for Linux.
2024-10-17 18:27:55 -05:00
Jo 76a9afbae5
Ignore try lock error if it is WouldBlock (#8258)
## Summary

Address a TODO comment, seems like we don't need `raw_os_err`?
2024-10-16 14:15:48 -05:00
Amos Wenger 715f28fd39
chore: Move all integration tests to a single binary (#8093)
As per
https://matklad.github.io/2021/02/27/delete-cargo-integration-tests.html

Before that, there were 91 separate integration tests binary.

(As discussed on Discord — I've done the `uv` crate, there's still a few
more commits coming before this is mergeable, and I want to see how it
performs in CI and locally).
2024-10-11 16:41:35 +02:00
Kemal Akkoyun 1a39ffe391
uv run: List available scripts when a script is not specified (#7687)
Signed-off-by: Kemal Akkoyun <kakkoyun@gmail.com>
## Summary

This PR adds the ability to list available scripts in the environment
when `uv run` is invoked without any arguments.
It somewhat mimics the behavior of `rye run` command
(See https://rye.astral.sh/guide/commands/run).

This is an attempt to fix #4024.

## Test Plan

I added test cases. The CI pipeline should pass.

### Manuel Tests

```shell
❯ uv run
Provide a command or script to invoke with `uv run <command>` or `uv run script.py`.

The following scripts are available:

normalizer
python
python3
python3.12

See `uv run --help` for more information.
```

---------

Signed-off-by: Kemal Akkoyun <kakkoyun@gmail.com>
Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-10-08 19:34:50 +00:00
Charlie Marsh 7435ee3b24
Allow spaces in path requirements (#7767)
## Summary

This PR modifies our parsing to allow spaces in URLs. I don't know if
this is a correct change... But we now parse URLs until we see:

- A newline.
- A semicolon (marker) or hash (comment), _preceded_ by a space. We
parse the URL until the last
  non-whitespace character (inclusive).
- A semicolon (marker) or hash (comment) _followed_ by a space. We treat
this as an error, since
the end of the URL is ambiguous (e.g., `https://foo.com; marker`) would
be a URL that ends in `;`).

Closes https://github.com/astral-sh/uv/issues/6032.
2024-09-30 12:38:38 -04:00
konsti c053dc84f4
Progress bars for `uv publish` (#7613) 2024-09-24 15:55:33 +00:00
Zanie Blue 5206a33e78
Do not error if the `CACHEDIR.TAG` file exists but cannot be written to (#7550)
Attempting to address the error in
https://github.com/astral-sh/uv/issues/7434 — it seems overkill to fail
if the file exists but isn't writable.
2024-09-19 09:39:59 -05:00
Charlie Marsh e36cc99b0d
Use portable paths when serializing sources (#7504)
## Summary

Closes https://github.com/astral-sh/uv/issues/7493.
2024-09-18 18:51:14 +00:00
Zanie Blue 8b830de94d
Do not use a user-facing warning for "Waiting to acquire lock..." message (#7502)
Closes https://github.com/astral-sh/uv/issues/7489
2024-09-18 15:34:27 +00:00
Charlie Marsh 7e6df8ffd4
Remove canonicalize calls (#6919)
## Summary

A few of these should use `absolute` instead of `canonicalize`; and
apparently we no longer need to strip the `CANONICAL_CWD` to get tests
passing.
2024-09-01 18:23:11 +00:00
Chao Ning ae3f35cfe2
fix: replace std::fs::canonicalize with Simplified::simple_canonicaliz… (#6776)
## Summary
This PR addresses an issue on Windows where `std::fs::canonicalize` can
fail or panic when resolving paths on mapped network drives. By
replacing it with `Simplified::simple_canonicalize`, we aim to improve
the robustness and cross-platform compatibility of path resolution.

### Changes
* Updated `CANONICAL_CWD` in `path.rs` to use
`Simplified::simple_canonicalize` instead of `std::fs::canonicalize`.

### Why
* `std::fs::canonicalize` has known issues with resolving paths on
mapped network drives on Windows, which can lead to panics or incorrect
path resolution.
* `Simplified::simple_canonicalize` internally uses
`dunce::canonicalize`, which handles these cases more gracefully,
ensuring better stability and reliability.

## Test Plan
Since `simple_canonicalize` has already been tested in a prior PR, this
change is expected to work without introducing any new issues. No
additional tests are necessary beyond ensuring existing tests pass,
which will confirm the correctness of the change.
2024-09-01 13:59:15 -04:00
Charlie Marsh 50c5fe96ec
Avoid stripping root for user path display (#6865)
## Summary

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

## Test Plan

```
❯ ~/workspace/uv/target/debug/uv pip list --verbose
DEBUG uv 0.4.0
DEBUG Searching for Python interpreter in system path
DEBUG Found `cpython-3.12.3-macos-aarch64-none` at `/Users/crmarsh/.local/share/rtx/installs/python/3.12.3/bin/python3` (search path)
DEBUG Using Python 3.12.3 environment at /Users/crmarsh/.local/share/rtx/installs/python/3.12.3/bin/python3
```
2024-08-30 09:50:22 -04:00
Zanie Blue 206b136f13
Improve logging for locked file acquisition (#6777)
Consistency etc. when debugging a deadlock
2024-08-29 20:35:39 +00:00
Zanie Blue e3d5d3d26d
Avoid deadlocks when multiple uv processes lock resources (#6790)
This is achieved by updating the `LockedFile::acquire` API to be async —
as in some cases we were attempting to acquire the lock synchronously,
i.e., without yielding, which blocked the runtime.

Closes https://github.com/astral-sh/uv/issues/6691 — I tested with the
reproduction there and a local release build and no longer reproduce the
deadlock with these changes.

Some additional context in the [internal Discord
thread](https://discord.com/channels/1039017663004942429/1278430431204741270/1278478941262188595)
2024-08-29 11:16:14 -05:00
Charlie Marsh 0dc74f619c
Remove `path-absolutize` dependency (#6589)
## Summary

This is now in the standard library.
2024-08-25 12:01:07 +00:00
Charlie Marsh 7fa265a11b
Use relative paths for `--find-links` and local registries (#6566)
## Summary

See: https://github.com/astral-sh/uv/issues/6458
2024-08-25 02:41:47 +00:00
Charlie Marsh e11bbb539a Migrate to XDG and Linux strategy for macOS directories (#5806)
This PR moves us to the Linux strategy for our global directories on
macOS. We both feel on the team _and_ have received feedback (in Issues
and Polls) that the `Application Support` directories are more intended
for GUIs, and CLI tools are correct to respect the XDG variables and use
the same directory paths on Linux and macOS.

Namely, we now use:

- `/Users/crmarsh/.local/share/uv/tools` (for tools)
- `/Users/crmarsh/.local/share/uv/python` (for Pythons)
- `/Users/crmarsh/.cache/uv` (for the cache)

The strategy is such that if the `/Users/crmarsh/Library/Application
Support/uv` already exists, we keep using it -- same goes for
`/Users/crmarsh/Library/Caches/uv`, so **it's entirely backwards
compatible**.

If you want to force a migration to the new schema, you can run:

- `uv cache clean`
- `uv tool uninstall --all`
- `uv python uninstall --all`

Which will clean up the macOS-specific directories, paving the way for
the above paths. In other words, once you run those commands, subsequent
`uv` operations will automatically use the `~/.cache` and `~/.local`
variants.

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

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-08-20 11:31:46 -05:00
Charlie Marsh dfec262586
Capture portable path serialization in a struct (#5652)
## Summary

I need to reuse this in #5494, so want to abstract it out and make it
reusable.
2024-07-31 16:00:37 +00:00
Charlie Marsh 750b3a7c8c
Avoid setting executable permissions on files we might not own (#5582)
## Summary

If we just created an entrypoint script, we can of course set the
permissions (we just created it). However, if we're copying from the
cache, we might _not_ own the file. In that case, if we need to change
the permissions (we shouldn't, since the script is likely already
executable -- we set the permissions when we unzip, but I guess they
could _not_ be properly set in the zip itself), we have to copy it.

Closes https://github.com/astral-sh/uv/issues/5581.
2024-07-30 12:32:52 +00:00
Charlie Marsh 51a03738a2
Use cached current directory everywhere (#5574) 2024-07-29 17:03:45 -04:00
Charlie Marsh 24859bd3ee
Upgrade to Rust 1.80.0 (#5472) 2024-07-27 01:49:47 +00:00
Charlie Marsh 4f3dde34dc
Use 666 rather than 644 for default permissions (#5498)
## Summary

I don't know why I used 644 here. 666 is the actual default:
7c2012d0ec/library/std/src/sys/pal/unix/fs.rs (L1069)

Closes https://github.com/astral-sh/uv/issues/5496.
2024-07-27 00:08:52 +00:00
Charlie Marsh 8b8f34ac21
Avoid canonicalizing executables on Windows (#5446)
## Summary

If you have an executable path on a network share path (like
`\\some-host\some-share\...\python.exe`), canonicalizing it adds the
`\\?` prefix, but dunce cannot safely strip it.

This PR changes the Windows logic to avoid canonicalizing altogether. We
don't really expect symlinks on Windows, so it seems unimportant to
resolve them.

Closes: https://github.com/astral-sh/uv/issues/5440.
2024-07-26 08:57:33 -04:00
Charlie Marsh 1e965b47c3
Set standard permissions for temporary files (#5457)
## Summary

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

## Test Plan

Before:

```
❯ ls -l .venv/lib/python3.12/site-packages/httpx-0.27.0.dist-info
total 48
-rw-------  1 crmarsh  staff     2 Jul 25 14:21 INSTALLER
-rw-r--r--  1 crmarsh  staff  7184 Jul 23 23:20 METADATA
-rw-r--r--  1 crmarsh  staff  2541 Jul 25 14:21 RECORD
-rw-------  1 crmarsh  staff     0 Jul 25 14:21 REQUESTED
-rw-r--r--  1 crmarsh  staff    87 Jul 23 23:20 WHEEL
-rw-r--r--  1 crmarsh  staff    37 Jul 23 23:20 entry_points.txt
drwxr-xr-x  3 crmarsh  staff    96 Jul 25 14:21 licenses
```

After:

```
❯ ls -l .venv/lib/python3.12/site-packages/flask-3.0.3.dist-info/
total 48
-rw-r--r--  1 crmarsh  staff     2 Jul 25 14:21 INSTALLER
-rw-r--r--  1 crmarsh  staff  1475 Jul 25 14:21 LICENSE.txt
-rw-r--r--  1 crmarsh  staff  3177 Jul 25 14:21 METADATA
-rw-r--r--  1 crmarsh  staff  2565 Jul 25 14:21 RECORD
-rw-r--r--  1 crmarsh  staff     0 Jul 25 14:21 REQUESTED
-rw-r--r--  1 crmarsh  staff    81 Jul 25 14:21 WHEEL
-rw-r--r--  1 crmarsh  staff    40 Jul 25 14:21 entry_points.txt
```
2024-07-25 20:50:30 +00:00
konsti abb6ac5127
Support workspace to workspace path dependencies (#4833)
Add support for path dependencies from a package in one workspace to a
package in another workspace, which it self has workspace dependencies.

Say we have a main workspace with packages `a` and `b`, and a second
workspace with `c` and `d`. We have `a -> b`, `b -> c`, `c -> d`. This
would previously lead to a mangled path for `d`, which is now fixed.

Like distribution paths, we split workspace paths into an absolute
install path and a relative (or absolute, if the user provided an
absolute path) lock path.

Part of https://github.com/astral-sh/uv/issues/3943
2024-07-16 20:38:46 +00:00
Ibraheem Ahmed be2a67cd9b
Replace `map_or(false, ..)` uses with `is_some_and` and `is_ok_and` (#4703)
## Summary

Looks like there isn't a clippy lint for this yet.
2024-07-01 19:28:42 +00:00
Zanie Blue 5641f3a5d9
Add guard to `replace_symlink` on Windows (#4519)
`junction::create` apparently will happily succeed but not create a link
to files? Since our symlink function does not indicate that it cannot
handle files, this was quite surprising.


Tested over in #4509 which previously failed on an assertion that
`black.exe` existed.
```
error: Failed to install entrypoint
    Caused by: Cannot create a junction for [TEMP_DIR]/tools/black/Scripts/black.exe: is not a directory
```

We should file an issue upstream too, I think?
2024-06-25 13:47:40 -05:00
Zanie Blue 7fe7d8b34e
Fix symlink doc (#4514)
This bit me.
2024-06-25 08:27:03 -05:00
konsti b865341517
Use correct lock path for workspace dependencies (#4421)
Previously, distributions created through `Source::Workspace` would have
the absolute path as lock path. This didn't cause any problems, since in
`Urls` we would later overwrite those urls with the correct one created
from being workspace members by path.

Changing the order surfaced this. This change emits the correct lock
path. I've manually checked the difference with `dbg!`, this is not
observable on main, but on the diverging urls branch it fixes lockfile
creation.
2024-06-20 13:28:47 +00:00
konsti 30126950fe
Fix relative and absolute path handling in lockfiles (#4266)
Previously, `b` in the test case would have been incorrectly locked to
the path of `a`. I've moved `relative_to` into uv-fs since it's now used
in two different places.

Previously failing lockfile when `a/pyproject.toml` and
`a/b/pyproject.toml` exist (not in a workspace) and `a` was depending on
`b`:

```toml
version = 1
requires-python = ">=3.11, <3.13"

[[distribution]]
name = "b"
version = "0.1.0"
source = "directory+/home/konsti/projects/uv/a"
sdist = { path = "/home/konsti/projects/uv/a" }

[[distribution]]
name = "black"
version = "0.1.0"
source = "editable+."
sdist = { path = "." }

[[distribution.dependencies]]
name = "b"
version = "0.1.0"
source = "directory+/home/konsti/projects/uv/a"
```
2024-06-13 11:51:08 -04:00
konsti 081f20c53e
Add support for `tool.uv` into distribution building (#3904)
With the change, we remove the special casing of workspace dependencies
and resolve `tool.uv` for all git and directory distributions. This
gives us support for non-editable workspace dependencies and path
dependencies in other workspaces. It removes a lot of special casing
around workspaces. These changes are the groundwork for supporting
`tool.uv` with dynamic metadata.

The basis for this change is moving `Requirement` from
`distribution-types` to `pypi-types` and the lowering logic from
`uv-requirements` to `uv-distribution`. This changes should be split out
in separate PRs.

I've included an example workspace `albatross-root-workspace2` where
`bird-feeder` depends on `a` from another workspace `ab`. There's a
bunch of failing tests and regressed error messages that still need
fixing. It does fix the audited package count for the workspace tests.
2024-05-31 02:42:03 +00:00
Charlie Marsh cedd18e4c6
Remove some unused `pub` functions (#3872)
## Summary

I wrote a bad Python script to find these.
2024-05-28 15:58:13 +00:00
Charlie Marsh 8d566e553d
Use a cross-platform representation for relative paths in `pip compile` (#3804)
## Summary

I haven't tested on Windows yet, but the idea here is that we should use
a portable representation when printing paths.

I decided to limit the scope here to paths that we write to output
files.

Closes https://github.com/astral-sh/uv/issues/3800.
2024-05-24 03:02:42 +00:00
Zanie Blue 81eff0ecc8
Improve logging for environment locking (#3792)
```
DEBUG Acquired lock for `.venv`
```

instead of

```
DEBUG Trying to lock if free: .venv/.lock
```

At trace level, this includes the pre-lock message as well

```
TRACE Checking lock for `.venv`
DEBUG Acquired lock for `.venv`
```

We'll still display the lock file path when something goes wrong
2024-05-23 09:27:07 -05:00
Charlie Marsh e0da977fc9
Get `cargo shear` passing (#3533)
## Summary

Remove a few unused deps, and ignore `flate2` (which we include for
feature control).
2024-05-13 01:43:45 +00:00
Tom Parker-Shemilt bc963d13cb
Annotate sources of requirements (#3269)
## Summary

Fixes https://github.com/astral-sh/uv/issues/1343. This is kinda a first
draft at the moment, but does at least mostly work locally (barring some
bits of the test suite that seem to not work for me in general).

## Test Plan

Mostly running the existing tests and checking the revised output is
sane

## Outstanding issues

Most of these come down to "AFAIK, the existing tools don't support
these patterns, but `uv` does" and so I'm not sure there's an existing
good answer here! Most of the answers so far are "whatever was easiest
to build"

- [x] ~~Is "-r pyproject.toml" correct? Should it show something else or
get skipped entirely~~ No it wasn't. Fixed in
3044fa8b86
- [ ] If the requirements file is stdin, that just gets skipped. Should
it be recorded?
- [ ] Overrides get shown as "--override<override.txt>". Correct?
- [x] ~~Some of the tests (e.g.
`dependency_excludes_non_contiguous_range_of_compatible_versions`) make
assumptions about the order of package versions being outputted, which
this PR breaks. I'm not sure if the text is fairly arbitrary and can be
replaced or whether the behaviour needs fixing?~~ - fixed by removing
the custom pubgrub PartialEq/Hash
- [ ] Are all the `TrackedFromStr` et al changes needed, or is there an
easier way? I don't think so, I think it's necessary to track these sort
of things fairly comprehensively to make this feature work, and this
sort of invasive change feels necessary, but happy to be proved wrong
there :)
- [x] ~~If you have a requirement coming in from two or more different
requirements files only one turns up. I've got a closed-source example
for this (can go into more detail if needed), mostly consisting of a
complicated set of common deps creating a larger set. It's a rarer case,
but worth considering.~~ 042432b200
- [ ] Doesn't add annotations for `setup.py` yet
- This is pretty hard, as the correct location to insert the path is
`crates/pypi-types/src/metadata.rs`'s `parse_pkg_info`, which as it's
based off a source distribution has entirely thrown away such matters as
"where did this package requirement get built from". Could add "`built
package name`" as a dep, but that's a little odd.
2024-05-08 23:19:22 -04:00
Charlie Marsh f8a7813add
Rename `--force` to `--allow-existing` (#3416)
## Summary

We've found `--force` to be a confusing name here. (Not breaking as this
hasn't shipped in a release.)
2024-05-07 17:11:31 +00:00
Charlie Marsh 614c07329b
Allow `--force` to overwrite existing virtualenv (#2548)
## Summary

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

## Test Plan

- `mkdir .venv`
- `touch .venv/foo`
- `cargo run venv` (ensure failure)
- `cargo run venv --force` (ensure success)
- `cargo run venv --force` (ensure success again)
2024-05-01 16:34:52 +00:00
konsti 1344cfae4b
Use fs_err for cachedir errors (#3304)
When running

```
set UV_CACHE_DIR=%LOCALAPPDATA%\uv\cache-foo && uv venv venv
```

in windows CMD, the error would be just

```
error: The system cannot find the path specified. (os error 3)
```

The problem is that the first action in the cache dir is adding the tag,
and the `cachedir` crate is using `std::fs` instead of `fs_err`. I've
copied the two functions we use from the crate and changed the import
from `std::fs` to `fs_err`.

The new error is

```
error: failed to open file `C:\Users\Konstantin\AppData\Local\uv\cache-foo \CACHEDIR.TAG`
  Caused by: The system cannot find the path specified. (os error 3)
```

which correctly explains the problem.

Closes #3280
2024-04-29 16:33:10 +02:00
Ben Beasley 2d95ca4b83
Make the junction crate dependency Windows-only (#3043)
<!--
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

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

Since the [`junction` crate](https://crates.io/crates/junction)
implements Windows-only functionality, and since the only place it is
used is guarded by `#[cfg(windows)]`,


1f626bfc73/crates/uv-fs/src/lib.rs (L65-L86)

it makes sense not to depend on this crate at all on non-Windows
platforms.

If nothing else, this makes Linux distribution packagers’ lives just a
*tiny* bit easier.

## Test Plan

<!-- How was it tested? -->

On Fedora Linux 39:

```
# To avoid an error when /tmp and the working directory are on different filesystems:
$ mkdir _tmp
$ TMPDIR="${PWD}/tmp" cargo run -p uv-dev -- fetch-python
$ cargo test
```

I don’t have access to a Windows system.
2024-04-15 16:01:24 -05: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 691ed09a9b
Fix windows lock race: Lock exclusive after all try lock errors (#2800)
We don't know what kind of error the OS gives us on `try_lock_exclusive`
with an already locked file, so we assume all those errors are an
already locked file and call `lock_exclusive`.

For example the windows error:

```
Os {
    code: 33,
    kind: Uncategorized,
    message: "The process cannot access the file because another process has locked a portion of the file.",
}
```

Fixes #2767
2024-04-03 16:02:40 +02:00
Zanie Blue 248d6f89ef
Bring harmony to the test snapshot filtering situation (#2678)
The snapshot filtering situation has gotten way out of hand, with each
test hand-rolling it's own filters on top of copied cruft from previous
tests.

I've attempted to address this holistically:

- `TestContext.filters()` has everything you should need 
- This was introduced a while ago, but needed a few more filters for it
to be generalized everywhere
- Using `INSTA_FILTERS` is **not recommended** unless you do not want
the context filters
    - It is okay to extend these filters for things unrelated to paths
- If you have to write a custom path filter, please highlight it in
review so we can address it in the common module
- `TestContext.site_packages()` gives cross-platform access to the
site-packages directory
    - Do not manually construct the path to site-packages from the venv
- Do not turn off tests on Windows because you manually constructed a
Unix path to site-packages
- `TestContext.workspace_root` gives access to uv's repository directory
    - Use this for installing from `scripts/packages/`
- If you need coverage for relative paths, copy the test package into
the `temp_dir` don't change the working directory of the test fixture

There is additional work that can be done here, such as:

- Auditing and removing additional uses of `INSTA_FILTERS`
- Updating manual construction of `Command` instances to use a utility
- The `venv` tests are particularly frightening in their lack of a test
context and could use some love
- Improving the developer experience i.e. apply context filters to
snapshots by default
2024-03-27 14:10:12 +00: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
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
Charlie Marsh d9b160b405
Add backoff for transient Windows failures (#2419)
## Summary

This may be required elsewhere, but all the traces in that issue are
related to persisting the temporary directory to our persistent cache,
so lets start there.

See: https://github.com/astral-sh/uv/issues/1491.
2024-03-13 13:16:26 -04:00
Andrew Gallant 41c911fc41 uv-fs: fix Windows path literals
This was causing `cargo test --doc` to fail for me locally.
2024-03-08 09:10:14 -05:00
Andrew Gallant b3b5afaf78 uv-fs: transparently support reading UTF-16 files
This PR tweaks uv to support reading `requirements.txt` regardless of
whether it is encoded as UTF-8 or UTF-16. This is particularly relevant
on Windows where `uv pip freeze > requirements.txt` will likely write a
UTF-16 encoded `requirements.txt` file.

There is some discussion on #1666 where it's suggested that perhaps
we should explicitly not support this. I didn't see that until I
had already put this PR together, but even so, I think it's worth
considering this. UTF-16 is predominant on Windows. It is very easy
to produce a UTF-16 encoded file. Moreover, there is an easy and well
specified way to recognize and transcode UTF-16 encoded data to UTF-8.

I think the downside of this is that it could encourage the use UTF-16
encoded `requirements.txt` files *in addition* to UTF-8 encoded
files, and it would probably be nice to converge and standardize on
one encoding. One possible alternative to this PR is that we provide
a better error message. Another alternative is to ensure that a
`-o/--output` flag exists for all commands (neither `uv pip freeze` nor
`pip freeze` have such a flag) so that users can always write output
to a file without relying on their environment's piping behavior.
(Although this last alternative seems a little sad to me.)

It's also worth noting the [PEP-0508] doesn't seem to mention file
encoding at all. So I think from a "do the standards allow this"
perspective, this change is OK.

Finally, `pip` itself seems to work with UTF-16 encoded
`requirements.txt` files.

I think I personally overall lean towards supporting UTF-16 for
`requirements.txt` files. In part because I think it smoothes out the
UX a little bit, in part because there is no obvious specification
(that I'm aware of) that mandates that these files are UTF-8, and
finally in part because `pip` supports it too.

Fixes #1666, Fixes #2276

[PEP-0508]: https://peps.python.org/pep-0508/
2024-03-08 09:10:14 -05:00
Charlie Marsh 996a859b29
Use reparse points to detect Windows installer shims (#2284)
## Summary

This PR enables use of the Windows Store Pythons even with `py` is not
installed. Specifically, we need to ensure that the `python.exe` and
`python3.exe` executables installed into the
`C:\Users\crmar\AppData\Local\Microsoft\WindowsApp` directory _are_ used
when they're not "App execution aliases" (which merely open the Windows
Store, to help you install Python).

When `py` is installed, this isn't strictly necessary, since the
"resolved" executables are discovered via `py`. These look like
`C:\Users\crmar\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.11_qbs5n2kfra8p0\python.exe`.

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

## Test Plan

- Removed all Python installations from my Windows machine.
- Uninstalled `py`.
- Enabled "App execution aliases".
- Verified that for both `cargo run venv --python python.exe` and `cargo
run venv --python python3.exe`, `uv` exited with a failure that no
Python could be found.
- Installed Python 3.10 via the Windows Store.
- Verified that the above commands succeeded without error.
- Verified that `cargo run venv --python python3.10.exe` _also_
succeeded.
2024-03-07 15:47:32 -05:00
konsti de0109169d
Fix uv tokio extra, part 2 (#2274)
Follow to #2272 by adding the tokio gate to `read_to_string`.
2024-03-07 12:27:37 +00:00
konsti 85042308a1
Fix uv-fs extras by removing dead code (#2272)
Running the pep508_rs tests was failing due to uv-fs depending on
`fs_err::tokio` even when not selected. But the function that used it is
unused anyway, so i removed it.
2024-03-07 12:16:29 +00:00
jannisko 71626e8dec
Support remote `https://` requirements files (#1332) (#2081)
## Summary

Allow using http(s) urls for constraints and requirements files handed
to the CLI, by handling paths starting with `http://` or `https://`
differently. This allows commands for such as: `uv pip install -c
https://raw.githubusercontent.com/apache/airflow/constraints-2.8.1/constraints-3.8.txt
requests`.

closes #1332

## Test Plan

Testing install using a `constraints.txt` file hosted on github in the
airflow repository:

fbdc2eba8e/crates/uv/tests/pip_install.rs (L1440-L1484)

## Advice Needed

- filesystem/http dispatch is implemented at a relatively low level (at
`crates/uv-fs/src/lib.rs#read_to_string`). Should I change some naming
here so it is obvious that the function is able to dispatch?
- I kept the CLI argument for -c and -r as a PathBuf, even though now it
is technically either a path or a url. We could either keep this as is
for now, or implement a new enum for this case? The enum could then
handle dispatch to files/http.
- Using another abstraction layer like
https://docs.rs/object_store/latest/object_store/ for the
files/urls/[s3] could work as well, though I ran into a bug during
testing which I couldn't debug
2024-03-06 04:18:11 +00: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 1f19ef670b
Avoid canonicalizing user-provided interpreters (#2072)
## Summary

We shouldn't be resolving symlinks on the provided interpreter;
otherwise we break `pyenv`, since running `cargo run pip install mypy
--python .venv/bin/python` will immediately resolve to (e.g.)
`/Users/crmarsh/.pyenv/versions/3.10.2/bin/python3.10`, and pyenv relies
on the path to do its lookups.

Instead, the canonicalizing happens when we query the interpreter
metadata.

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

## Test Plan

Ran `cargo run pip install mypy --python .venv/bin/python -v -n` with a
virtualenv created using a pyenv Python; verified that Mypy was
installed into the virtual environment, rather than into the global
environment.
2024-02-28 21:32:52 -05:00
Charlie Marsh ef15098288
Use `Simplified` instead of `Normalized` for path prefix stripping (#2071)
## Summary

This directly matches the naming of the `dunce` methods.
2024-02-29 01:44:50 +00: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
Zanie Blue 2586f655bb
Rename to `uv` (#1302)
First, replace all usages in files in-place. I used my editor for this.
If someone wants to add a one-liner that'd be fun.

Then, update directory and file names:

```
# Run twice for nested directories
find . -type d -print0 | xargs -0 rename s/puffin/uv/g
find . -type d -print0 | xargs -0 rename s/puffin/uv/g

# Update files
find . -type f -print0 | xargs -0 rename s/puffin/uv/g
```

Then add all the files again

```
# Add all the files again
git add crates
git add python/uv

# This one needs a force-add
git add -f crates/uv-trampoline
```
2024-02-15 11:19:46 -06:00