Open-Source Wikis

/

uv

/

Crates

/

uv-python

astral-sh/uv

uv-python

crates/uv-python/ is uv's Python interpreter management subsystem: how uv finds an interpreter, queries it, and (when needed) downloads one. It is by far the largest non-binary crate (~3.3 MB on disk, including the embedded download manifest).

Purpose

Python is a moving target. uv has to:

  • Discover a usable interpreter from a request like >=3.12,<3.13, cpython@3.12, or pypy@3.10. Sources include the active venv, the project's .venv, PATH, the Windows registry, the Microsoft Store, uv's managed install directory, and the Microsoft pyenv-win directory.
  • Query an interpreter to populate a MarkerEnvironment (sys, sysconfig, platform).
  • Download and install managed Python builds from python-build-standalone (CPython) or upstream PyPy releases.
  • Pin the interpreter for a project via .python-version or .python-versions.

Directory layout

crates/uv-python/
├── Cargo.toml
├── README.md
├── build.rs                          # Build-time setup
├── download-metadata.json            # 2.6 MB: every managed Python build uv knows about
├── fetch-download-metadata.py        # Refreshes download-metadata.json from upstream
├── python/                           # Python introspection scripts run via subprocess
└── src/
    ├── lib.rs                        # 102k chars; module wiring + Error type
    ├── discovery.rs                  # 175k chars; the discovery state machine
    ├── downloads.rs                  # 84k chars; managed-Python download/install
    ├── managed.rs                    # 50k chars; ManagedPythonInstallations + ManagedPythonInstallation
    ├── interpreter.rs                # 55k chars; Interpreter introspection via subprocess
    ├── installation.rs               # 32k chars; PythonInstallation: a discovered interpreter
    ├── environment.rs                # PythonEnvironment: a venv we can install into
    ├── implementation.rs             # ImplementationName (CPython, PyPy, GraalPy, …)
    ├── python_version.rs             # PythonVersion + parsing
    ├── version_files.rs              # .python-version / .python-versions readers
    ├── virtualenv.rs                 # PyVenvConfiguration parsing (the pyvenv.cfg file)
    ├── target.rs                     # `--target` install destination
    ├── prefix.rs                     # `--prefix` install destination
    ├── macos_dylib.rs                # macOS dylib handling for managed Python
    ├── microsoft_store.rs            # Windows Store integration (only on Windows)
    ├── windows_registry.rs           # PEP 514 Windows registry discovery
    ├── pointer_size.rs               # 32/64-bit detection
    ├── sysconfig/                    # sysconfig parsing helpers
    └── ...                           # Tests embedded in the modules

Key abstractions

Type File Role
PythonRequest discovery.rs A user's interpreter request: version range, implementation, executable path, install dir, …. Parses strings like cpython>=3.12,<3.13.
PythonPreference discovery.rs OnlyManaged, Managed (default), System, OnlySystem. Determines whether discovery considers managed installs, system installs, or only one.
PythonDownloads discovery.rs Automatic (default), Manual, Never. Whether discovery may download a missing Python.
PythonSource discovery.rs Where a discovered interpreter came from (active venv, parent venv, system path, registry, managed, …).
EnvironmentPreference discovery.rs Whether discovery prefers virtual environments, system, or any.
find_python_installations discovery.rs The top-level discovery iterator. Returns a stream of PythonInstallation candidates ordered by preference.
PythonInstallation installation.rs A discovered Python: implementation, version, executable, source.
PythonInstallationKey / PythonInstallationMinorVersionKey installation.rs Stable string keys (cpython-3.12.3-macos-aarch64-none) used by managed installs and the .python-version file.
Interpreter interpreter.rs A queried interpreter: marker environment, paths, sysconfig, prefix, real path. Loaded by spawning the interpreter and parsing JSON output from python/get_interpreter_info.py.
PythonEnvironment environment.rs A venv (existing or new) backed by an Interpreter. The install destination for uv pip install and uv sync.
ManagedPythonInstallations / ManagedPythonInstallation managed.rs Reads/writes uv's managed Python directory (uv python dir). Each install is keyed by PythonInstallationKey.
PlatformRequest downloads.rs The platform tuple (OS, arch, libc, variant) for downloads.
PythonVersion python_version.rs Strongly-typed Python version with parsing.
PythonVersionFile version_files.rs The parsed .python-version or .python-versions file.
PyVenvConfiguration virtualenv.rs The pyvenv.cfg parser.

How it works

flowchart TD
    request[PythonRequest<br/>e.g. >=3.12,<3.13] --> find[find_python_installations]
    find --> sources[(Discovery sources<br/>active venv, .venv, PATH,<br/>Windows registry, Microsoft Store,<br/>managed installs)]
    sources --> candidate[PythonInstallation candidate]
    candidate -->|matches request?| ok{Compatible?}
    ok -->|yes| query[Query: spawn python -c<br/>get_interpreter_info.py]
    query --> interpreter[Interpreter]
    ok -->|no, none compatible<br/>and downloads enabled| download[downloads::install_managed]
    download --> manifest[download-metadata.json]
    download --> fetch[Download tarball, verify hash]
    fetch --> extract[Unpack into uv-python dir]
    extract --> query
    interpreter --> env[PythonEnvironment]

Discovery

discovery.rs is the longest source file in uv (~175 KB) because the discovery rules are extensive. The basic flow:

  1. Iterate discovery sources in preference order. The default order roughly is: active VIRTUAL_ENV, project .venv, parent venvs, UV_PYTHON_PATH/PATH, managed installs, Windows registry, Microsoft Store, system Python.
  2. For each candidate, parse the executable name to skip obvious mismatches (e.g., python2 when the user asked for 3.x).
  3. Spawn the candidate to query its real version and implementation via python/get_interpreter_info.py. Cache the result in ~/.cache/uv/interpreter-v$N/ keyed by executable timestamp.
  4. Compare against the PythonRequest (version specifier + implementation + variant).
  5. Filter by PythonPreference (system vs. managed) and EnvironmentPreference.

The cache is critical — interpreter queries are expensive. The cache key uses the executable path's mtime so any update invalidates the cache.

Querying

Interpreter::query runs the candidate Python with crates/uv-python/python/'s introspection script. The script imports sys, sysconfig, platform, and os, then prints a JSON document on stdout that includes:

  • sys.version, sys.executable, sys.implementation.
  • sysconfig.get_paths(...) for both posix_prefix and posix_user.
  • os.name, platform.machine(), platform.libc_ver().
  • sysconfig.get_config_vars(...) for ABI tags.
  • All variables required to evaluate PEP 508 markers.

The result populates an Interpreter and a MarkerEnvironment.

Managed installs

managed.rs and downloads.rs together implement uv python install:

  1. Resolve the requested key against the in-tree download-metadata.json. The manifest is regenerated by fetch-download-metadata.py and committed; this means uv python install doesn't need to talk to a metadata server first.
  2. Download the tarball, verify the SHA-256 against the manifest, and extract it under uv python dir.
  3. Apply platform-specific fixups: rewrite RPATHs on Linux, rewrite Mach-O install names on macOS (macos_dylib.rs), register the install with the Windows registry under PEP 514.
  4. Place stable shims in the user-executable directory (uv python update-shell).

.python-version

version_files.rs reads .python-version (single version) and .python-versions (multi-line) files. uv python pin writes them. The discovery layer treats them as another input alongside explicit --python arguments and tool.uv.python config keys.

Integration points

  • Resolver. The resolver takes the PythonRequirement (target + exact) computed from the active interpreter and the project's requires-python range.
  • Installer. PythonEnvironment is the install destination. The installer reads Interpreter::sys_executable and Interpreter::site_packages to know where to put files.
  • uv-virtualenv. When uv needs to create a new venv, it calls into uv-virtualenv with an Interpreter for the base Python.
  • Caching. Interpreter query results, download archives, and manifest data all flow through uv-cache.
  • Cross-OS quirks. macOS dylib handling in macos_dylib.rs, Windows registry/PE manifests in windows_registry.rs and microsoft_store.rs, Unix RPATH fixups in managed.rs.

Entry points for modification

  • Add a new discovery sourcediscovery.rs. Each source is a function that yields PythonInstallation candidates; the dispatcher in find_python_installations orders them.
  • Add a new managed Python build — refresh download-metadata.json via fetch-download-metadata.py and bump the manifest. crates/uv-python/build.rs will pull the resulting JSON into the binary.
  • Adjust .python-version semanticsversion_files.rs and discovery.rs (VersionFileDiscoveryOptions).
  • Tweak interpreter cachinginterpreter.rs. The query cache lives under ~/.cache/uv/interpreter-v$N/; bumping the version invalidates older entries.

Key source files

File Purpose
crates/uv-python/src/discovery.rs The discovery state machine; sources, ordering, and request matching.
crates/uv-python/src/interpreter.rs Interpreter::query and the marker-environment builder.
crates/uv-python/src/downloads.rs Downloading, hashing, extracting managed Python builds.
crates/uv-python/src/managed.rs The on-disk managed-Python directory layout.
crates/uv-python/src/installation.rs PythonInstallation and the canonical key.
crates/uv-python/src/environment.rs PythonEnvironment (a venv-shaped install).
crates/uv-python/src/version_files.rs .python-version / .python-versions.
crates/uv-python/src/windows_registry.rs PEP 514 Windows registry support.
crates/uv-python/download-metadata.json The manifest of managed Python builds.
crates/uv-python/python/ The introspection scripts run via subprocess.

See also

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

uv-python – uv wiki | Factory