uv/CONTRIBUTING.md
Aria Desires 80ac8db7db
Some checks are pending
CI / check system | python on macos x86_64 (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / lint (push) Waiting to run
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / cargo shear (push) Waiting to run
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | macos (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / build binary | linux (push) Blocked by required conditions
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / build binary | windows (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | free-threaded on linux (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / check system | python3.10 on windows (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / check system | python on debian (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | python on opensuse (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on linux (push) Blocked by required conditions
CI / check system | conda3.8 on linux (push) Blocked by required conditions
CI / check system | conda3.11 on macos (push) Blocked by required conditions
CI / check system | conda3.8 on macos (push) Blocked by required conditions
CI / check system | conda3.11 on windows (push) Blocked by required conditions
CI / check system | conda3.8 on windows (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
Always spawn a main2 thread to normalize main stack size issues (#10479)
Also removes UV_STACK_SIZE and uses RUST_MIN_STACK instead, tweaking
docs to reflect the differences.

Fixes #10367
2025-01-14 22:35:17 -05:00

6.3 KiB

Contributing

We have issues labeled as Good First Issue and Help Wanted which are good opportunities for new contributors.

Setup

Rust, a C compiler, and CMake are required to build uv.

Linux

On Ubuntu and other Debian-based distributions, you can install the C compiler and CMake with:

sudo apt install build-essential cmake

macOS

You can install CMake with Homebrew:

brew install cmake

See the Python section for instructions on installing the Python versions.

Windows

You can install CMake from the installers or with pipx install cmake.

Testing

For running tests, we recommend nextest.

If tests fail due to a mismatch in the JSON Schema, run: cargo dev generate-json-schema.

Python

Testing uv requires multiple specific Python versions; they can be installed with:

cargo run python install

The storage directory can be configured with UV_PYTHON_INSTALL_DIR.

Snapshot testing

uv uses insta for snapshot testing. It's recommended (but not necessary) to use cargo-insta for a better snapshot review experience. See the installation guide for more information.

In tests, you can use uv_snapshot! macro to simplify creating snapshots for uv commands. For example:

#[test]
fn test_add() {
    let context = TestContext::new("3.12");
    uv_snapshot!(context.filters(), context.add().arg("requests"), @"");
}

To run and review a specific snapshot test:

cargo test --package <package> --test <test> -- <test_name> -- --exact
cargo insta review

Local testing

You can invoke your development version of uv with cargo run -- <args>. For example:

cargo run -- venv
cargo run -- pip install requests

Running inside a Docker container

Source distributions can run arbitrary code on build and can make unwanted modifications to your system ("Someone's Been Messing With My Subnormals!" on Blogspot, "nvidia-pyindex" on PyPI), which can even occur when just resolving requirements. To prevent this, there's a Docker container you can run commands in:

$ docker buildx build -t uv-builder -f builder.dockerfile --load .
# Build for musl to avoid glibc errors, might not be required with your OS version
cargo build --target x86_64-unknown-linux-musl --profile profiling
docker run --rm -it -v $(pwd):/app uv-builder /app/target/x86_64-unknown-linux-musl/profiling/uv-dev resolve-many --cache-dir /app/cache-docker /app/scripts/popular_packages/pypi_10k_most_dependents.txt

We recommend using this container if you don't trust the dependency tree of the package(s) you are trying to resolve or install.

Profiling and Benchmarking

Please refer to Ruff's Profiling Guide, it applies to uv, too.

We provide diverse sets of requirements for testing and benchmarking the resolver in scripts/requirements and for the installer in scripts/requirements/compiled.

You can use scripts/benchmark to benchmark predefined workloads between uv versions and with other tools, e.g., from the scripts/benchmark directory:

uv run resolver \
    --uv-pip \
    --poetry \
    --benchmark \
    resolve-cold \
    ../scripts/requirements/trio.in

Analyzing concurrency

You can use tracing-durations-export to visualize parallel requests and find any spots where uv is CPU-bound. Example usage, with uv and uv-dev respectively:

RUST_LOG=uv=info TRACING_DURATIONS_FILE=target/traces/jupyter.ndjson cargo run --features tracing-durations-export --profile profiling -- pip compile scripts/requirements/jupyter.in
RUST_LOG=uv=info TRACING_DURATIONS_FILE=target/traces/jupyter.ndjson cargo run --features tracing-durations-export --bin uv-dev --profile profiling -- resolve jupyter

Trace-level logging

You can enable trace level logging using the RUST_LOG environment variable, i.e.

RUST_LOG=trace uv

Documentation

To preview any changes to the documentation locally:

  1. Install the Rust toolchain.

  2. Run cargo dev generate-all, to update any auto-generated documentation.

  3. Run the development server with:

    # For contributors.
    uvx --with-requirements docs/requirements.txt -- mkdocs serve -f mkdocs.public.yml
    
    # For members of the Astral org, which has access to MkDocs Insiders via sponsorship.
    uvx --with-requirements docs/requirements-insiders.txt -- mkdocs serve -f mkdocs.insiders.yml
    

The documentation should then be available locally at http://127.0.0.1:8000/uv/.

To update the documentation dependencies, edit docs/requirements.in and docs/requirements-insiders.in, then run:

uv pip compile docs/requirements.in -o docs/requirements.txt --universal -p 3.12
uv pip compile docs/requirements-insiders.in -o docs/requirements-insiders.txt --universal -p 3.12

Documentation is deployed automatically on release by publishing to the Astral documentation repository, which itself deploys via Cloudflare Pages.

After making changes to the documentation, format the markdown files with:

npx prettier --prose-wrap always --write "**/*.md"

Releases

Releases can only be performed by Astral team members.

Changelog entries and version bumps are automated. First, run:

./scripts/release.sh

Then, editorialize the CHANGELOG.md file to ensure entries are consistently styled.

Then, open a pull request e.g. Bump version to ....

Binary builds will automatically be tested for the release.

After merging the pull request, run the release workflow with the version tag. Do not include a leading v. The release will automatically be created on GitHub after everything else publishes.