Released on 2026-07-28.
Since we released uv 0.11.0 in March, we've accumulated changes that improve correctness, safety, and compatibility with specifications, but could break some workflows. This release contains those changes; many have been marked as breaking out of an abundance of caution.
We expect most users to be able to upgrade without making changes.
There are no breaking changes to the configuration of the
uv build backend. If your [build-system]
table includes an upper bound on uv_build, update it to allow uv_build 0.12, e.g.,
uv_build>=0.11.32,<0.13.
-
Define build systems by default with
uv init(#19197)Projects created with
uv initnow declare a build system and are packaged by default. This was the default project layout all the way back in v0.3, but we found that the use of thehatchlingbuild system was confusing to newcomers and consequently dropped use of a build system by default in v0.4. Since then, we've created our own build system (uv_build) with tight integration with uv and are excited to restore the default to a best-practice project layout.Previously,
uv init examplecreated an unpackaged layout containingmain.pyand apyproject.tomlwithout a build system. The project could declare dependencies but was not itself installed into its virtual environment.Now,
uv init exampledefines a[build-system]usinguv_build, places application source code insrc/example, and includes a[project.scripts]entry namedexample. Defining a build system allows the project to be imported from tests or other code, installed as a dependency, and run as a command:$ uv init example $ cd example $ uv run example Hello from example!
Existing projects are unaffected. Use
uv init --no-package exampleto create the previous unpackaged layout without a build system.See the project creation documentation for more details.
This stabilizes the
packaged-initpreview feature. -
Reject unsupported source distribution and wheel archive formats (#18927)
PEP 625 requires source distributions to use
.tar.gzarchives. Previously, uv also accepted legacy formats such as.tar.bz2and.tar.xz. Those formats are now rejected, including when referenced by an existing lockfile. Legacy.zipsource distributions remain supported for backwards compatibility.Wheels and other ZIP archives can no longer contain entries compressed with bzip2, LZMA, or XZ. Entries must use the stored, DEFLATE, or zstd compression methods.
Removing support for uncommon compression methods reduces uv's compression dependencies and the attack surface exposed when processing untrusted packages.
You cannot opt out of this behavior. If you depend on a legacy source distribution that uses an unsupported format, we recommend rebuilding it as a
.tar.gzarchive and regenerating any lockfile containing references to the legacy archive. -
Reject wheel files that could replace the Python interpreter (#20748, #20749)
uv already rejected wheel entry points named
python, but case variants such asPythonwere still accepted. On case-insensitive filesystems, including common macOS and Windows setups, these entry points could overwrite the virtual environment's interpreter.Wheels could also place interpreter files in their
.data/scriptsdirectory or in paths such as.data/data/bin/python, bypassing the entry-point check and replacing the interpreter during installation.uv now rejects case-insensitive variants of reserved interpreter names and wheel data files that would be installed over an interpreter. This includes names such as
Python,python.py, andPython.exe, along with other reserved interpreter names and their versioned variants.You cannot opt out of these checks. Rename conflicting entry points or wheel data files and rebuild the affected wheel.
-
Prefer stable releases before falling back to pre-releases (#19993)
A dependency can introduce a pre-release requirement after resolution starts. uv previously required each package's pre-release eligibility to be known before resolution began: the default
if-necessary-or-explicitmode allowed them for direct requirements that explicitly requested a pre-release, or for packages that only published pre-releases.This meant that a pre-release requirement discovered in a dependency's metadata, e.g.,
example>=2.0.0b1, would fail to resolve even when a compatible pre-release existed. To resolve it, you had to add that dependency as a direct requirement or allow pre-releases across your entire dependency graph.The default mode is now
if-necessary. uv tries stable candidates first and falls back to pre-releases when no stable candidate satisfies the active constraints. Like pip, uv now supports pre-release requirements discovered transitively, but can select different versions than previous uv releases when both stable and pre-release candidates are available.You can opt out of automatic pre-release selection with
--prerelease disallow. Alternatively,--prerelease allowconsiders pre-releases without first preferring stable releases, and--prerelease explicitonly allows them for direct requirements that mention a pre-release.The old
if-necessary-or-explicitmode distinguished between explicitly requested pre-releases and packages with no stable releases. That distinction is unnecessary now thatif-necessaryhandles both cases, including transitive requirements. The old name remains available as an alias but is deprecated and will be removed in a future release. -
Respect
--require-hashesdirectives inrequirements.txt(#19336)Previously,
uv pip installanduv pip syncwarned about--require-hashesinside arequirements.txtfile but still installed dependencies without checking their hashes. Now, the directive enables hash-checking mode, just as if--require-hasheshad been passed on the command line.For example, this requirements file is no longer accepted because the requirement is neither pinned nor hashed:
--require-hashes anyioYou cannot opt out while the directive is present. Pin every requirement with
==and provide its hash, or remove--require-hashesif hash checking is not intended. -
Reject MD5-only hashes in hash-checking mode (#20758)
Previously,
uv pip install --require-hashesanduv pip sync --require-hashesaccepted requirements whose only available digest used MD5. MD5 is not collision-resistant, so relying on it undermined installations that require hash verification and differed from pip's behavior.Hash-checking mode now requires at least one secure digest for every requirement. For example, the following requirement is rejected unless a secure hash, such as SHA-256, is also supplied:
anyio==4.0.0 --hash=md5:420d85e19168705cdf0223621b18831aA secure hash can be supplied directly on the requirement or in a matching constraints file. Ordinary hash verification without
--require-hashescontinues to support MD5.You cannot opt out while hash checking is required. Regenerate affected hashes with SHA-256 or another supported secure hash.
-
Reject invalid
pylock.tomlfiles and artifacts (#20402, #20440, #20443)uv now validates additional requirements from the
pylock.tomlspecification:- The
packagesarray must be present. Previously, uv interpreted a missing array as an empty lockfile, souv pip synccould uninstall an environment instead of rejecting malformed input. An explicitly emptypackages = []array remains valid. - Lockfile filenames must be
pylock.tomlor a single-name variant such aspylock.dev.toml. Names such aspylock..tomlandpylock.foo.bar.tomlare rejected. - If a wheel, source distribution, or other artifact declares a
size, the downloaded or cached artifact must match. Previously, an incorrect size was accepted when the hash was correct. Sizes reported by package indexes remain advisory.
You cannot opt out of these checks. Regenerate malformed lockfiles, rename invalid filenames, and either correct or remove an incorrect optional
sizevalue. - The
-
Honor explicit certificate overrides even when no certificates can be loaded (#20741, #20767)
Previously, uv ignored
SSL_CERT_FILEorSSL_CERT_DIRvalues that pointed to missing or inaccessible paths, empty files or directories, or sources without valid certificates. Instead, it fell back to its default trust roots, potentially allowing HTTPS connections that the configured override was intended to reject.Now, any non-empty
SSL_CERT_FILEorSSL_CERT_DIRvalue replaces uv's default certificate roots, even when no valid certificates can be loaded. In that case, HTTPS requests fail because no certificates are trusted. This applies to package downloads and remote scripts, including GitHub Gists.Fix or unset the certificate override. Unsetting it restores the default trust store; empty environment-variable values continue to be ignored.
-
Support pip-compatible
--certhandling inuv pip(#20418)The
uv pipinterface now accepts--cert <path>, e.g.:$ uv pip install --cert ./company-ca.pem exampleAs in pip, the provided PEM bundle replaces all other certificate sources for that invocation, including system certificates and
SSL_CERT_FILEorSSL_CERT_DIR. This change has no effect unless you pass--cert. Include the necessary certificate authorities in the bundle.--certis only supported byuv pipcommands; other uv commands continue to use their existing certificate configuration. -
Discover projects relative to the script passed to
uv run(#20225)Previously,
uv run project/script.pydiscovered its project from the current directory, even when the script belonged to another project. uv now starts project and workspace discovery from the script's directory instead.For example, running
uv run other-project/script.pynow usesother-projectand its dependencies. This fixes scripts that previously failed because their own dependencies were not installed, but can select a different environment than before.You can opt out of script-relative discovery by selecting a project explicitly, e.g.,
uv run --project . other-project/script.py.This stabilizes the
target-workspace-discoverypreview feature. -
Require
--forcebefore clearing a directory that is not a virtual environment (#20225)uv venv --clearpreviously removed any existing target directory, even if it was not a virtual environment. uv emitted a warning but still deleted the directory and its contents. Now, uv refuses to clear directories that do not contain a virtual environment.You can opt out of this safety check by explicitly passing
--force, e.g.,uv venv --clear --force ./not-a-virtualenv.This stabilizes the
venv-safe-clearpreview feature. -
Reject
--projectwhen initializing a project (#20225)--projectselects an existing project, so it is not meaningful when initializing a new one. Previously,uv init --project examplewarned and initializedexampleanyway; if a positional path was also provided,--projectwas ignored.This usage is now an error. Use
uv init exampleto initialize a project at the requested path, oruv init --directory exampleto change the working directory first.This stabilizes the
init-project-flagpreview feature. -
Reject missing or invalid
--projectpaths (#20225)uv previously warned when
--projectreferred to a missing directory or a file other thanpyproject.toml, but then attempted to continue. This could produce confusing errors later or run against an unintended project.Now,
uv run --project missing pythonfails immediately instead of continuing. You cannot opt out of this behavior. Create the directory first or select an existing project. Passing--project path/to/pyproject.tomlremains supported and selects the file's parent directory.This stabilizes the
project-directory-must-existpreview feature. -
Skip distributions with non-normalized filenames when publishing (#20225)
Distribution filenames must use normalized package names and versions. For example, a wheel for version
1.01.0should be namedexample-1.1.0-py3-none-any.whl, notexample-1.01.0-py3-none-any.whl.Previously,
uv publishwarned about non-normalized filenames but still attempted to upload them. It now skips the affected wheels and source distributions instead.You cannot opt out of this behavior. Rebuild distributions with normalized filenames before publishing.
This stabilizes the
publish-require-normalizedpreview feature. -
Classify Conda environments named
baseandrootby their paths (#20225)Conda environments named
baseorrootwere previously assumed to be the base Conda environment, even when they were ordinary child environments. uv now recognizes child Conda environments namedbaseorrootbased on their paths, as it already does for other names.You can opt out of automatic interpreter selection by requesting an interpreter explicitly with
--python /path/to/python.This stabilizes the
special-conda-env-namespreview feature. -
Reject broken
.venvsymlinks during environment discovery (#20433)Previously, uv could ignore a broken
.venvsymlink and continue searching parent directories for another virtual environment. As a result, commands such asuv pip installcould unexpectedly modify an unrelated ancestor environment.uv now stops at a broken
.venvsymlink and reports its exact path. Errors encountered while reading virtual environment metadata, including permission failures, are also reported immediately instead of being ignored.You cannot opt out of this behavior. Repair or remove the broken
.venvsymlink and correct any permissions that prevent uv from inspecting the environment. -
Reinstall matching installed Python patch versions instead of upgrading implicitly (#20659)
Before Python upgrades were supported,
uv python install 3.12 --reinstalldoubled as a way to install the latest Python 3.12 patch release. Now that--upgradeis available,--reinstallreinstalls the matching patch releases that are already present.For example, if Python 3.12.6 and 3.12.7 are installed,
uv python install 3.12 --reinstallreinstalls both versions instead of installing the latest available 3.12 release.You can recover the previous upgrade behavior with
uv python install 3.12 --upgrade. Combine--upgrade --reinstallto reinstall only the latest patch. -
Require
--upgrade-groupto name an existing dependency group (#18957)Previously,
uv lock --upgrade-group docssilently succeeded even if nodocsdependency group existed. uv now validates the requested group against the project, its workspace members, and workspace-level dependency groups.You cannot opt out of this behavior. Correct the group name or add it to
[dependency-groups]. Legacytool.uv.dev-dependenciesstill satisfies--upgrade-group dev. -
Resolve relative indexes and find-links against
--directory(#20740)The
--directoryoption changes the directory in which uv operates. Previously, relative index and find-links paths supplied on the command line were still resolved against the original working directory.uv now resolves
--index,--default-index,--index-url,--extra-index-url, and--find-linksrelative to the directory selected by--directory. For example:$ uv add --directory project --index ./packages exampleThis now uses
project/packagesinstead of./packagesin the original working directory. Absolute paths and indexes loaded from configuration files are unaffected.To preserve the previous target, pass an absolute path or adjust the relative path, e.g.,
--index ../packages. -
Preserve absolute paths provided to
uv add(#18402)uv addpreviously converted every local dependency into a project-relative path, even when the original request used an absolute path or a literalfile://URL. It now preserves the form of the request inpyproject.tomlanduv.lock:$ uv add ../library # remains relative $ uv add /projects/library # remains absolute
Absolute paths make a project less portable. Use a relative path to avoid recording an absolute path. URLs containing expanded variables retain their existing relative-path behavior.
-
Remove older PyPy distributions that are only available as bzip2 archives (#20423)
Older PyPy patch releases that are only distributed as
.tar.bz2archives are no longer available throughuv python install. These releases require unsupported bzip2 archives.The latest PyPy release for each supported Python minor version is available as a gzip-compressed archive and remains supported. For example,
uv python list 3.10 --all-versionsstill includes the latest PyPy 3.10 release, but older bzip2-only patch releases are omitted.You cannot opt out of this behavior. Request a newer PyPy patch release instead.
-
Omit excluded-package comments when annotations are disabled (#20085)
uv pip compile --no-annotatesuppresses comments describing the generated requirements file. Previously, a footer listing packages excluded with--unsafe-packagewas still included, even though annotations were disabled. That footer is now omitted.You can recover the footer by removing
--no-annotate.
-
TOML 1.0-compatible source distributions (#20225)
uv_buildnow writes a TOML 1.0-compatiblepyproject.tomlwhen building source distributions, allowing older Python build frontends to consume projects that use newer TOML syntax. The original project file remains available in the archive aspyproject.toml.orig.This stabilizes the
toml-backwards-compatibilitypreview feature. -
Automatic open-file limit adjustment on Unix (#20225)
On Linux and macOS, uv now attempts to raise the soft open-file limit at startup toward the hard limit, capped at 1,048,576 descriptors. The new limit also applies to subprocesses and reduces failures caused by running out of file descriptors. If the limit cannot be raised, uv continues running with the existing limit.
This stabilizes the
adjust-ulimitpreview feature.
- Allow
uv upgradeto target multiple packages, upgrade all production dependencies, and exclude selected dependencies (#20338)
- Include extras activated by dependency groups when evaluating conflicts (#20237)
Released on 2026-07-31.
- Add package-specific pre-release policies with
--prerelease-package(#20837) - Support local HTML files as flat indexes (#20802)
- Add Xonsh virtual environment activation scripts (
activate.xsh) (#19740) - Preserve filesystem paths passed to
uv add --indexwhen updatingpyproject.toml(#20817)
- Add automatic fixes to
uv checkwith--fix(#20793) - Avoid rejecting unchanged metadata-free lockfiles when workspace dependencies share direct sources (#20847)
- Honor direct URL constraints when validating metadata-free lockfiles (#20796)
- Ignore malformed PEP 723 scripts discovered during project checks (#20784)
- Use ty's native script exclusion in
uv check(#20742)
- Parse canonical uv lockfiles directly, with a fallback for other valid TOML syntax (#20648)
- Accelerate SHA-256 hashing on non-Windows ARM64 platforms (#20805)
- Flush shell startup file updates before
uv tool update-shellanduv python update-shellexit (#20842) - Make workspace-root dependency groups available to commands run from workspace members (#20840)
- Resolve
--find-linkspaths in requirements files relative to the containing file (#20832) - Respect configured indexes in
uv tool list --outdated(#20770)
- Document Astral GPU indexes in the PyTorch guide (#20785)
- Use consistent dependency-group argument descriptions throughout the CLI documentation (#20823)
Released on 2026-08-05.
- Ensure diagnostic hints end with a newline to prevent malformed terminal output (#20959)
- Audit one or all installed tools with
uv tool audit(#20921) - Report physically reclaimed disk space during cache cleanup with the
cache-physical-spacepreview feature (#20925)
- Add
UV_RUN_RLIMIT_NOFILEto set the open-file limit for commands launched byuv run(#20926)
- Speed up
uv.lockparsing for wheel entries (#20881) - Speed up
uv.lockparsing for source distribution entries (#20882) - Speed up filename extraction from distribution URLs (#20879)
- Reduce filesystem metadata lookups during bytecode compilation (#20928)
- Reuse file metadata when building source distributions (#20927)
- Preserve compatibility with older uv versions when recording artifact sizes in cached wheels and source distributions (#20963)
- Avoid including workspace-root default dependency groups when syncing or exporting a selected workspace member unless explicitly requested (#20930)
- Separate build and publish jobs in the GitHub Actions publishing guide (#20946)
- Ensure the GitHub Actions publishing example waits for the build job to finish (#20957)
- Correct typos in the Docker integration guide (#20970)
Released on 2026-08-07.
- Add CPython 3.13.15 (#20997)
- Add
--output-formatto select automatic, human-readable, or raw-byte output foruv cache size(#20992) - Preserve JSON output from
uv workspace metadata --quietwhile suppressing diagnostics (#20991) - Reduce memory usage for large workspaces by streaming
uv workspace metadataJSON output (#20990)
- Reduce Linux startup latency by initializing the workspace cache before spawning another thread (#20989)
- Reuse compiled workspace exclusion patterns during workspace discovery (#20988)
- Speed up conflict-heavy resolutions by avoiding materialized range complements (#20982)
- Avoid slow procfs reads during Python interpreter discovery on Linux (#20987)
- Add PEP 740 attestations to the GitHub Actions publishing example (#20986)
- Restrict the GitHub Actions publishing example to Python version tags (#20973)
- Correct
--python-pinto--pin-pythonin theuv init --bareexample (#20876)
Released on 2026-08-13.
- Prefer post-quantum key exchange and enable opt-in TLS diagnostics (#21054)
- Accept whitespace before versions in noncompliant wildcard comparisons such as
Requires-Python: >= 3.5.*(#21012) - Report a specific error when a PEP 723 closing tag contains trailing whitespace or other content (#20944)
- Omit source-span carets from diagnostics for empty PEP 508 requirements (#21094)
- Add
uv check --no-install-projectand respectUV_NO_INSTALL_PROJECTto install dependencies without building or installing the project (#21085) - Make the ty subprocess invoked by
uv checkhonor uv's color and progress settings, including quiet mode (#21086)
- Speed up resolutions with long runs of unavailable package versions by coalescing gaps in the resolver's version ranges (#20804)
- Speed up Simple API parsing by deserializing PyPI and Pyx file metadata directly (#21041)
- Use windowed
pythonw.exelaunchers for virtual environments created from managed Python minor-version links (#19235) - Allow
uv lockto proceed when.venvis an unusable project environment (#21068) - Respect
fork-strategywhen ordering forks created fromenvironmentsor existing lockfileresolution-markers(#21000) - Preserve consecutive wildcard Python minor-version exclusions such as
!=3.11.*, !=3.12.*inuv.lock(#21045) - Preserve inline comments on the final item in dependency arrays when
uv addupdates it (#21008) - Recover from stale base-interpreter cache metadata when an existing virtual environment exposes a version mismatch (#21073)
- Prevent interpreter cache reuse across different
PYTHONEXECUTABLEand__PYVENV_LAUNCHER__overrides (#21075) - Show standard styling, usage guidance, and line termination for invalid
uv version --bumpvalues (#21076)
Released on 2026-08-14.
- Add CPython 3.10.21, 3.11.16, and 3.12.14 (#21138)
- Prefer newer versions and standard variants when selecting between equally prioritized Python interpreters (#21134)
- Simplify errors and hints for invalid editable requirements, and redact credentials in requirement URLs (#21130)
- Allow
--indexand--default-indexto select configured package indexes by name with theindex-by-namepreview feature (#17455) - Include distribution artifact URLs and hashes in CycloneDX SBOM exports by default (#21131)
- Fall back to logical file sizes when using
cache-physical-spaceon filesystems that do not support physical-space accounting (#21133)
- Resolve relative package index paths in PEP 723 scripts against the script directory (#21097)
Released on 2026-08-25.
- Update CPython to use OpenSSL 3.5.8 and libffi 3.4.8 #21295)
- Report cache-cleaning space savings from filesystem block allocation and avoid double-counting hard links (#21261)
- Limit warnings about unbounded
uv_buildrequirements to source-distribution builds (#21078) - Display byte counts below 1 KiB without a fractional part (#21237)
- Add
uv workspace metadata --sync --exactto remove packages outside the selected resolution (#21117) - Add the
artifact-hash-filteringpreview feature to makeuv pip compile --generate-hasheshonor--only-binaryand--no-binary(#21235) - Respect package-specific
exclude-newercutoffs whenuv checkselects itstyexecutable (#21227) - Preserve virtual-environment hints from
tar-codecsource-distribution errors when the base interpreter is outside abindirectory (#21146)
- Enable profile-guided optimization for Linux x86-64 release binaries (#21001)
- Enable profile-guided optimization for Windows x86-64 release binaries (#21003)
- Enable profile-guided optimization for macOS ARM64 release binaries (#21002)
- Enable profile-guided optimization for Linux ARM64 release binaries (#21004)
- Speed up syncing projects with many activated conflict items by reusing their encoded representation (#21148)
- Allow explicit
uv buildand non-editable first-party workspace packages whenno-buildis enabled (#21294) - Reuse configured index credentials during
uv tool upgradewhen the tool receipt references the same index (#21275) - Ensure full 40-character Git commit pins resolve to the requested object instead of a SHA-named branch (#21224)
- Prevent TLS segfaults in riscv64 musl release binaries (#21158)
- Preserve dependencies selected by recursive extras when markers mix production and extra conditions (#21181)
- Preserve version constraints from transitively referenced recursive extras (#21209)
- Resolve repository-relative Git archive dependencies inside the checkout during the initial
uv sync(#21264) - Return an error instead of panicking when a bearer token cannot be encoded as an HTTP header (#21282)
- Do not misclassify package URLs ending in
.pyas local script paths (#21144) - Use directory creation times consistently across libc implementations for directory
cache-keysentries (#21137) - Promote human-readable sizes to the next unit at rounding boundaries (#21136)
- Add Python 3.15 release-candidate Docker images (#21293)
- Raise the minimum supported Rust version to 1.96 and update the repository toolchain to Rust 1.98 (#21258)
Released on 2026-08-27.
- Replace managed Python installations when upgrading to a newer build of the same version (#21323)
- Support Linux
s390x,ppc64le, andloongarch64targets for cross-platform dependency resolution (#21313) - Retry downloads with configured credentials when Azure Storage denies anonymous access to an
endpoint configured via
UV_AZURE_ENDPOINT_URL(#21318)
- Use content-based directory hashes to deduplicate extracted wheels in the cache with the
content-addressed-cachepreview feature (#19693)
- Reject source archives with hash mismatches before persisting their extracted contents to the cache (#21248)
Released on 2026-08-31.
- Warn about invalid tool directories and continue upgrading valid tools with
uv tool upgrade --all(#21368)
- Deduplicate identical files within and across cached wheels with the
content-addressed-cachepreview feature (#21327) - Reduce allocations while extracting content-addressed wheels by reusing the hashing buffer across files (#21340)
- Speed up content-addressed cache cleanup on macOS by reading hard-link counts in bulk (#21344)
- Prevent concurrent uv processes from downloading and extracting the same remote wheel more than once (#21379)
- Speed up dependency graph construction from large lockfiles by indexing packages during traversal (#21373)
- Extend indexed lockfile traversal to exports, dependency trees, audits, and freshness checks (#21377)
- Speed up warm resolutions by reducing repeated marker interner work (#21300)
- Do not trust hashes from direct URLs discovered only in wheel metadata when installing with
--require-hashes(#21348) - Use a compatible Azure Storage API version for anonymous and authenticated requests, allowing credential retries when public access is disabled (#21366)
- Redact Azure shared access signature (
sig) query parameters from displayed URLs (#21360) - Treat projects below one-level workspace member globs as standalone instead of aborting workspace discovery (#21341)
- Update
astral-tokio-tarto 0.7.0 and use effective sizes when tracking extracted hard links (#21346)
Released on 2026-09-01.
- Add
--no-lockedand--no-frozento disable lock modes enabled byUV_LOCKEDandUV_FROZENfor a single invocation (#21408) - Report the exact command-line lock-mode flag in warnings and errors (#21402)
- Speed up cold wheel installs by extracting each streaming ZIP archive in a single blocking task and reusing buffers across files (#21372)
- Update
async_http_range_readerto 0.11.1 to address a potential memory-safety issue when reading metadata ranges from untrusted wheels (#21401) - Remove sensitive headers when redirects cross authentication realms, including same-host redirects that change URL schemes (#21382)
- Redact secrets in signed URLs from retry diagnostics, including nested request errors (#21381)
- Give
--locked,--frozen,--check, and--check-existsprecedence over conflictingUV_LOCKEDandUV_FROZENvalues (#21396) - Prevent concurrent uv processes from redundantly extracting the same local or source-built wheel (#21400)
Released on 2026-09-04.
- Attempt to revoke short-lived PyPI trusted-publishing tokens after
uv publishcompletes, including when publishing fails (#21423)
- Omit
exclude-newer-packagesettings for packages outside the resolution fromuv.lockwith themissing-exclude-newer-package-lockpreview feature (#21455) - Show terminal dependency cycles in
uv tree --invertoutput (#21404)
- Speed up locking large workspaces with conflicts by excluding unrelated extras and dependency groups from conflict simplification (#21399)
- Speed up
uv publishby hashing each artifact in a single blocking task and reusing the buffer across reads (#21389)
- Prevent
--lockedfrom failing whenexclude-newer-packagesettings differ only for packages outside the resolution (#21454) - Allow
uv lock --checkto reuse a lockfile when an absoluteexclude-newercutoff is moved later (#19571) - Allow
uv lock --checkto reuse a lockfile when a package-specificexclude-newercutoff is disabled (#21450) - Require an explicit
--namewhenuv initwould infer a project name reserved for a Python interpreter (#21395) - Write package-specific
exclude-newercutoffs touv.lockin a deterministic order (#21453)
Released on 2026-09-08.
- Generate missing artifact hashes when exporting
pylock.tomlfiles to ensure they conform to PEP 751 (#20146) - Warn when
pylock.tomlartifact hash tables are empty, which will be rejected in a future uv release (#21462)
- Speed up installs that overwrite existing files by eliminating per-file temporary directories for atomic hard-link, symlink, and reflink replacements (#21478)
- Speed up installs that merge copied wheels into existing environments by replacing per-file temporary directories with adjacent temporary files (#21468)
- Speed up local wheel installs by replacing the shared ZIP cursor lock with positioned reads (#21500)
- Speed up local wheel installs by reusing ZIP readers and buffers across extracted files (#21499)
- Avoid transitive dependency checks and unnecessary resolution when
uv pip install --no-depsfinds the requested packages already installed (#21523)
- Verify source archives against hashes recorded in
uv.lockbefore reading their metadata or running their build backends (#21223) - Verify supplied hashes for registry requirements pinned with
===under both--verify-hashesand--require-hashes(#21543) - Apply hashes from public-version pins to matching local versions when no exact local-version hash is provided (#21544)
- Support PowerShell virtual environment activation from UNC paths, including WSL paths (#19159)
- Trim surrounding whitespace from entries in
.python-versionand.python-versionsfiles (#21529) - Suppress
VIRTUAL_ENVmismatch warnings foruv add --no-sync,uv remove --no-sync, anduv add --frozen(#21496) - Warn and continue when
uv python listcannot query an interpreter (#21498)
- Restore TOML syntax highlighting for
exclude-newerexamples (#21534)
Released on 2026-09-09.
The executables in our macOS and Windows release archives and uv and uv_build wheels are now
code-signed. macOS executables are signed with an Apple Developer ID certificate and notarized by
Apple. Windows executables have timestamped Authenticode signatures from Azure Artifact Signing.
This enables verification of the release publisher and binary integrity, supports publisher-based
allowlisting, and should reduce security warnings and antivirus false positives.
- Exclude distributions uploaded after the
exclude-newercutoff from lockfiles and generated requirement hashes (#21539)
Released on 2026-09-10.
- Add GraalPy 3.13.0 (#21431)
- Verify hashes when downloading PEP 658 metadata sidecars (#21563)
- Respect
tyexclusions whenuv checkautomatically selects members of a virtual workspace (#21555)
- Avoid full wheel downloads during resolution by reusing supported hashes from direct URL fragments when metadata is available separately (#21279)
- Edit Windows entry-point launcher resources in memory to support Nano Server and reduce antivirus contention (#18713)
- Prefer
core-metadataover legacy aliases in JSON index responses (#21563)
Released on 2026-09-15.
- Resume interrupted downloads with HTTP Range requests when supported (#21570)
- Use a consistent format for error rendering (#17110)
- Render error and warning causes with compact
cause:labels (#21599, #21603) - Show underlying causes and hints in user warnings (#21565)
- Show resolver hints for failed
uv tool upgradeoperations (#21566)
- Export multiple dependency selections from a shared lockfile in one
uv export --batchinvocation with thebatch-exportpreview feature (#21618)
- Speed up dependency resolution from local wheelhouses by reading wheel metadata in a single blocking task (#21619)
- Speed up cold resolution against large package indexes by parsing Simple API responses in bounded background workers (#21593)
- Speed up warm-cache resolution by decoding fresh HTTP cache entries in the cache-read task (#21621)
- Select releases that satisfy
required-environmentswithin each resolver fork instead of combining incompatible wheel coverage across forks (#21672) - Install packages with paths longer than
MAX_PATHon Windows systems without long-path support enabled (#21625) - Prevent
uv python installfrom overwriting valid unmanaged Python symlinks with relative targets on Unix (#21639) - Redact credentials and signatures from missing-path-segment URL errors (#21616)
- Avoid exceeding the configured retry budget when cached HTTP responses fail revalidation (#21640)
- Prefer
bin/pythonoverbin/python3when discovering interpreters in Unix environments (#21559) - Classify package-operation exit codes by their underlying cause: return
1for expected failures and2for recognized operational and internal failures (#17110) - Suppress managed-Python fallback warnings under
--quiet(#21565) - Keep failed
uv tool upgradeerrors visible with-qwhile suppressing them with-qq(#21566)
Released on 2026-09-15.
- Speed up cold-cache resolution and HTTP cache revalidation by batching cache writes (#21675)
- Fix regressions in
0.12.14when installing to symlinked destinations or usinguv pip install --target .(#21699)
Released on 2026-09-17.
- Add Pyodide 314.0.7, 0.29.5, and 0.27.8 (#21741)
- Verify downloaded wheels and source distributions against hashes supplied by package indexes (#21562)
- Allow
build-constraint-dependenciesentries to include hashes for verifying downloaded build dependencies (#21467) - Honor Darwin
platform_releasemarkers inrequired-environmentsusing macOS wheel deployment targets (#21766) - Reject unsupported Git URL schemes while parsing lockfiles instead of panicking during frozen exports (#21779)
- Support
lock-without-metadataacross all dependency types while retainingpackage.metadatafor remote URL dependencies to enable offline validation (#21163) - Honor configured and command-line index settings, including credentials, in
uv upgrade(#21776) - Allow
uv checkto run in projects that are not managed by uv and outside workspaces (#21777) - Respect
--pythonandUV_PYTHONwhen selecting the Python version foruv check(#21744)
- Redact Azure shared access signatures from displayed and logged URLs (#21755)
- Check archive sizes from
pylock.tomlbefore reusing cached distributions (#21609) - Keep user-authored local dependency paths relative in lockfiles when backend metadata reports absolute paths (#20631)
- Use the bundled
uv_buildbackend only when its version matches active version pins (#21742) - Handle malformed index URLs without panicking when credentials are configured (#21784)
- Report a configuration error instead of panicking for proxy URLs without a host (#21781)
- Return a credential-redacted error instead of panicking when a URL cannot be converted to a path (#21783)
Released on 2026-09-18.
- Reject unsupported Git archive paths in lockfiles with a clear error instead of panicking during frozen exports (#21780)
- Set minimum glibc and musl versions that universal resolutions must support with
minimum-libc-version(#21651) - Reject
pylock.tomlfiles whose wheel filenames do not match their declared package names or versions (#20746) - Keep
uv workspace metadataread-only unless--syncis provided (#21821) - Apply
uv checklock modes when retrieving workspace metadata (#21821)
- Speed up builds with many exclusion patterns by avoiding quadratic deduplication (#21650)
- Reduce resolver allocations when deduplicating package and distribution requests (#21810)
- Prevent
required-environmentsfrom selecting package versions whose wheels require a newer macOS version than the configured Darwin baseline (#21825)
- Clarify the 0.12.14 and 0.12.15 release notes (#21817)
Released on 2026-09-22.
This release addresses GHSA-2cv4-cqwr-gwf7, which is a path traversal weakness during wheel installation on Windows. No other platforms are affected by this advisory.
- Add
--output-format jsontouv pip installanduv pip sync, including for--dry-runand--check(#21893) - Add
--checktouv pip installanduv pip syncto report planned changes without modifying the environment (#21844) - Identify failures from
get_requires_for_build_*hooks correctly in build errors (#21881)
- Validate build requirements for
uv build --no-build-isolationwith--preview-features build-dependency-check; use--skip-dependency-checkto opt out (#21880)
- Speed up
uv_buildeditable wheel creation by omitting compression from temporary wheels (#21918)
- Select package versions with wheels compatible with each Python resolution fork, correctly interpreting generic and stable-ABI wheel tags (#21835, #21836)
- Restore project, script, and lock files when
uv add,uv remove, oruv versionfails or is interrupted (#21860, #21856) - Use configured
dependency-metadatawhen checking whether installed requirements are satisfied (#21843) - Reject archive entries that normalize to absolute Windows paths (#21923)
- Recognize distribution filenames and archive extensions when URL fragments contain
?(#21920) - Generate correctly lowercased platform tags for BSD and Haiku releases (#21853)
- Avoid rebuilding a Windows relative path into an absolute form (#21923)
Released on 2026-09-24.
- Format upload URLs with backticks in
uv publisherrors (#21934)
- Run build-backend hooks with lazy imports on CPython 3.15 and later using the
build-lazy-importspreview feature (#21967) - Omit unused resolution settings from
uv.lockand ignore changes to them when checking lockfile freshness with theresolution-inputspreview feature (#21913)
- Preserve signed and encoded query parameters in direct-URL metadata to avoid reinstalling unchanged packages (#21971)
- Recognize
1.0.0as satisfying===1during installed-package checks, matching resolution (#21931) - Avoid collisions between Git checkout readiness markers and
.okfiles in dependencies (#21891) - Preserve always-false
python_versionmarkers when parsing their serialized form (#21939)
- Restore the public
FlatDistributionsexport and itsBTreeMapconversion for downstream resolvers (#21965)
- Make individual preview-feature reference entries linkable by name (#21950)
Released on 2026-09-28.
- Reuse lockfiles when dependency declarations are semantically equivalent (#21951)
- Preserve second-line encoding declarations when installing wheel scripts with CRLF shebangs (#21990)
- Write normalized requirement declarations with the
lockfile-normalizationpreview feature (#21951) - Honor synthetic default groups when installing or syncing from
pylock.toml(#22003) - Resolve local paths in exported
pylock.tomlfiles relative to the output file (#22042) - Install each package only once when repeated
tool-install-locksrequirements resolve to the same package (#22000) - Reuse
lock-without-metadatalockfiles for conflicting groups with distinct base and extra requirement specifiers (#22055) - Use consistent root-package paths in
uv workspace metadataanduv tree --format jsonoutput (#22050)
- Continue searching
XDG_CONFIG_DIRSafter empty entries (#21987)
- Restore the previous HTTP cache-write scheduling while investigating severe cache-revalidation stalls on ext4 filesystems (#22051)
- Apply hash constraints to every repeated requirement under
--require-hashesand--verify-hashes(#21996) - Allow metadata builds for first-party workspace projects under
--no-build(#21988) - Honor project exclusion flags with
--all-packages, including--no-install-projectand--no-emit-project(#21994) - Restore
pyproject.tomlifuv upgradefails or is interrupted (#21983) - Generate working Nushell activation scripts for relocatable virtual environments (#21979)
- Prevent commands from running and changing state after displaying
--show-settings(#21989) - Treat UTF-16 requirements files containing only a byte-order mark as empty (#21991)
- Ignore unrecognized managed-Python implementation directories during
uv python listanduv python upgradeinstead of panicking (#22033) - Avoid panics and incorrect rewriting when managed Python sysconfig paths merely start with
/install(#22036) - Report whitespace-only non-ASCII requirements as invalid instead of panicking (#22035)
- Avoid a resolver panic when trace logging an always-false constraint (#22034)
Released on 2026-09-29.
- Update CPython to use OpenSSL 3.5.9 (#22076)
- Omit empty
[manifest]tables from lockfiles that contain only manifest subtables (#22070)
- Omit redundant runtime constraints from
uv.lock, including those involving pre-releases, with theresolution-inputspreview feature (#22004, #22068)
- Prevent
uv python pin --rmfrom removing a global.python-versionsfile without--global(#21992) - Fix installed-package checks incorrectly reporting post-releases as incompatible with exclusive lower bounds on pre-releases (#22049)
Released on 2026-10-01.
- Add CPython 3.10.22, 3.11.17, 3.12.15, 3.13.16, and 3.14.8 (#22147)
- Accept uppercase release suffixes in wheel platform tags (#22113)
- Record workspace-member default groups in lockfiles (#22010, #22103)
- Record workspace-member dependency-group Python requirements in lockfiles (#22044, #22103)
- Record default groups for non-project workspace roots in lockfiles (#22104)
- Record dependency-group Python requirements for non-project workspace roots in lockfiles (#22104)
- Format URLs and paths consistently in CLI messages (#21937)
- Hide the unsupported
--offlineoption fromuv publishhelp (#22124)
- Honor
--no-default-groupsinuv audit(#22090) - Report a clear error when
uv auditoruv tool auditruns offline and hide the unsupported option from help (#22114)
- Add
UV_PYTHON_ARCHto select an interpreter architecture independently of its Python version (#22098)
- Reduce uv's binary size by compressing embedded Python download metadata (#22126)
- Verify unchanged requirements against existing lockfile hashes when relocking (#22083)
- Honor dependency-group Python requirements at non-project workspace roots (#22101)
- Use each selected workspace member's recorded default groups during frozen sync (#22015)
- Avoid false entry-point warnings for required workspace members (#22112)
- Raise the minimum supported Rust version for building uv to 1.97 and update the toolchain to Rust 1.99 (#22121)
Released on 2026-10-03.
- Add CPython 3.15.0rc3 (#22164)
- Sync from
uv.lockwithout a workspace manifest usinguv sync --frozenwithfrozen-lockfile(#22018) - Export from
uv.lockwithout a workspace manifest usinguv export --frozenwithfrozen-lockfile(#22007) - Inspect dependency trees from
uv.lockwithout a workspace manifest usinguv tree --frozenwithfrozen-lockfile(#22016) - Inspect workspace metadata and optionally sync its environment from
uv.lockwithout a workspace manifest usinguv workspace metadata --frozenwithfrozen-lockfile(#22017, #22018)
- Reject alternate sources for workspace members across conflicting dependency selections, avoiding lockfiles that cannot be installed (#22153)
- Allow x86-64 Python interpreters running under emulation on Windows ARM64 to install compatible
win_amd64wheels instead of building from source (#22099)
Released on 2026-10-08.
- Remove orphaned temporary build environments with
uv cache prune(#22171) - Accept PEP 508 marker operators directly before grouped expressions (#22309)
- Reject malformed requirements-file options instead of partially parsing or ignoring them (#22317)
- Show underlying filesystem and registry errors when managed Python uninstallation fails (#22362)
- Identify the invalid source URL in Python mirror errors (#22364)
- Display preferred advisory IDs in
uv auditreports, prioritizing PYSEC, GHSA, then CVE identifiers (#22292)
- Support custom installation mirrors for GraalPy (#22269)
- Support custom installation mirrors for Pyodide (#22271)
- Allow
UV_NO_CACHE=falseto overrideno-cache = truein configuration (#22324) - Report more precise error locations for invalid trusted-host ports and preview-feature list entries (#22144)
- Speed up later commands after creating an environment by warming its interpreter cache (#21304)
- Reduce code-signature verification work for ARM64 macOS releases with 16 KiB signature pages (#22246)
- Enforce resource limits when parsing package indexes and
--find-linkspages withastral-html(#22203) - Reduce standalone
uv-buildexecutable size by 7.5% by omitting unused Zstandard support (#22242) - Reduce uv's binary size by about 232 KB by simplifying configuration deserialization (#22144)
- Reduce Python download error formatting code size by sharing its formatter (#22141)
- Verify supplied hashes even when hash presence is disabled with
--no-require-hashesorrequire-hashes = false(#22369) - Honor exact managed Python patch pins when creating script environments instead of following patch upgrades (#22360)
- Prevent dependency overrides and constraints from activating optional dependencies when their extras are not selected (#22237)
- Exclude optional dependencies from exports when their extras are activated only in incompatible environments (#22234)
- Give explicit
uv publish --trusted-publishingvalues precedence over configuration (#22279) - Allow
UV_OFFLINE=falseto overrideoffline = truein configuration (#22283) - Allow
UV_SYSTEM_CERTS=falseto overridesystem-certs = truein configuration (#22291) - Allow
uv auth loginover IPv6 loopback addresses (#22306) - Resolve GitHub dependencies whose Git references contain
#or%characters (#22281) - Recognize existing Pyodide interpreters as satisfying Pyodide Python requests (#22322)
- Preserve JSON output from
uv versionanduv self versionwith a single--quietflag (#22280) - Preserve trailing spaces and tabs in passwords returned by subprocess keyrings (#22284)
- Restore wheel incompatibility hints when
WHEELmetadata contains multiple expandedTag:rows (#22235) - Preserve Windows wheel-script rename errors unless a cross-drive copy fallback applies (#22302)
- Prevent workspace-cache assertion failures after modifying a project at the workspace root (#22236)
- Hide the ignored
--keyring-provideroption fromuv authhelp (#19520) - Report HTTP client setup failures directly when resolving unnamed
uv toolrequirements (#22320)