Since the launch of Python version, project, and tool management capabilities back in August, we've seen extraordinary adoption of uv. We've been iterating rapidly: adding new features, fixing bugs, and improving the user experience. Despite moving quickly, stability and compatibility have been a major focus — we've made thirty releases since our last breaking change. Consequently, we've accumulated various changes that improve correctness and user experience, 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.
Breaking
- **Use base executable to set virtualenv Python path** ([8481](https://github.com/astral-sh/uv/pull/8481))
Previously, uv canonicalized the path to the Python executable when setting the Python path in created virtual environments. This behavior had several undesirable effects: it would bypass stabilized version directories (as constructed by Homebrew) and it was not consistent with the Python standard library's behavior. Now, uv uses the `sys._base_executable` path.
- **Use XDG (i.e. `~/.local/bin`) instead of the Cargo home directory in the installer** ([8420](https://github.com/astral-sh/uv/pull/8420))
Previously, uv's installer used `$CARGO_HOME` or `~/.cargo/bin` for its target install directory. It's been a longstanding complaint that uv uses this directory, as there's no relationship to Cargo. Now, uv will be installed into `$XDG_BIN_HOME`, `$XDG_DATA_HOME/../bin`, or `~/.local/bin` (in that order). Note that `$UV_INSTALL_DIR` can always be used to override the target directory.
- **Discover and respect `.python-version` files in parent directories** ([6370](https://github.com/astral-sh/uv/pull/6370))
Previously, uv only read `.python-version` files from the working directory. Now, uv will check parent directories for `.python-version` files; however uv will not search for `.python-version` files beyond project boundaries. The new behavior is better aligned with that of `pyenv` and Rye.
- **Error when disallowed settings are defined in `uv.toml`** ([8550](https://github.com/astral-sh/uv/pull/8550))
Some settings can only be defined in the `pyproject.toml`. Previously, uv would ignore these settings when present in the `uv.toml`. Now, uv will error to avoid confusion about why the settings are not respected.
- **Implement PEP 440-compliant local version semantics** ([8797](https://github.com/astral-sh/uv/pull/8797))
Previously, uv's implementation of local versions (e.g. `2.0+cpu`) was not compliant with the specification due to the technical complexity of implementing the local version semantics in the PubGrub algorithm. Thanks to the work of ericmarkmartin, uv now has a spec-compliant implementation. Namely, uv will now allow a request for `torch==2.1.0` to install `torch2.1.0+cpu` regardless of whether `torch2.1.0` (without a local tag) actually exists.
- **Treat the base Conda environment as a system environment** ([7691](https://github.com/astral-sh/uv/pull/7691))
Previously, uv would not distinguish between the base and other Conda environments. Now, uv uses `CONDA_DEFAULT_ENV` and the names `base` and `default` to determine if an environment active via `CONDA_PREFIX` is the base environment. If the base environment is active, the `--system` flag must be used to mutate it.
- **Do not allow pre-releases when the `!=` operator is used** ([7974](https://github.com/astral-sh/uv/pull/7974))
Previously, uv would use the presence of a pre-release specifier in a version specifier as an opt-in to allow pre-release versions during resolution. The new behavior does not allow pre-releases when an inequals operator is used, e.g., `!= 2.0a1`.
- **Prefer `USERPROFILE` over `FOLDERID_Profile` when selecting a home directory on Windows** ([8048](https://github.com/astral-sh/uv/pull/8048))
This change is a side-effect of switching from the `directories` crate to `etcetera` for determining canonical system paths. If `USERPROFILE` is not set, the behavior will be unchanged.
- **Improve interactions between color environment variables and CLI options** ([8215](https://github.com/astral-sh/uv/pull/8215))
Previously, uv would respect the `FORCE_COLOR` and `NO_COLOR` environment variables over the `--color` flag. Now, when the `--color` flag is explicitly provided, uv will respect it over the environment variables.
- **Make `allow-insecure-host` a global option** ([8476](https://github.com/astral-sh/uv/pull/8476))
Previously, this option was only available in some parts of uv. Now, `--allow-insecure-host` can be provided to any command. For consistency, the `allow-insecure-host` setting has been removed from the `[tool.uv.pip]` configuration in favor of `[tool.uv]`.
- **Only write `.python-version` files during `uv init` for workspace members if the version differs** ([8897](https://github.com/astral-sh/uv/pull/8897))
Previously, uv would create a `.python-version` file for workspace members during `uv init`. Now, uv will only do so if the version differs from the `.python-version` file in the workspace root since uv will respect `.python-version` files in parent directories.
Enhancements
- Add `uv tree --outdated` ([8893](https://github.com/astral-sh/uv/pull/8893))
- Add armv8l alias for armv7l to support arm 32-bit compatibility mode ([8881](https://github.com/astral-sh/uv/pull/8881))
- Add support for `pip list --outdated` ([8872](https://github.com/astral-sh/uv/pull/8872))
- Allow semicolons directly after direct URLs ([8836](https://github.com/astral-sh/uv/pull/8836))
- Enable support for arbitrary git transports ([8769](https://github.com/astral-sh/uv/pull/8769))
- Improve Python discovery source messages ([8890](https://github.com/astral-sh/uv/pull/8890))
- Show dedicated error for trailing `;` on URL and path requirements ([8835](https://github.com/astral-sh/uv/pull/8835))
- Add progress bar for `uv cache clean` ([8857](https://github.com/astral-sh/uv/pull/8857))
- Warn on failure to query system configuration file ([8829](https://github.com/astral-sh/uv/pull/8829))
Preview features
- Add support for building basic source distributions with the experimental uv build backend ([8886](https://github.com/astral-sh/uv/pull/8886))
Bug fixes
- Respect dynamic version updates in `uv lock` ([8867](https://github.com/astral-sh/uv/pull/8867))
- Respect fork markers in `--resolution-mode=lowest-direct` ([8839](https://github.com/astral-sh/uv/pull/8839))
Documentation
- Add further examples of git+https support ([8841](https://github.com/astral-sh/uv/pull/8841))
- Add installer variables to environment reference ([8874](https://github.com/astral-sh/uv/pull/8874))
- Add note on private classifier ([8783](https://github.com/astral-sh/uv/pull/8783))
- Update pip-and-uv strictness example ([8822](https://github.com/astral-sh/uv/pull/8822))
- Fix `uv python install` docs to use an existing PyPy version ([8845](https://github.com/astral-sh/uv/pull/8845))
- Document how to mimic `--verbose` with `RUST_LOG` ([8858](https://github.com/astral-sh/uv/pull/8858))