Files
uv/crates
Chisato 538ebe6fcf Fix symlink preservation in virtual environment creation (#14933)
## Summary

  Fixes inconsistent symlink handling in `uv venv` command (#14670).

## Problem


00efde06b6/crates/uv-virtualenv/src/virtualenv.rs (L81)

The original code used `Path::metadata()` which automatically follows
symlinks, causing the system to treat symlinked virtual environment
paths as regular directories. When a user runs uv venv on an existing
symlinked virtual environment `(.venv -> foo)`, the code incorrectly
treats the symlink as a regular directory because `location.metadata()`
automatically follows the symlink and returns metadata for the target
directory `foo/`. This causes the removal logic to delete the symlink
itself and permanently breaking the symlink relationship and replacing
it with a standard directory structure.
 
## Solution

- Use canonicalize() to resolve symlinks only when removing and
recreating virtual
  environments
- This ensures operations target the actual directory while preserving
the symlink
  structure
- Minimal change that fixes the core issue without complex path
management

## Test Plan

```bash
➜  test-env alias uv-dev='/Users/wingmunfung/workspace/uv/target/debug/uv'
➜  test-env ln -s dummy foo
➜  test-env ln -s foo .venv
➜  test-env ls -lah        
total 0
drwxr-xr-x   4 wingmunfung  staff   128B Jul 30 10:39 .
drwxr-xr-x  48 wingmunfung  staff   1.5K Jul 29 17:08 ..
lrwxr-xr-x   1 wingmunfung  staff     3B Jul 30 10:39 .venv -> foo
lrwxr-xr-x   1 wingmunfung  staff     5B Jul 30 10:39 foo -> dummy
➜  test-env uv-dev venv
Using CPython 3.13.2
Creating virtual environment at: .venv
error: Failed to create virtual environment
  Caused by: failed to create directory `.venv`: File exists (os error 17)
➜  test-env mkdir dummy
➜  test-env uv-dev venv
Using CPython 3.13.2
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
➜  test-env ls -lah
total 0
drwxr-xr-x   5 wingmunfung  staff   160B Jul 30 10:39 .
drwxr-xr-x  48 wingmunfung  staff   1.5K Jul 29 17:08 ..
lrwxr-xr-x   1 wingmunfung  staff     3B Jul 30 10:39 .venv -> foo
drwxr-xr-x   7 wingmunfung  staff   224B Jul 30 10:39 dummy
lrwxr-xr-x   1 wingmunfung  staff     5B Jul 30 10:39 foo -> dummy
➜  test-env uv-dev venv
Using CPython 3.13.2
Creating virtual environment at: .venv
✔ A virtual environment already exists at `.venv`. Do you want to replace it? · yes
Activate with: source .venv/bin/activate
➜  test-env ls -lah
total 0
drwxr-xr-x   5 wingmunfung  staff   160B Jul 30 10:39 .
drwxr-xr-x  48 wingmunfung  staff   1.5K Jul 29 17:08 ..
lrwxr-xr-x   1 wingmunfung  staff     3B Jul 30 10:39 .venv -> foo
drwxr-xr-x@  7 wingmunfung  staff   224B Jul 30 10:39 dummy
lrwxr-xr-x   1 wingmunfung  staff     5B Jul 30 10:39 foo -> dummy

### the symlink still exists
```

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2025-07-31 11:59:23 +00:00
..
2025-07-30 16:24:20 +00:00
2025-07-25 15:19:38 -05:00
2025-04-04 11:49:26 -04:00
2025-07-30 16:24:20 +00:00

Crates

uv-bench

Functionality for benchmarking uv.

uv-cache-key

Generic functionality for caching paths, URLs, and other resources across platforms.

uv-distribution-filename

Parse built distribution (wheel) and source distribution (sdist) filenames to extract structured metadata.

uv-distribution-types

Abstractions for representing built distributions (wheels) and source distributions (sdists), and the sources from which they can be downloaded.

uv-install-wheel-rs

Install built distributions (wheels) into a virtual environment.

uv-once-map

A waitmap-like concurrent hash map for executing tasks exactly once.

uv-pep440-rs

Utilities for interacting with Python version numbers and specifiers.

uv-pep508-rs

Utilities for parsing and evaluating dependency specifiers, previously known as PEP 508.

uv-platform-tags

Functionality for parsing and inferring Python platform tags as per PEP 425.

uv-cli

Command-line interface for the uv package manager.

uv-build-frontend

A PEP 517-compatible build frontend for uv.

uv-cache

Functionality for caching Python packages and associated metadata.

uv-client

Client for interacting with PyPI-compatible HTTP APIs.

uv-dev

Development utilities for uv.

uv-dispatch

A centralized struct for resolving and building source distributions in isolated environments. Implements the traits defined in uv-types.

uv-distribution

Client for interacting with built distributions (wheels) and source distributions (sdists). Capable of fetching metadata, distribution contents, etc.

uv-extract

Utilities for extracting files from archives.

uv-fs

Utilities for interacting with the filesystem.

uv-git

Functionality for interacting with Git repositories.

uv-installer

Functionality for installing Python packages into a virtual environment.

uv-python

Functionality for detecting and leveraging the current Python interpreter.

uv-normalize

Normalize package and extra names as per Python specifications.

uv-requirements

Utilities for reading package requirements from pyproject.toml and requirements.txt files.

uv-resolver

Functionality for resolving Python packages and their dependencies.

uv-shell

Utilities for detecting and manipulating shell environments.

uv-types

Shared traits for uv, to avoid circular dependencies.

uv-pypi-types

General-purpose type definitions for types used in PyPI-compatible APIs.

uv-virtualenv

A venv replacement to create virtual environments in Rust.

uv-warnings

User-facing warnings for uv.

uv-workspace

Workspace abstractions for uv.

uv-requirements-txt

Functionality for parsing requirements.txt files.