uv/crates/uv-pep440
Zanie Blue 6856a27711
Add `extra-build-dependencies` (#14735)
Replaces https://github.com/astral-sh/uv/pull/14092

Adds `tool.uv.extra-build-dependencies = {package = [dependency, ...]}`
which extends `build-system.requires` during package builds.

These are lowered via workspace sources, are applied to transitive
dependencies, and are included in the wheel cache shard hash.

There are some features we need to follow-up on, but are out of scope
here:

- Preferring locked versions for build dependencies
- Settings for requiring locked versions for build depencies

There are some quality of life follow-ups we should also do:

- Warn on `extra-build-dependencies` that do not apply to any packages
- Add test cases and improve error messaging when the
`extra-build-dependencies` resolve fails


-------

There ~are~ were a few open decisions to be made here

1. Should we resolve these dependencies alongside the
`build-system.requires` dependencies? Or should we resolve separately?
(I think the latter is more powerful? because you can override things?
but it opens the door to breaking your build)
2. Should we install these dependencies into the same environment? Or
should we layer it on top as we do elsewhere? (I think it's fine to
install into the same environment)
3. Should we respect sources defined in the parent project? (I think
yes, but then we need to lower the dependencies earlier — I don't think
that's a big deal, but it's not implemented)
4. Should we respect sources defined in the child project? (I think no,
this gets really complicated and seems weird to allow)
5. Should we apply this to transitive dependencies? (I think so)

---------

Co-authored-by: Aria Desires <aria.desires@gmail.com>
Co-authored-by: konstin <konstin@mailbox.org>
2025-07-30 09:53:07 -05:00
..
src Add `extra-build-dependencies` (#14735) 2025-07-30 09:53:07 -05:00
CHANGELOG.md Add `uv-` prefix to all internal crates (#7853) 2024-10-01 20:15:32 -04:00
Cargo.toml Add `extra-build-dependencies` (#14735) 2025-07-30 09:53:07 -05:00
License-Apache Add `uv-` prefix to all internal crates (#7853) 2024-10-01 20:15:32 -04:00
License-BSD Add `uv-` prefix to all internal crates (#7853) 2024-10-01 20:15:32 -04:00
Readme.md Fix typo in uv-pep440/README.md (#14965) 2025-07-30 12:25:48 +02:00

Readme.md

PEP440 in rust

Crates.io PyPI

A library for python version numbers and specifiers, implementing PEP 440. See Reimplementing PEP 440 for some background.

Higher level bindings to the requirements syntax are available in pep508_rs.

use std::str::FromStr;
use pep440_rs::{parse_version_specifiers, Version, VersionSpecifier};

let version = Version::from_str("1.19").unwrap();
let version_specifier = VersionSpecifier::from_str("==1.*").unwrap();
assert!(version_specifier.contains(&version));
let version_specifiers = parse_version_specifiers(">=1.16, <2.0").unwrap();
assert!(version_specifiers.contains(&version));

PEP 440 has a lot of unintuitive features, including:

  • An epoch that you can prefix the version with, e.g., 1!1.2.3. Lower epoch always means lower version (1.0 <=2!0.1)
  • Post versions, which can be attached to both stable releases and pre-releases
  • Dev versions, which can be attached to both stable releases and pre-releases. When attached to a pre-release the dev version is ordered just below the normal pre-release, however when attached to a stable version, the dev version is sorted before a pre-releases
  • Pre-release handling is a mess: "Pre-releases of any kind, including developmental releases, are implicitly excluded from all version specifiers, unless they are already present on the system, explicitly requested by the user, or if the only available version that satisfies the version specifier is a pre-release.". This means that we can't say whether a specifier matches without also looking at the environment
  • Pre-release vs. pre-release incl. dev is fuzzy
  • Local versions on top of all the others, which are added with a + and have implicitly typed string and number segments
  • No semver-caret (^), but a pseudo-semver tilde (~=)
  • Ordering contradicts matching: We have, e.g., 1.0+local > 1.0 when sorting, but ==1.0 matches 1.0+local. While the ordering of versions itself is a total order the version matching needs to catch all sorts of special cases