Use "pre-release" in prose and `Prerelease` in code (#5697)

## Summary

Closes https://github.com/astral-sh/uv/issues/5630.
This commit is contained in:
Charlie Marsh 2024-08-01 16:56:29 -04:00 committed by GitHub
parent 6797caccdb
commit 499c368f1e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 278 additions and 277 deletions

View File

@ -98,7 +98,7 @@
- Match wheel tags against `Requires-Python` major-minor ([#5289](https://github.com/astral-sh/uv/pull/5289)) - Match wheel tags against `Requires-Python` major-minor ([#5289](https://github.com/astral-sh/uv/pull/5289))
- Remove Simple API cache files for alternative indexes in `cache clean` ([#5353](https://github.com/astral-sh/uv/pull/5353)) - Remove Simple API cache files for alternative indexes in `cache clean` ([#5353](https://github.com/astral-sh/uv/pull/5353))
- Remove extraneous `are` from wheel tag error messages ([#5303](https://github.com/astral-sh/uv/pull/5303)) - Remove extraneous `are` from wheel tag error messages ([#5303](https://github.com/astral-sh/uv/pull/5303))
- Allow conflicting prerelease strategies when forking ([#5150](https://github.com/astral-sh/uv/pull/5150)) - Allow conflicting pre-release strategies when forking ([#5150](https://github.com/astral-sh/uv/pull/5150))
- Use tag error rather than requires-python error for ABI filtering ([#5296](https://github.com/astral-sh/uv/pull/5296)) - Use tag error rather than requires-python error for ABI filtering ([#5296](https://github.com/astral-sh/uv/pull/5296))
## 0.2.27 ## 0.2.27
@ -1107,7 +1107,7 @@ See [#2976](https://github.com/astral-sh/uv/pull/2976#discussion_r1566521453) fo
- Accept `setup.py` and `setup.cfg` files in compile ([#2634](https://github.com/astral-sh/uv/pull/2634)) - Accept `setup.py` and `setup.cfg` files in compile ([#2634](https://github.com/astral-sh/uv/pull/2634))
- Add `--no-binary` and `--only-binary` support to `requirements.txt` ([#2680](https://github.com/astral-sh/uv/pull/2680)) - Add `--no-binary` and `--only-binary` support to `requirements.txt` ([#2680](https://github.com/astral-sh/uv/pull/2680))
- Allow prereleases, locals, and URLs in non-editable path requirements ([#2671](https://github.com/astral-sh/uv/pull/2671)) - Allow pre-releases, locals, and URLs in non-editable path requirements ([#2671](https://github.com/astral-sh/uv/pull/2671))
- Use PEP 517 to extract dynamic `pyproject.toml` metadata ([#2633](https://github.com/astral-sh/uv/pull/2633)) - Use PEP 517 to extract dynamic `pyproject.toml` metadata ([#2633](https://github.com/astral-sh/uv/pull/2633))
- Add `Editable project location` and `Required-by` to `pip show` ([#2589](https://github.com/astral-sh/uv/pull/2589)) - Add `Editable project location` and `Required-by` to `pip show` ([#2589](https://github.com/astral-sh/uv/pull/2589))
- Avoid `prepare_metadata_for_build_wheel` calls for Hatch packages with dynamic dependencies ([#2645](https://github.com/astral-sh/uv/pull/2645)) - Avoid `prepare_metadata_for_build_wheel` calls for Hatch packages with dynamic dependencies ([#2645](https://github.com/astral-sh/uv/pull/2645))
@ -1457,7 +1457,7 @@ pass the `--native-tls` command-line flag to enable this behavior.
- Expand scope of archive timestamping ([#1960](https://github.com/astral-sh/uv/pull/1960)) - Expand scope of archive timestamping ([#1960](https://github.com/astral-sh/uv/pull/1960))
- Gracefully handle virtual environments with conflicting packages ([#1893](https://github.com/astral-sh/uv/pull/1893)) - Gracefully handle virtual environments with conflicting packages ([#1893](https://github.com/astral-sh/uv/pull/1893))
- Invalidate dependencies when editables are updated ([#1955](https://github.com/astral-sh/uv/pull/1955)) - Invalidate dependencies when editables are updated ([#1955](https://github.com/astral-sh/uv/pull/1955))
- Make < exclusive for non-prerelease markers ([#1878](https://github.com/astral-sh/uv/pull/1878)) - Make < exclusive for non-pre-release markers ([#1878](https://github.com/astral-sh/uv/pull/1878))
- Properly apply constraints in venv audit ([#1956](https://github.com/astral-sh/uv/pull/1956)) - Properly apply constraints in venv audit ([#1956](https://github.com/astral-sh/uv/pull/1956))
- Re-sync editables on-change ([#1959](https://github.com/astral-sh/uv/pull/1959)) - Re-sync editables on-change ([#1959](https://github.com/astral-sh/uv/pull/1959))
- Remove current directory from PATH in PEP 517 hooks ([#1975](https://github.com/astral-sh/uv/pull/1975)) - Remove current directory from PATH in PEP 517 hooks ([#1975](https://github.com/astral-sh/uv/pull/1975))

View File

@ -30,6 +30,7 @@ Just uv, please.
## Terminology ## Terminology
1. Use "lockfile" not "lock file". 1. Use "lockfile" not "lock file".
2. Use "pre-release", not "prerelease" (except in code, in which case: use `Prerelease`, not `PreRelease`; and `prerelease`, not `pre_release`).
## Documentation ## Documentation

View File

@ -38,16 +38,16 @@ PEP 440 has a lot of unintuitive features, including:
* An epoch that you can prefix the version which, e.g. `1!1.2.3`. Lower epoch always means lower * An epoch that you can prefix the version which, e.g. `1!1.2.3`. Lower epoch always means lower
version (`1.0 <=2!0.1`) version (`1.0 <=2!0.1`)
* post versions, which can be attached to both stable releases and prereleases * post versions, which can be attached to both stable releases and pre-releases
* dev versions, which can be attached to sbpth table releases and prereleases. When attached to a * dev versions, which can be attached to sbpth table releases and pre-releases. When attached to a
prerelease the dev version is ordered just below the normal prerelease, however when attached 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 prereleases to a stable version, the dev version is sorted before a pre-releases
* prerelease handling is a mess: "Pre-releases of any kind, including developmental 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 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 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 the version specifier is a pre-release.". This means that we can't say whether a specifier
matches without also looking at the environment matches without also looking at the environment
* prelease vs. prerelease incl. dev is fuzzy * 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 * local versions on top of all the others, which are added with a + and have implicitly typed
string and number segments string and number segments
* no semver-caret (`^`), but a pseudo-semver tilde (`~=`) * no semver-caret (`^`), but a pseudo-semver tilde (`~=`)

View File

@ -24,16 +24,16 @@ PEP 440 has a lot of unintuitive features, including:
* An epoch that you can prefix the version which, e.g. `1!1.2.3`. Lower epoch always means lower * An epoch that you can prefix the version which, e.g. `1!1.2.3`. Lower epoch always means lower
version (`1.0 <=2!0.1`) version (`1.0 <=2!0.1`)
* post versions, which can be attached to both stable releases and prereleases * post versions, which can be attached to both stable releases and pre-releases
* dev versions, which can be attached to sbpth table releases and prereleases. When attached to a * dev versions, which can be attached to both table releases and pre-releases. When attached to a
prerelease the dev version is ordered just below the normal prerelease, however when attached 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 prereleases to a stable version, the dev version is sorted before a pre-releases
* prerelease handling is a mess: "Pre-releases of any kind, including developmental 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 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 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 the version specifier is a pre-release.". This means that we can't say whether a specifier
matches without also looking at the environment matches without also looking at the environment
* prelease vs. prerelease incl. dev is fuzzy * 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 * local versions on top of all the others, which are added with a + and have implicitly typed
string and number segments string and number segments
* no semver-caret (`^`), but a pseudo-semver tilde (`~=`) * no semver-caret (`^`), but a pseudo-semver tilde (`~=`)

View File

@ -16,16 +16,16 @@
//! //!
//! * An epoch that you can prefix the version which, e.g. `1!1.2.3`. Lower epoch always means lower //! * An epoch that you can prefix the version which, e.g. `1!1.2.3`. Lower epoch always means lower
//! version (`1.0 <=2!0.1`) //! version (`1.0 <=2!0.1`)
//! * post versions, which can be attached to both stable releases and prereleases //! * post versions, which can be attached to both stable releases and pre-releases
//! * dev versions, which can be attached to sbpth table releases and prereleases. When attached to a //! * dev versions, which can be attached to both table releases and pre-releases. When attached to a
//! prerelease the dev version is ordered just below the normal prerelease, however when attached //! 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 prereleases //! to a stable version, the dev version is sorted before a pre-releases
//! * prerelease handling is a mess: "Pre-releases of any kind, including developmental 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 //! 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 //! 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 //! the version specifier is a pre-release.". This means that we can't say whether a specifier
//! matches without also looking at the environment //! matches without also looking at the environment
//! * prelease vs. prerelease incl. dev is fuzzy //! * 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 //! * local versions on top of all the others, which are added with a + and have implicitly typed
//! string and number segments //! string and number segments
//! * no semver-caret (`^`), but a pseudo-semver tilde (`~=`) //! * no semver-caret (`^`), but a pseudo-semver tilde (`~=`)
@ -38,7 +38,7 @@
pub use version::PyVersion; pub use version::PyVersion;
pub use { pub use {
version::{ version::{
LocalSegment, Operator, OperatorParseError, PreRelease, PreReleaseKind, Version, LocalSegment, Operator, OperatorParseError, Prerelease, PrereleaseKind, Version,
VersionParseError, VersionPattern, VersionPatternParseError, MIN_VERSION, VersionParseError, VersionPattern, VersionPatternParseError, MIN_VERSION,
}, },
version_specifier::{ version_specifier::{

View File

@ -371,7 +371,7 @@ impl Version {
/// Returns the pre-release part of this version, if it exists. /// Returns the pre-release part of this version, if it exists.
#[inline] #[inline]
pub fn pre(&self) -> Option<PreRelease> { pub fn pre(&self) -> Option<Prerelease> {
match *self.inner { match *self.inner {
VersionInner::Small { ref small } => small.pre(), VersionInner::Small { ref small } => small.pre(),
VersionInner::Full { ref full } => full.pre, VersionInner::Full { ref full } => full.pre,
@ -501,7 +501,7 @@ impl Version {
/// Set the pre-release component and return the updated version. /// Set the pre-release component and return the updated version.
#[inline] #[inline]
#[must_use] #[must_use]
pub fn with_pre(mut self, value: Option<PreRelease>) -> Self { pub fn with_pre(mut self, value: Option<Prerelease>) -> Self {
if let VersionInner::Small { ref mut small } = Arc::make_mut(&mut self.inner) { if let VersionInner::Small { ref mut small } = Arc::make_mut(&mut self.inner) {
if small.set_pre(value) { if small.set_pre(value) {
return self; return self;
@ -709,7 +709,7 @@ impl std::fmt::Display for Version {
let pre = self let pre = self
.pre() .pre()
.as_ref() .as_ref()
.map(|PreRelease { kind, number }| format!("{kind}{number}")) .map(|Prerelease { kind, number }| format!("{kind}{number}"))
.unwrap_or_default(); .unwrap_or_default();
let post = self let post = self
.post() .post()
@ -1014,21 +1014,21 @@ impl VersionSmall {
} }
#[inline] #[inline]
fn pre(&self) -> Option<PreRelease> { fn pre(&self) -> Option<Prerelease> {
let (kind, number) = (self.suffix_kind(), self.suffix_version()); let (kind, number) = (self.suffix_kind(), self.suffix_version());
if kind == Self::SUFFIX_PRE_ALPHA { if kind == Self::SUFFIX_PRE_ALPHA {
Some(PreRelease { Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number, number,
}) })
} else if kind == Self::SUFFIX_PRE_BETA { } else if kind == Self::SUFFIX_PRE_BETA {
Some(PreRelease { Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number, number,
}) })
} else if kind == Self::SUFFIX_PRE_RC { } else if kind == Self::SUFFIX_PRE_RC {
Some(PreRelease { Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number, number,
}) })
} else { } else {
@ -1037,7 +1037,7 @@ impl VersionSmall {
} }
#[inline] #[inline]
fn set_pre(&mut self, value: Option<PreRelease>) -> bool { fn set_pre(&mut self, value: Option<Prerelease>) -> bool {
if self.min().is_some() if self.min().is_some()
|| self.dev().is_some() || self.dev().is_some()
|| self.post().is_some() || self.post().is_some()
@ -1049,18 +1049,18 @@ impl VersionSmall {
None => { None => {
self.set_suffix_kind(Self::SUFFIX_NONE); self.set_suffix_kind(Self::SUFFIX_NONE);
} }
Some(PreRelease { kind, number }) => { Some(Prerelease { kind, number }) => {
if number > Self::SUFFIX_MAX_VERSION { if number > Self::SUFFIX_MAX_VERSION {
return false; return false;
} }
match kind { match kind {
PreReleaseKind::Alpha => { PrereleaseKind::Alpha => {
self.set_suffix_kind(Self::SUFFIX_PRE_ALPHA); self.set_suffix_kind(Self::SUFFIX_PRE_ALPHA);
} }
PreReleaseKind::Beta => { PrereleaseKind::Beta => {
self.set_suffix_kind(Self::SUFFIX_PRE_BETA); self.set_suffix_kind(Self::SUFFIX_PRE_BETA);
} }
PreReleaseKind::Rc => { PrereleaseKind::Rc => {
self.set_suffix_kind(Self::SUFFIX_PRE_RC); self.set_suffix_kind(Self::SUFFIX_PRE_RC);
} }
} }
@ -1234,8 +1234,8 @@ struct VersionFull {
/// i.e. alpha, beta or rc plus a number /// i.e. alpha, beta or rc plus a number
/// ///
/// Note that whether this is Some influences the version range /// Note that whether this is Some influences the version range
/// matching since normally we exclude all prerelease versions /// matching since normally we exclude all pre-release versions
pre: Option<PreRelease>, pre: Option<Prerelease>,
/// The [Post release /// The [Post release
/// version](https://peps.python.org/pep-0440/#post-releases), higher /// version](https://peps.python.org/pep-0440/#post-releases), higher
/// post version are preferred over lower post or none-post versions /// post version are preferred over lower post or none-post versions
@ -1353,14 +1353,14 @@ impl FromStr for VersionPattern {
#[archive(check_bytes)] #[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))] #[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[cfg_attr(feature = "pyo3", pyclass)] #[cfg_attr(feature = "pyo3", pyclass)]
pub struct PreRelease { pub struct Prerelease {
/// The kind of pre-release. /// The kind of pre-release.
pub kind: PreReleaseKind, pub kind: PrereleaseKind,
/// The number associated with the pre-release. /// The number associated with the pre-release.
pub number: u64, pub number: u64,
} }
/// Optional prerelease modifier (alpha, beta or release candidate) appended to version /// Optional pre-release modifier (alpha, beta or release candidate) appended to version
/// ///
/// <https://peps.python.org/pep-0440/#pre-releases> /// <https://peps.python.org/pep-0440/#pre-releases>
#[derive( #[derive(
@ -1379,16 +1379,16 @@ pub struct PreRelease {
#[archive(check_bytes)] #[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))] #[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[cfg_attr(feature = "pyo3", pyclass)] #[cfg_attr(feature = "pyo3", pyclass)]
pub enum PreReleaseKind { pub enum PrereleaseKind {
/// alpha prerelease /// alpha pre-release
Alpha, Alpha,
/// beta prerelease /// beta pre-release
Beta, Beta,
/// release candidate prerelease /// release candidate pre-release
Rc, Rc,
} }
impl std::fmt::Display for PreReleaseKind { impl std::fmt::Display for PrereleaseKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Alpha => write!(f, "a"), Self::Alpha => write!(f, "a"),
@ -1470,7 +1470,7 @@ struct Parser<'a> {
/// The release numbers extracted from the version. /// The release numbers extracted from the version.
release: ReleaseNumbers, release: ReleaseNumbers,
/// The pre-release version, if any. /// The pre-release version, if any.
pre: Option<PreRelease>, pre: Option<Prerelease>,
/// The post-release version, if any. /// The post-release version, if any.
post: Option<u64>, post: Option<u64>,
/// The dev release, if any. /// The dev release, if any.
@ -1687,22 +1687,22 @@ impl<'a> Parser<'a> {
// SPELLINGS and MAP are in correspondence. SPELLINGS is used to look // SPELLINGS and MAP are in correspondence. SPELLINGS is used to look
// for what spelling is used in the version string (if any), and // for what spelling is used in the version string (if any), and
// the index of the element found is used to lookup which type of // the index of the element found is used to lookup which type of
// PreRelease it is. // pre-release it is.
// //
// Note also that the order of the strings themselves matters. If 'pre' // Note also that the order of the strings themselves matters. If 'pre'
// were before 'preview' for example, then 'preview' would never match // were before 'preview' for example, then 'preview' would never match
// since the strings are matched in order. // since the strings are matched in order.
const SPELLINGS: StringSet = const SPELLINGS: StringSet =
StringSet::new(&["alpha", "beta", "preview", "pre", "rc", "a", "b", "c"]); StringSet::new(&["alpha", "beta", "preview", "pre", "rc", "a", "b", "c"]);
const MAP: &[PreReleaseKind] = &[ const MAP: &[PrereleaseKind] = &[
PreReleaseKind::Alpha, PrereleaseKind::Alpha,
PreReleaseKind::Beta, PrereleaseKind::Beta,
PreReleaseKind::Rc, PrereleaseKind::Rc,
PreReleaseKind::Rc, PrereleaseKind::Rc,
PreReleaseKind::Rc, PrereleaseKind::Rc,
PreReleaseKind::Alpha, PrereleaseKind::Alpha,
PreReleaseKind::Beta, PrereleaseKind::Beta,
PreReleaseKind::Rc, PrereleaseKind::Rc,
]; ];
let oldpos = self.i; let oldpos = self.i;
@ -1720,7 +1720,7 @@ impl<'a> Parser<'a> {
// Under the normalization rules, a pre-release without an // Under the normalization rules, a pre-release without an
// explicit number defaults to `0`. // explicit number defaults to `0`.
let number = self.parse_number()?.unwrap_or(0); let number = self.parse_number()?.unwrap_or(0);
self.pre = Some(PreRelease { kind, number }); self.pre = Some(Prerelease { kind, number });
Ok(()) Ok(())
} }
@ -2294,13 +2294,13 @@ impl PyVersion {
pub fn release(&self) -> Vec<u64> { pub fn release(&self) -> Vec<u64> {
self.0.release().to_vec() self.0.release().to_vec()
} }
/// The [prerelease](https://peps.python.org/pep-0440/#pre-releases), i.e. alpha, beta or rc /// The [pre-release](https://peps.python.org/pep-0440/#pre-releases), i.e. alpha, beta or rc
/// plus a number /// plus a number
/// ///
/// Note that whether this is Some influences the version /// Note that whether this is Some influences the version
/// range matching since normally we exclude all prerelease versions /// range matching since normally we exclude all pre-release versions
#[getter] #[getter]
pub fn pre(&self) -> Option<PreRelease> { pub fn pre(&self) -> Option<Prerelease> {
self.0.pre() self.0.pre()
} }
/// The [Post release version](https://peps.python.org/pep-0440/#post-releases), /// The [Post release version](https://peps.python.org/pep-0440/#post-releases),
@ -2452,8 +2452,8 @@ fn sortable_tuple(version: &Version) -> (u64, u64, Option<u64>, u64, &[LocalSegm
(None, None, Some(n), None) => (1, 0, None, n, version.local()), (None, None, Some(n), None) => (1, 0, None, n, version.local()),
// alpha release // alpha release
( (
Some(PreRelease { Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: n, number: n,
}), }),
post, post,
@ -2462,8 +2462,8 @@ fn sortable_tuple(version: &Version) -> (u64, u64, Option<u64>, u64, &[LocalSegm
) => (2, n, post, dev.unwrap_or(u64::MAX), version.local()), ) => (2, n, post, dev.unwrap_or(u64::MAX), version.local()),
// beta release // beta release
( (
Some(PreRelease { Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number: n, number: n,
}), }),
post, post,
@ -2472,8 +2472,8 @@ fn sortable_tuple(version: &Version) -> (u64, u64, Option<u64>, u64, &[LocalSegm
) => (3, n, post, dev.unwrap_or(u64::MAX), version.local()), ) => (3, n, post, dev.unwrap_or(u64::MAX), version.local()),
// alpha release // alpha release
( (
Some(PreRelease { Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: n, number: n,
}), }),
post, post,
@ -2554,16 +2554,16 @@ mod tests {
("1.0.dev456", Version::new([1, 0]).with_dev(Some(456))), ("1.0.dev456", Version::new([1, 0]).with_dev(Some(456))),
( (
"1.0a1", "1.0a1",
Version::new([1, 0]).with_pre(Some(PreRelease { Version::new([1, 0]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 1, number: 1,
})), })),
), ),
( (
"1.0a2.dev456", "1.0a2.dev456",
Version::new([1, 0]) Version::new([1, 0])
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 2, number: 2,
})) }))
.with_dev(Some(456)), .with_dev(Some(456)),
@ -2571,40 +2571,40 @@ mod tests {
( (
"1.0a12.dev456", "1.0a12.dev456",
Version::new([1, 0]) Version::new([1, 0])
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 12, number: 12,
})) }))
.with_dev(Some(456)), .with_dev(Some(456)),
), ),
( (
"1.0a12", "1.0a12",
Version::new([1, 0]).with_pre(Some(PreRelease { Version::new([1, 0]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 12, number: 12,
})), })),
), ),
( (
"1.0b1.dev456", "1.0b1.dev456",
Version::new([1, 0]) Version::new([1, 0])
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number: 1, number: 1,
})) }))
.with_dev(Some(456)), .with_dev(Some(456)),
), ),
( (
"1.0b2", "1.0b2",
Version::new([1, 0]).with_pre(Some(PreRelease { Version::new([1, 0]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number: 2, number: 2,
})), })),
), ),
( (
"1.0b2.post345.dev456", "1.0b2.post345.dev456",
Version::new([1, 0]) Version::new([1, 0])
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number: 2, number: 2,
})) }))
.with_dev(Some(456)) .with_dev(Some(456))
@ -2613,8 +2613,8 @@ mod tests {
( (
"1.0b2.post345", "1.0b2.post345",
Version::new([1, 0]) Version::new([1, 0])
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number: 2, number: 2,
})) }))
.with_post(Some(345)), .with_post(Some(345)),
@ -2622,8 +2622,8 @@ mod tests {
( (
"1.0b2-346", "1.0b2-346",
Version::new([1, 0]) Version::new([1, 0])
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number: 2, number: 2,
})) }))
.with_post(Some(346)), .with_post(Some(346)),
@ -2631,30 +2631,30 @@ mod tests {
( (
"1.0c1.dev456", "1.0c1.dev456",
Version::new([1, 0]) Version::new([1, 0])
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: 1, number: 1,
})) }))
.with_dev(Some(456)), .with_dev(Some(456)),
), ),
( (
"1.0c1", "1.0c1",
Version::new([1, 0]).with_pre(Some(PreRelease { Version::new([1, 0]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: 1, number: 1,
})), })),
), ),
( (
"1.0rc2", "1.0rc2",
Version::new([1, 0]).with_pre(Some(PreRelease { Version::new([1, 0]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: 2, number: 2,
})), })),
), ),
( (
"1.0c3", "1.0c3",
Version::new([1, 0]).with_pre(Some(PreRelease { Version::new([1, 0]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: 3, number: 3,
})), })),
), ),
@ -2719,8 +2719,8 @@ mod tests {
"1!1.0a1", "1!1.0a1",
Version::new([1, 0]) Version::new([1, 0])
.with_epoch(1) .with_epoch(1)
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 1, number: 1,
})), })),
), ),
@ -2728,8 +2728,8 @@ mod tests {
"1!1.0a2.dev456", "1!1.0a2.dev456",
Version::new([1, 0]) Version::new([1, 0])
.with_epoch(1) .with_epoch(1)
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 2, number: 2,
})) }))
.with_dev(Some(456)), .with_dev(Some(456)),
@ -2738,8 +2738,8 @@ mod tests {
"1!1.0a12.dev456", "1!1.0a12.dev456",
Version::new([1, 0]) Version::new([1, 0])
.with_epoch(1) .with_epoch(1)
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 12, number: 12,
})) }))
.with_dev(Some(456)), .with_dev(Some(456)),
@ -2748,8 +2748,8 @@ mod tests {
"1!1.0a12", "1!1.0a12",
Version::new([1, 0]) Version::new([1, 0])
.with_epoch(1) .with_epoch(1)
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 12, number: 12,
})), })),
), ),
@ -2757,8 +2757,8 @@ mod tests {
"1!1.0b1.dev456", "1!1.0b1.dev456",
Version::new([1, 0]) Version::new([1, 0])
.with_epoch(1) .with_epoch(1)
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number: 1, number: 1,
})) }))
.with_dev(Some(456)), .with_dev(Some(456)),
@ -2767,8 +2767,8 @@ mod tests {
"1!1.0b2", "1!1.0b2",
Version::new([1, 0]) Version::new([1, 0])
.with_epoch(1) .with_epoch(1)
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number: 2, number: 2,
})), })),
), ),
@ -2776,8 +2776,8 @@ mod tests {
"1!1.0b2.post345.dev456", "1!1.0b2.post345.dev456",
Version::new([1, 0]) Version::new([1, 0])
.with_epoch(1) .with_epoch(1)
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number: 2, number: 2,
})) }))
.with_post(Some(345)) .with_post(Some(345))
@ -2787,8 +2787,8 @@ mod tests {
"1!1.0b2.post345", "1!1.0b2.post345",
Version::new([1, 0]) Version::new([1, 0])
.with_epoch(1) .with_epoch(1)
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number: 2, number: 2,
})) }))
.with_post(Some(345)), .with_post(Some(345)),
@ -2797,8 +2797,8 @@ mod tests {
"1!1.0b2-346", "1!1.0b2-346",
Version::new([1, 0]) Version::new([1, 0])
.with_epoch(1) .with_epoch(1)
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number: 2, number: 2,
})) }))
.with_post(Some(346)), .with_post(Some(346)),
@ -2807,8 +2807,8 @@ mod tests {
"1!1.0c1.dev456", "1!1.0c1.dev456",
Version::new([1, 0]) Version::new([1, 0])
.with_epoch(1) .with_epoch(1)
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: 1, number: 1,
})) }))
.with_dev(Some(456)), .with_dev(Some(456)),
@ -2817,8 +2817,8 @@ mod tests {
"1!1.0c1", "1!1.0c1",
Version::new([1, 0]) Version::new([1, 0])
.with_epoch(1) .with_epoch(1)
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: 1, number: 1,
})), })),
), ),
@ -2826,8 +2826,8 @@ mod tests {
"1!1.0rc2", "1!1.0rc2",
Version::new([1, 0]) Version::new([1, 0])
.with_epoch(1) .with_epoch(1)
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: 2, number: 2,
})), })),
), ),
@ -2835,8 +2835,8 @@ mod tests {
"1!1.0c3", "1!1.0c3",
Version::new([1, 0]) Version::new([1, 0])
.with_epoch(1) .with_epoch(1)
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: 3, number: 3,
})), })),
), ),
@ -3254,134 +3254,134 @@ mod tests {
// pre-release tests // pre-release tests
assert_eq!( assert_eq!(
p("5a1"), p("5a1"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 1 number: 1
})) }))
); );
assert_eq!( assert_eq!(
p("5alpha1"), p("5alpha1"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 1 number: 1
})) }))
); );
assert_eq!( assert_eq!(
p("5b1"), p("5b1"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number: 1 number: 1
})) }))
); );
assert_eq!( assert_eq!(
p("5beta1"), p("5beta1"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Beta, kind: PrereleaseKind::Beta,
number: 1 number: 1
})) }))
); );
assert_eq!( assert_eq!(
p("5rc1"), p("5rc1"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: 1 number: 1
})) }))
); );
assert_eq!( assert_eq!(
p("5c1"), p("5c1"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: 1 number: 1
})) }))
); );
assert_eq!( assert_eq!(
p("5preview1"), p("5preview1"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: 1 number: 1
})) }))
); );
assert_eq!( assert_eq!(
p("5pre1"), p("5pre1"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: 1 number: 1
})) }))
); );
assert_eq!( assert_eq!(
p("5.6.7pre1"), p("5.6.7pre1"),
Version::new([5, 6, 7]).with_pre(Some(PreRelease { Version::new([5, 6, 7]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Rc, kind: PrereleaseKind::Rc,
number: 1 number: 1
})) }))
); );
assert_eq!( assert_eq!(
p("5alpha789"), p("5alpha789"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 789 number: 789
})) }))
); );
assert_eq!( assert_eq!(
p("5.alpha789"), p("5.alpha789"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 789 number: 789
})) }))
); );
assert_eq!( assert_eq!(
p("5-alpha789"), p("5-alpha789"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 789 number: 789
})) }))
); );
assert_eq!( assert_eq!(
p("5_alpha789"), p("5_alpha789"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 789 number: 789
})) }))
); );
assert_eq!( assert_eq!(
p("5alpha.789"), p("5alpha.789"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 789 number: 789
})) }))
); );
assert_eq!( assert_eq!(
p("5alpha-789"), p("5alpha-789"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 789 number: 789
})) }))
); );
assert_eq!( assert_eq!(
p("5alpha_789"), p("5alpha_789"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 789 number: 789
})) }))
); );
assert_eq!( assert_eq!(
p("5ALPHA789"), p("5ALPHA789"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 789 number: 789
})) }))
); );
assert_eq!( assert_eq!(
p("5aLpHa789"), p("5aLpHa789"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 789 number: 789
})) }))
); );
assert_eq!( assert_eq!(
p("5alpha"), p("5alpha"),
Version::new([5]).with_pre(Some(PreRelease { Version::new([5]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 0 number: 0
})) }))
); );
@ -3501,8 +3501,8 @@ mod tests {
assert_eq!( assert_eq!(
p("5a2post3"), p("5a2post3"),
Version::new([5]) Version::new([5])
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 2 number: 2
})) }))
.with_post(Some(3)) .with_post(Some(3))
@ -3510,8 +3510,8 @@ mod tests {
assert_eq!( assert_eq!(
p("5.a-2_post-3"), p("5.a-2_post-3"),
Version::new([5]) Version::new([5])
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 2 number: 2
})) }))
.with_post(Some(3)) .with_post(Some(3))
@ -3519,8 +3519,8 @@ mod tests {
assert_eq!( assert_eq!(
p("5a2-3"), p("5a2-3"),
Version::new([5]) Version::new([5])
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 2 number: 2
})) }))
.with_post(Some(3)) .with_post(Some(3))
@ -3769,8 +3769,8 @@ mod tests {
// Ensure that the `.max` suffix plays nicely with pre-release versions. // Ensure that the `.max` suffix plays nicely with pre-release versions.
let greater = Version::new([1, 0]) let greater = Version::new([1, 0])
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 1, number: 1,
})) }))
.with_max(Some(0)); .with_max(Some(0));
@ -3790,8 +3790,8 @@ mod tests {
// Ensure that the `.max` suffix plays nicely with pre-release versions. // Ensure that the `.max` suffix plays nicely with pre-release versions.
let less = Version::new([1, 0]) let less = Version::new([1, 0])
.with_pre(Some(PreRelease { .with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 1, number: 1,
})) }))
.with_max(Some(0)); .with_max(Some(0));

View File

@ -537,7 +537,7 @@ impl VersionSpecifier {
return false; return false;
} }
// According to PEP 440, this ignores the prerelease special rules // According to PEP 440, this ignores the pre-release special rules
// pypa/packaging disagrees: https://github.com/pypa/packaging/issues/617 // pypa/packaging disagrees: https://github.com/pypa/packaging/issues/617
other >= this other >= this
} }

View File

@ -16,7 +16,7 @@ use uv_configuration::{
}; };
use uv_normalize::{ExtraName, PackageName}; use uv_normalize::{ExtraName, PackageName};
use uv_python::{PythonFetch, PythonPreference, PythonVersion}; use uv_python::{PythonFetch, PythonPreference, PythonVersion};
use uv_resolver::{AnnotationStyle, ExcludeNewer, PreReleaseMode, ResolutionMode}; use uv_resolver::{AnnotationStyle, ExcludeNewer, PrereleaseMode, ResolutionMode};
pub mod compat; pub mod compat;
pub mod options; pub mod options;
@ -2868,7 +2868,7 @@ pub struct ResolverArgs {
/// along with first-party requirements that contain an explicit pre-release marker in the /// along with first-party requirements that contain an explicit pre-release marker in the
/// declared specifiers (`if-necessary-or-explicit`). /// declared specifiers (`if-necessary-or-explicit`).
#[arg(long, value_enum, env = "UV_PRERELEASE")] #[arg(long, value_enum, env = "UV_PRERELEASE")]
pub prerelease: Option<PreReleaseMode>, pub prerelease: Option<PrereleaseMode>,
#[arg(long, hide = true)] #[arg(long, hide = true)]
pub pre: bool, pub pre: bool,
@ -2957,7 +2957,7 @@ pub struct ResolverInstallerArgs {
/// along with first-party requirements that contain an explicit pre-release marker in the /// along with first-party requirements that contain an explicit pre-release marker in the
/// declared specifiers (`if-necessary-or-explicit`). /// declared specifiers (`if-necessary-or-explicit`).
#[arg(long, value_enum, env = "UV_PRERELEASE")] #[arg(long, value_enum, env = "UV_PRERELEASE")]
pub prerelease: Option<PreReleaseMode>, pub prerelease: Option<PrereleaseMode>,
#[arg(long, hide = true)] #[arg(long, hide = true)]
pub pre: bool, pub pre: bool,

View File

@ -1,6 +1,6 @@
use uv_cache::Refresh; use uv_cache::Refresh;
use uv_configuration::ConfigSettings; use uv_configuration::ConfigSettings;
use uv_resolver::PreReleaseMode; use uv_resolver::PrereleaseMode;
use uv_settings::{PipOptions, ResolverInstallerOptions, ResolverOptions}; use uv_settings::{PipOptions, ResolverInstallerOptions, ResolverOptions};
use crate::{ use crate::{
@ -53,7 +53,7 @@ impl From<ResolverArgs> for PipOptions {
keyring_provider, keyring_provider,
resolution, resolution,
prerelease: if pre { prerelease: if pre {
Some(PreReleaseMode::Allow) Some(PrereleaseMode::Allow)
} else { } else {
prerelease prerelease
}, },
@ -128,7 +128,7 @@ impl From<ResolverInstallerArgs> for PipOptions {
keyring_provider, keyring_provider,
resolution, resolution,
prerelease: if pre { prerelease: if pre {
Some(PreReleaseMode::Allow) Some(PrereleaseMode::Allow)
} else { } else {
prerelease prerelease
}, },
@ -212,7 +212,7 @@ pub fn resolver_options(resolver_args: ResolverArgs, build_args: BuildArgs) -> R
keyring_provider, keyring_provider,
resolution, resolution,
prerelease: if pre { prerelease: if pre {
Some(PreReleaseMode::Allow) Some(PrereleaseMode::Allow)
} else { } else {
prerelease prerelease
}, },
@ -283,7 +283,7 @@ pub fn resolver_installer_options(
keyring_provider, keyring_provider,
resolution, resolution,
prerelease: if pre { prerelease: if pre {
Some(PreReleaseMode::Allow) Some(PrereleaseMode::Allow)
} else { } else {
prerelease prerelease
}, },

View File

@ -177,7 +177,7 @@ impl PythonVersion {
mod tests { mod tests {
use std::str::FromStr; use std::str::FromStr;
use pep440_rs::{PreRelease, PreReleaseKind, Version}; use pep440_rs::{Prerelease, PrereleaseKind, Version};
use crate::PythonVersion; use crate::PythonVersion;
@ -200,8 +200,8 @@ mod tests {
assert_eq!(version.python_version().to_string(), "3.11"); assert_eq!(version.python_version().to_string(), "3.11");
assert_eq!( assert_eq!(
version.python_full_version(), version.python_full_version(),
Version::new([3, 11, 8]).with_pre(Some(PreRelease { Version::new([3, 11, 8]).with_pre(Some(Prerelease {
kind: PreReleaseKind::Alpha, kind: PrereleaseKind::Alpha,
number: 1 number: 1
})) }))
); );

View File

@ -12,7 +12,7 @@ use uv_normalize::PackageName;
use uv_types::InstalledPackagesProvider; use uv_types::InstalledPackagesProvider;
use crate::preferences::Preferences; use crate::preferences::Preferences;
use crate::prerelease_mode::{AllowPreRelease, PreReleaseStrategy}; use crate::prerelease::{AllowPrerelease, PrereleaseStrategy};
use crate::resolution_mode::ResolutionStrategy; use crate::resolution_mode::ResolutionStrategy;
use crate::version_map::{VersionMap, VersionMapDistHandle}; use crate::version_map::{VersionMap, VersionMapDistHandle};
use crate::{Exclusions, Manifest, Options, ResolverMarkers}; use crate::{Exclusions, Manifest, Options, ResolverMarkers};
@ -21,7 +21,7 @@ use crate::{Exclusions, Manifest, Options, ResolverMarkers};
#[allow(clippy::struct_field_names)] #[allow(clippy::struct_field_names)]
pub(crate) struct CandidateSelector { pub(crate) struct CandidateSelector {
resolution_strategy: ResolutionStrategy, resolution_strategy: ResolutionStrategy,
prerelease_strategy: PreReleaseStrategy, prerelease_strategy: PrereleaseStrategy,
index_strategy: IndexStrategy, index_strategy: IndexStrategy,
} }
@ -39,7 +39,7 @@ impl CandidateSelector {
markers, markers,
options.dependency_mode, options.dependency_mode,
), ),
prerelease_strategy: PreReleaseStrategy::from_mode( prerelease_strategy: PrereleaseStrategy::from_mode(
options.prerelease_mode, options.prerelease_mode,
manifest, manifest,
markers, markers,
@ -57,7 +57,7 @@ impl CandidateSelector {
#[inline] #[inline]
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn prerelease_strategy(&self) -> &PreReleaseStrategy { pub(crate) fn prerelease_strategy(&self) -> &PrereleaseStrategy {
&self.prerelease_strategy &self.prerelease_strategy
} }
@ -244,7 +244,7 @@ impl CandidateSelector {
&& self && self
.prerelease_strategy .prerelease_strategy
.allows(package_name, resolver_markers) .allows(package_name, resolver_markers)
!= AllowPreRelease::Yes != AllowPrerelease::Yes
{ {
continue; continue;
} }
@ -404,10 +404,10 @@ impl CandidateSelector {
versions: impl Iterator<Item = (&'a Version, VersionMapDistHandle<'a>)>, versions: impl Iterator<Item = (&'a Version, VersionMapDistHandle<'a>)>,
package_name: &'a PackageName, package_name: &'a PackageName,
range: &Range<Version>, range: &Range<Version>,
allow_prerelease: AllowPreRelease, allow_prerelease: AllowPrerelease,
) -> Option<Candidate<'a>> { ) -> Option<Candidate<'a>> {
#[derive(Debug)] #[derive(Debug)]
enum PreReleaseCandidate<'a> { enum PrereleaseCandidate<'a> {
NotNecessary, NotNecessary,
IfNecessary(&'a Version, &'a PrioritizedDist), IfNecessary(&'a Version, &'a PrioritizedDist),
} }
@ -419,7 +419,7 @@ impl CandidateSelector {
let candidate = if version.any_prerelease() { let candidate = if version.any_prerelease() {
if range.contains(version) { if range.contains(version) {
match allow_prerelease { match allow_prerelease {
AllowPreRelease::Yes => { AllowPrerelease::Yes => {
let Some(dist) = maybe_dist.prioritized_dist() else { let Some(dist) = maybe_dist.prioritized_dist() else {
continue; continue;
}; };
@ -440,18 +440,18 @@ impl CandidateSelector {
VersionChoiceKind::Compatible, VersionChoiceKind::Compatible,
) )
} }
AllowPreRelease::IfNecessary => { AllowPrerelease::IfNecessary => {
let Some(dist) = maybe_dist.prioritized_dist() else { let Some(dist) = maybe_dist.prioritized_dist() else {
continue; continue;
}; };
// If pre-releases are allowed as a fallback, store the // If pre-releases are allowed as a fallback, store the
// first-matching prerelease. // first-matching prerelease.
if prerelease.is_none() { if prerelease.is_none() {
prerelease = Some(PreReleaseCandidate::IfNecessary(version, dist)); prerelease = Some(PrereleaseCandidate::IfNecessary(version, dist));
} }
continue; continue;
} }
AllowPreRelease::No => { AllowPrerelease::No => {
continue; continue;
} }
} }
@ -462,7 +462,7 @@ impl CandidateSelector {
// If we have at least one stable release, we shouldn't allow the "if-necessary" // If we have at least one stable release, we shouldn't allow the "if-necessary"
// pre-release strategy, regardless of whether that stable release satisfies the // pre-release strategy, regardless of whether that stable release satisfies the
// current range. // current range.
prerelease = Some(PreReleaseCandidate::NotNecessary); prerelease = Some(PrereleaseCandidate::NotNecessary);
// Return the first-matching stable distribution. // Return the first-matching stable distribution.
if range.contains(version) { if range.contains(version) {
@ -507,8 +507,8 @@ impl CandidateSelector {
); );
match prerelease { match prerelease {
None => None, None => None,
Some(PreReleaseCandidate::NotNecessary) => None, Some(PrereleaseCandidate::NotNecessary) => None,
Some(PreReleaseCandidate::IfNecessary(version, dist)) => Some(Candidate::new( Some(PrereleaseCandidate::IfNecessary(version, dist)) => Some(Candidate::new(
package_name, package_name,
version, version,
dist, dist,

View File

@ -7,7 +7,7 @@ pub use lock::{Lock, LockError};
pub use manifest::Manifest; pub use manifest::Manifest;
pub use options::{Options, OptionsBuilder}; pub use options::{Options, OptionsBuilder};
pub use preferences::{Preference, PreferenceError, Preferences}; pub use preferences::{Preference, PreferenceError, Preferences};
pub use prerelease_mode::PreReleaseMode; pub use prerelease::PrereleaseMode;
pub use pubgrub::{PubGrubSpecifier, PubGrubSpecifierError}; pub use pubgrub::{PubGrubSpecifier, PubGrubSpecifierError};
pub use python_requirement::PythonRequirement; pub use python_requirement::PythonRequirement;
pub use requires_python::{RequiresPython, RequiresPythonBound, RequiresPythonError}; pub use requires_python::{RequiresPython, RequiresPythonBound, RequiresPythonError};
@ -37,7 +37,7 @@ mod marker;
mod options; mod options;
mod pins; mod pins;
mod preferences; mod preferences;
mod prerelease_mode; mod prerelease;
mod pubgrub; mod pubgrub;
mod python_requirement; mod python_requirement;
mod redirect; mod redirect;

View File

@ -42,7 +42,7 @@ use uv_workspace::VirtualProject;
use crate::resolution::{AnnotatedDist, ResolutionGraphNode}; use crate::resolution::{AnnotatedDist, ResolutionGraphNode};
use crate::resolver::FxOnceMap; use crate::resolver::FxOnceMap;
use crate::{ use crate::{
ExcludeNewer, InMemoryIndex, MetadataResponse, PreReleaseMode, RequiresPython, ResolutionGraph, ExcludeNewer, InMemoryIndex, MetadataResponse, PrereleaseMode, RequiresPython, ResolutionGraph,
ResolutionMode, VersionMap, VersionsResponse, ResolutionMode, VersionMap, VersionsResponse,
}; };
@ -61,8 +61,8 @@ pub struct Lock {
requires_python: Option<RequiresPython>, requires_python: Option<RequiresPython>,
/// The [`ResolutionMode`] used to generate this lock. /// The [`ResolutionMode`] used to generate this lock.
resolution_mode: ResolutionMode, resolution_mode: ResolutionMode,
/// The [`PreReleaseMode`] used to generate this lock. /// The [`PrereleaseMode`] used to generate this lock.
prerelease_mode: PreReleaseMode, prerelease_mode: PrereleaseMode,
/// The [`ExcludeNewer`] used to generate this lock. /// The [`ExcludeNewer`] used to generate this lock.
exclude_newer: Option<ExcludeNewer>, exclude_newer: Option<ExcludeNewer>,
/// The actual locked version and their metadata. /// The actual locked version and their metadata.
@ -180,7 +180,7 @@ impl Lock {
mut distributions: Vec<Distribution>, mut distributions: Vec<Distribution>,
requires_python: Option<RequiresPython>, requires_python: Option<RequiresPython>,
resolution_mode: ResolutionMode, resolution_mode: ResolutionMode,
prerelease_mode: PreReleaseMode, prerelease_mode: PrereleaseMode,
exclude_newer: Option<ExcludeNewer>, exclude_newer: Option<ExcludeNewer>,
fork_markers: Option<BTreeSet<MarkerTree>>, fork_markers: Option<BTreeSet<MarkerTree>>,
) -> Result<Self, LockError> { ) -> Result<Self, LockError> {
@ -367,7 +367,7 @@ impl Lock {
} }
/// Returns the pre-release mode used to generate this lock. /// Returns the pre-release mode used to generate this lock.
pub fn prerelease_mode(&self) -> PreReleaseMode { pub fn prerelease_mode(&self) -> PrereleaseMode {
self.prerelease_mode self.prerelease_mode
} }
@ -482,7 +482,7 @@ impl Lock {
if self.resolution_mode != ResolutionMode::default() { if self.resolution_mode != ResolutionMode::default() {
doc.insert("resolution-mode", value(self.resolution_mode.to_string())); doc.insert("resolution-mode", value(self.resolution_mode.to_string()));
} }
if self.prerelease_mode != PreReleaseMode::default() { if self.prerelease_mode != PrereleaseMode::default() {
doc.insert("prerelease-mode", value(self.prerelease_mode.to_string())); doc.insert("prerelease-mode", value(self.prerelease_mode.to_string()));
} }
if let Some(exclude_newer) = self.exclude_newer { if let Some(exclude_newer) = self.exclude_newer {
@ -604,7 +604,7 @@ struct LockWire {
#[serde(default)] #[serde(default)]
resolution_mode: ResolutionMode, resolution_mode: ResolutionMode,
#[serde(default)] #[serde(default)]
prerelease_mode: PreReleaseMode, prerelease_mode: PrereleaseMode,
#[serde(default)] #[serde(default)]
exclude_newer: Option<ExcludeNewer>, exclude_newer: Option<ExcludeNewer>,
#[serde(rename = "distribution", default)] #[serde(rename = "distribution", default)]

View File

@ -1,12 +1,12 @@
use uv_configuration::IndexStrategy; use uv_configuration::IndexStrategy;
use crate::{DependencyMode, ExcludeNewer, PreReleaseMode, ResolutionMode}; use crate::{DependencyMode, ExcludeNewer, PrereleaseMode, ResolutionMode};
/// Options for resolving a manifest. /// Options for resolving a manifest.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, serde::Deserialize)] #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, serde::Deserialize)]
pub struct Options { pub struct Options {
pub resolution_mode: ResolutionMode, pub resolution_mode: ResolutionMode,
pub prerelease_mode: PreReleaseMode, pub prerelease_mode: PrereleaseMode,
pub dependency_mode: DependencyMode, pub dependency_mode: DependencyMode,
pub exclude_newer: Option<ExcludeNewer>, pub exclude_newer: Option<ExcludeNewer>,
pub index_strategy: IndexStrategy, pub index_strategy: IndexStrategy,
@ -16,7 +16,7 @@ pub struct Options {
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct OptionsBuilder { pub struct OptionsBuilder {
resolution_mode: ResolutionMode, resolution_mode: ResolutionMode,
prerelease_mode: PreReleaseMode, prerelease_mode: PrereleaseMode,
dependency_mode: DependencyMode, dependency_mode: DependencyMode,
exclude_newer: Option<ExcludeNewer>, exclude_newer: Option<ExcludeNewer>,
index_strategy: IndexStrategy, index_strategy: IndexStrategy,
@ -35,9 +35,9 @@ impl OptionsBuilder {
self self
} }
/// Sets the [`PreReleaseMode`]. /// Sets the [`PrereleaseMode`].
#[must_use] #[must_use]
pub fn prerelease_mode(mut self, prerelease_mode: PreReleaseMode) -> Self { pub fn prerelease_mode(mut self, prerelease_mode: PrereleaseMode) -> Self {
self.prerelease_mode = prerelease_mode; self.prerelease_mode = prerelease_mode;
self self
} }

View File

@ -10,7 +10,7 @@ use crate::{DependencyMode, Manifest, ResolverMarkers};
#[serde(deny_unknown_fields, rename_all = "kebab-case")] #[serde(deny_unknown_fields, rename_all = "kebab-case")]
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))] #[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum PreReleaseMode { pub enum PrereleaseMode {
/// Disallow all pre-release versions. /// Disallow all pre-release versions.
Disallow, Disallow,
@ -30,7 +30,7 @@ pub enum PreReleaseMode {
IfNecessaryOrExplicit, IfNecessaryOrExplicit,
} }
impl std::fmt::Display for PreReleaseMode { impl std::fmt::Display for PrereleaseMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Disallow => write!(f, "disallow"), Self::Disallow => write!(f, "disallow"),
@ -42,10 +42,10 @@ impl std::fmt::Display for PreReleaseMode {
} }
} }
/// Like [`PreReleaseMode`], but with any additional information required to select a candidate, /// Like [`PrereleaseMode`], but with any additional information required to select a candidate,
/// like the set of direct dependencies. /// like the set of direct dependencies.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) enum PreReleaseStrategy { pub(crate) enum PrereleaseStrategy {
/// Disallow all pre-release versions. /// Disallow all pre-release versions.
Disallow, Disallow,
@ -64,9 +64,9 @@ pub(crate) enum PreReleaseStrategy {
IfNecessaryOrExplicit(ForkSet), IfNecessaryOrExplicit(ForkSet),
} }
impl PreReleaseStrategy { impl PrereleaseStrategy {
pub(crate) fn from_mode( pub(crate) fn from_mode(
mode: PreReleaseMode, mode: PrereleaseMode,
manifest: &Manifest, manifest: &Manifest,
markers: Option<&MarkerEnvironment>, markers: Option<&MarkerEnvironment>,
dependencies: DependencyMode, dependencies: DependencyMode,
@ -74,9 +74,9 @@ impl PreReleaseStrategy {
let mut packages = ForkSet::default(); let mut packages = ForkSet::default();
match mode { match mode {
PreReleaseMode::Disallow => Self::Disallow, PrereleaseMode::Disallow => Self::Disallow,
PreReleaseMode::Allow => Self::Allow, PrereleaseMode::Allow => Self::Allow,
PreReleaseMode::IfNecessary => Self::IfNecessary, PrereleaseMode::IfNecessary => Self::IfNecessary,
_ => { _ => {
for requirement in manifest.requirements(markers, dependencies) { for requirement in manifest.requirements(markers, dependencies) {
let RequirementSource::Registry { specifier, .. } = &requirement.source else { let RequirementSource::Registry { specifier, .. } = &requirement.source else {
@ -92,8 +92,8 @@ impl PreReleaseStrategy {
} }
match mode { match mode {
PreReleaseMode::Explicit => Self::Explicit(packages), PrereleaseMode::Explicit => Self::Explicit(packages),
PreReleaseMode::IfNecessaryOrExplicit => Self::IfNecessaryOrExplicit(packages), PrereleaseMode::IfNecessaryOrExplicit => Self::IfNecessaryOrExplicit(packages),
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -105,23 +105,23 @@ impl PreReleaseStrategy {
&self, &self,
package_name: &PackageName, package_name: &PackageName,
markers: &ResolverMarkers, markers: &ResolverMarkers,
) -> AllowPreRelease { ) -> AllowPrerelease {
match self { match self {
PreReleaseStrategy::Disallow => AllowPreRelease::No, PrereleaseStrategy::Disallow => AllowPrerelease::No,
PreReleaseStrategy::Allow => AllowPreRelease::Yes, PrereleaseStrategy::Allow => AllowPrerelease::Yes,
PreReleaseStrategy::IfNecessary => AllowPreRelease::IfNecessary, PrereleaseStrategy::IfNecessary => AllowPrerelease::IfNecessary,
PreReleaseStrategy::Explicit(packages) => { PrereleaseStrategy::Explicit(packages) => {
if packages.contains(package_name, markers) { if packages.contains(package_name, markers) {
AllowPreRelease::Yes AllowPrerelease::Yes
} else { } else {
AllowPreRelease::No AllowPrerelease::No
} }
} }
PreReleaseStrategy::IfNecessaryOrExplicit(packages) => { PrereleaseStrategy::IfNecessaryOrExplicit(packages) => {
if packages.contains(package_name, markers) { if packages.contains(package_name, markers) {
AllowPreRelease::Yes AllowPrerelease::Yes
} else { } else {
AllowPreRelease::IfNecessary AllowPrerelease::IfNecessary
} }
} }
} }
@ -130,7 +130,7 @@ impl PreReleaseStrategy {
/// The pre-release strategy for a given package. /// The pre-release strategy for a given package.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) enum AllowPreRelease { pub(crate) enum AllowPrerelease {
/// Allow all pre-release versions. /// Allow all pre-release versions.
Yes, Yes,

View File

@ -15,7 +15,7 @@ use uv_normalize::PackageName;
use crate::candidate_selector::CandidateSelector; use crate::candidate_selector::CandidateSelector;
use crate::fork_urls::ForkUrls; use crate::fork_urls::ForkUrls;
use crate::prerelease_mode::AllowPreRelease; use crate::prerelease::AllowPrerelease;
use crate::python_requirement::{PythonRequirement, PythonTarget}; use crate::python_requirement::{PythonRequirement, PythonTarget};
use crate::resolver::{IncompletePackage, UnavailablePackage, UnavailableReason}; use crate::resolver::{IncompletePackage, UnavailablePackage, UnavailableReason};
use crate::{RequiresPython, ResolverMarkers}; use crate::{RequiresPython, ResolverMarkers};
@ -591,8 +591,8 @@ impl PubGrubReportFormatter<'_> {
if any_prerelease { if any_prerelease {
// A pre-release marker appeared in the version requirements. // A pre-release marker appeared in the version requirements.
if selector.prerelease_strategy().allows(name, markers) != AllowPreRelease::Yes { if selector.prerelease_strategy().allows(name, markers) != AllowPrerelease::Yes {
hints.insert(PubGrubHint::PreReleaseRequested { hints.insert(PubGrubHint::PrereleaseRequested {
package: package.clone(), package: package.clone(),
range: self.simplify_set(set, package).into_owned(), range: self.simplify_set(set, package).into_owned(),
}); });
@ -605,8 +605,8 @@ impl PubGrubReportFormatter<'_> {
.find(|version| set.contains(version)) .find(|version| set.contains(version))
}) { }) {
// There are pre-release versions available for the package. // There are pre-release versions available for the package.
if selector.prerelease_strategy().allows(name, markers) != AllowPreRelease::Yes { if selector.prerelease_strategy().allows(name, markers) != AllowPrerelease::Yes {
hints.insert(PubGrubHint::PreReleaseAvailable { hints.insert(PubGrubHint::PrereleaseAvailable {
package: package.clone(), package: package.clone(),
version: version.clone(), version: version.clone(),
}); });
@ -621,14 +621,14 @@ pub(crate) enum PubGrubHint {
/// There are pre-release versions available for a package, but pre-releases weren't enabled /// There are pre-release versions available for a package, but pre-releases weren't enabled
/// for that package. /// for that package.
/// ///
PreReleaseAvailable { PrereleaseAvailable {
package: PubGrubPackage, package: PubGrubPackage,
#[derivative(PartialEq = "ignore", Hash = "ignore")] #[derivative(PartialEq = "ignore", Hash = "ignore")]
version: Version, version: Version,
}, },
/// A requirement included a pre-release marker, but pre-releases weren't enabled for that /// A requirement included a pre-release marker, but pre-releases weren't enabled for that
/// package. /// package.
PreReleaseRequested { PrereleaseRequested {
package: PubGrubPackage, package: PubGrubPackage,
#[derivative(PartialEq = "ignore", Hash = "ignore")] #[derivative(PartialEq = "ignore", Hash = "ignore")]
range: Range<Version>, range: Range<Version>,
@ -698,7 +698,7 @@ pub(crate) enum PubGrubHint {
impl std::fmt::Display for PubGrubHint { impl std::fmt::Display for PubGrubHint {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::PreReleaseAvailable { package, version } => { Self::PrereleaseAvailable { package, version } => {
write!( write!(
f, f,
"{}{} Pre-releases are available for {} in the requested range (e.g., {}), but pre-releases weren't enabled (try: `--prerelease=allow`)", "{}{} Pre-releases are available for {} in the requested range (e.g., {}), but pre-releases weren't enabled (try: `--prerelease=allow`)",
@ -708,7 +708,7 @@ impl std::fmt::Display for PubGrubHint {
version.bold() version.bold()
) )
} }
Self::PreReleaseRequested { package, range } => { Self::PrereleaseRequested { package, range } => {
write!( write!(
f, f,
"{}{} {} was requested with a pre-release marker (e.g., {}), but pre-releases weren't enabled (try: `--prerelease=allow`)", "{}{} {} was requested with a pre-release marker (e.g., {}), but pre-releases weren't enabled (try: `--prerelease=allow`)",

View File

@ -4,7 +4,7 @@ use itertools::Itertools;
use pubgrub::Range; use pubgrub::Range;
use thiserror::Error; use thiserror::Error;
use pep440_rs::{Operator, PreRelease, Version, VersionSpecifier, VersionSpecifiers}; use pep440_rs::{Operator, Prerelease, Version, VersionSpecifier, VersionSpecifiers};
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum PubGrubSpecifierError { pub enum PubGrubSpecifierError {
@ -115,7 +115,7 @@ impl PubGrubSpecifier {
if let Some(post) = high.post() { if let Some(post) = high.post() {
high = high.with_post(Some(post + 1)); high = high.with_post(Some(post + 1));
} else if let Some(pre) = high.pre() { } else if let Some(pre) = high.pre() {
high = high.with_pre(Some(PreRelease { high = high.with_pre(Some(Prerelease {
kind: pre.kind, kind: pre.kind,
number: pre.number + 1, number: pre.number + 1,
})); }));
@ -132,7 +132,7 @@ impl PubGrubSpecifier {
if let Some(post) = high.post() { if let Some(post) = high.post() {
high = high.with_post(Some(post + 1)); high = high.with_post(Some(post + 1));
} else if let Some(pre) = high.pre() { } else if let Some(pre) = high.pre() {
high = high.with_pre(Some(PreRelease { high = high.with_pre(Some(Prerelease {
kind: pre.kind, kind: pre.kind,
number: pre.number + 1, number: pre.number + 1,
})); }));

View File

@ -5,7 +5,7 @@ use distribution_types::IndexUrl;
use install_wheel_rs::linker::LinkMode; use install_wheel_rs::linker::LinkMode;
use uv_configuration::{ConfigSettings, IndexStrategy, KeyringProviderType, TargetTriple}; use uv_configuration::{ConfigSettings, IndexStrategy, KeyringProviderType, TargetTriple};
use uv_python::{PythonFetch, PythonPreference, PythonVersion}; use uv_python::{PythonFetch, PythonPreference, PythonVersion};
use uv_resolver::{AnnotationStyle, ExcludeNewer, PreReleaseMode, ResolutionMode}; use uv_resolver::{AnnotationStyle, ExcludeNewer, PrereleaseMode, ResolutionMode};
use crate::{FilesystemOptions, PipOptions}; use crate::{FilesystemOptions, PipOptions};
@ -64,7 +64,7 @@ impl_combine_or!(KeyringProviderType);
impl_combine_or!(LinkMode); impl_combine_or!(LinkMode);
impl_combine_or!(NonZeroUsize); impl_combine_or!(NonZeroUsize);
impl_combine_or!(PathBuf); impl_combine_or!(PathBuf);
impl_combine_or!(PreReleaseMode); impl_combine_or!(PrereleaseMode);
impl_combine_or!(PythonVersion); impl_combine_or!(PythonVersion);
impl_combine_or!(ResolutionMode); impl_combine_or!(ResolutionMode);
impl_combine_or!(String); impl_combine_or!(String);

View File

@ -12,7 +12,7 @@ use uv_configuration::{
use uv_macros::{CombineOptions, OptionsMetadata}; use uv_macros::{CombineOptions, OptionsMetadata};
use uv_normalize::{ExtraName, PackageName}; use uv_normalize::{ExtraName, PackageName};
use uv_python::{PythonFetch, PythonPreference, PythonVersion}; use uv_python::{PythonFetch, PythonPreference, PythonVersion};
use uv_resolver::{AnnotationStyle, ExcludeNewer, PreReleaseMode, ResolutionMode}; use uv_resolver::{AnnotationStyle, ExcludeNewer, PrereleaseMode, ResolutionMode};
/// A `pyproject.toml` with an (optional) `[tool.uv]` section. /// A `pyproject.toml` with an (optional) `[tool.uv]` section.
#[allow(dead_code)] #[allow(dead_code)]
@ -174,7 +174,7 @@ pub struct ResolverOptions {
pub index_strategy: Option<IndexStrategy>, pub index_strategy: Option<IndexStrategy>,
pub keyring_provider: Option<KeyringProviderType>, pub keyring_provider: Option<KeyringProviderType>,
pub resolution: Option<ResolutionMode>, pub resolution: Option<ResolutionMode>,
pub prerelease: Option<PreReleaseMode>, pub prerelease: Option<PrereleaseMode>,
pub config_settings: Option<ConfigSettings>, pub config_settings: Option<ConfigSettings>,
pub exclude_newer: Option<ExcludeNewer>, pub exclude_newer: Option<ExcludeNewer>,
pub link_mode: Option<LinkMode>, pub link_mode: Option<LinkMode>,
@ -305,7 +305,7 @@ pub struct ResolverInstallerOptions {
"#, "#,
possible_values = true possible_values = true
)] )]
pub prerelease: Option<PreReleaseMode>, pub prerelease: Option<PrereleaseMode>,
/// Settings to pass to the [PEP 517](https://peps.python.org/pep-0517/) build backend, /// Settings to pass to the [PEP 517](https://peps.python.org/pep-0517/) build backend,
/// specified as `KEY=VALUE` pairs. /// specified as `KEY=VALUE` pairs.
#[option( #[option(
@ -750,7 +750,7 @@ pub struct PipOptions {
"#, "#,
possible_values = true possible_values = true
)] )]
pub prerelease: Option<PreReleaseMode>, pub prerelease: Option<PrereleaseMode>,
/// Write the requirements generated by `uv pip compile` to the given `requirements.txt` file. /// Write the requirements generated by `uv pip compile` to the given `requirements.txt` file.
/// ///
/// If the file already exists, the existing versions will be preferred when resolving /// If the file already exists, the existing versions will be preferred when resolving

View File

@ -32,7 +32,7 @@ use uv_requirements::{
}; };
use uv_resolver::{ use uv_resolver::{
AnnotationStyle, DependencyMode, DisplayResolutionGraph, ExcludeNewer, FlatIndex, AnnotationStyle, DependencyMode, DisplayResolutionGraph, ExcludeNewer, FlatIndex,
InMemoryIndex, OptionsBuilder, PreReleaseMode, PythonRequirement, RequiresPython, InMemoryIndex, OptionsBuilder, PrereleaseMode, PythonRequirement, RequiresPython,
ResolutionMode, ResolverMarkers, ResolutionMode, ResolverMarkers,
}; };
use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy, InFlight}; use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy, InFlight};
@ -53,7 +53,7 @@ pub(crate) async fn pip_compile(
extras: ExtrasSpecification, extras: ExtrasSpecification,
output_file: Option<&Path>, output_file: Option<&Path>,
resolution_mode: ResolutionMode, resolution_mode: ResolutionMode,
prerelease_mode: PreReleaseMode, prerelease_mode: PrereleaseMode,
dependency_mode: DependencyMode, dependency_mode: DependencyMode,
upgrade: Upgrade, upgrade: Upgrade,
generate_hashes: bool, generate_hashes: bool,

View File

@ -24,7 +24,7 @@ use uv_python::{
}; };
use uv_requirements::{RequirementsSource, RequirementsSpecification}; use uv_requirements::{RequirementsSource, RequirementsSpecification};
use uv_resolver::{ use uv_resolver::{
DependencyMode, ExcludeNewer, FlatIndex, OptionsBuilder, PreReleaseMode, PythonRequirement, DependencyMode, ExcludeNewer, FlatIndex, OptionsBuilder, PrereleaseMode, PythonRequirement,
ResolutionMode, ResolverMarkers, ResolutionMode, ResolverMarkers,
}; };
use uv_types::{BuildIsolation, HashStrategy}; use uv_types::{BuildIsolation, HashStrategy};
@ -44,7 +44,7 @@ pub(crate) async fn pip_install(
overrides_from_workspace: Vec<Requirement>, overrides_from_workspace: Vec<Requirement>,
extras: &ExtrasSpecification, extras: &ExtrasSpecification,
resolution_mode: ResolutionMode, resolution_mode: ResolutionMode,
prerelease_mode: PreReleaseMode, prerelease_mode: PrereleaseMode,
dependency_mode: DependencyMode, dependency_mode: DependencyMode,
upgrade: Upgrade, upgrade: Upgrade,
index_locations: IndexLocations, index_locations: IndexLocations,

View File

@ -23,7 +23,7 @@ use uv_python::{
}; };
use uv_requirements::{RequirementsSource, RequirementsSpecification}; use uv_requirements::{RequirementsSource, RequirementsSpecification};
use uv_resolver::{ use uv_resolver::{
DependencyMode, ExcludeNewer, FlatIndex, OptionsBuilder, PreReleaseMode, PythonRequirement, DependencyMode, ExcludeNewer, FlatIndex, OptionsBuilder, PrereleaseMode, PythonRequirement,
ResolutionMode, ResolverMarkers, ResolutionMode, ResolverMarkers,
}; };
use uv_types::{BuildIsolation, HashStrategy}; use uv_types::{BuildIsolation, HashStrategy};
@ -77,7 +77,7 @@ pub(crate) async fn pip_sync(
let extras = ExtrasSpecification::default(); let extras = ExtrasSpecification::default();
let upgrade = Upgrade::default(); let upgrade = Upgrade::default();
let resolution_mode = ResolutionMode::default(); let resolution_mode = ResolutionMode::default();
let prerelease_mode = PreReleaseMode::default(); let prerelease_mode = PrereleaseMode::default();
let dependency_mode = DependencyMode::Direct; let dependency_mode = DependencyMode::Direct;
// Read all requirements from the provided sources. // Read all requirements from the provided sources.

View File

@ -312,7 +312,7 @@ async fn do_lock(
if lock.prerelease_mode() != options.prerelease_mode { if lock.prerelease_mode() != options.prerelease_mode {
let _ = writeln!( let _ = writeln!(
printer.stderr(), printer.stderr(),
"Ignoring existing lockfile due to change in prerelease mode: `{}` vs. `{}`", "Ignoring existing lockfile due to change in pre-release mode: `{}` vs. `{}`",
lock.prerelease_mode().cyan(), lock.prerelease_mode().cyan(),
options.prerelease_mode.cyan() options.prerelease_mode.cyan()
); );

View File

@ -26,7 +26,7 @@ use uv_configuration::{
use uv_normalize::PackageName; use uv_normalize::PackageName;
use uv_python::{Prefix, PythonFetch, PythonPreference, PythonVersion, Target}; use uv_python::{Prefix, PythonFetch, PythonPreference, PythonVersion, Target};
use uv_requirements::RequirementsSource; use uv_requirements::RequirementsSource;
use uv_resolver::{AnnotationStyle, DependencyMode, ExcludeNewer, PreReleaseMode, ResolutionMode}; use uv_resolver::{AnnotationStyle, DependencyMode, ExcludeNewer, PrereleaseMode, ResolutionMode};
use uv_settings::{ use uv_settings::{
Combine, FilesystemOptions, Options, PipOptions, ResolverInstallerOptions, ResolverOptions, Combine, FilesystemOptions, Options, PipOptions, ResolverInstallerOptions, ResolverOptions,
}; };
@ -1499,7 +1499,7 @@ pub(crate) struct ResolverSettings {
pub(crate) index_strategy: IndexStrategy, pub(crate) index_strategy: IndexStrategy,
pub(crate) keyring_provider: KeyringProviderType, pub(crate) keyring_provider: KeyringProviderType,
pub(crate) resolution: ResolutionMode, pub(crate) resolution: ResolutionMode,
pub(crate) prerelease: PreReleaseMode, pub(crate) prerelease: PrereleaseMode,
pub(crate) config_setting: ConfigSettings, pub(crate) config_setting: ConfigSettings,
pub(crate) exclude_newer: Option<ExcludeNewer>, pub(crate) exclude_newer: Option<ExcludeNewer>,
pub(crate) link_mode: LinkMode, pub(crate) link_mode: LinkMode,
@ -1513,7 +1513,7 @@ pub(crate) struct ResolverSettingsRef<'a> {
pub(crate) index_strategy: IndexStrategy, pub(crate) index_strategy: IndexStrategy,
pub(crate) keyring_provider: KeyringProviderType, pub(crate) keyring_provider: KeyringProviderType,
pub(crate) resolution: ResolutionMode, pub(crate) resolution: ResolutionMode,
pub(crate) prerelease: PreReleaseMode, pub(crate) prerelease: PrereleaseMode,
pub(crate) config_setting: &'a ConfigSettings, pub(crate) config_setting: &'a ConfigSettings,
pub(crate) exclude_newer: Option<ExcludeNewer>, pub(crate) exclude_newer: Option<ExcludeNewer>,
pub(crate) link_mode: LinkMode, pub(crate) link_mode: LinkMode,
@ -1629,7 +1629,7 @@ pub(crate) struct ResolverInstallerSettings {
pub(crate) index_strategy: IndexStrategy, pub(crate) index_strategy: IndexStrategy,
pub(crate) keyring_provider: KeyringProviderType, pub(crate) keyring_provider: KeyringProviderType,
pub(crate) resolution: ResolutionMode, pub(crate) resolution: ResolutionMode,
pub(crate) prerelease: PreReleaseMode, pub(crate) prerelease: PrereleaseMode,
pub(crate) config_setting: ConfigSettings, pub(crate) config_setting: ConfigSettings,
pub(crate) exclude_newer: Option<ExcludeNewer>, pub(crate) exclude_newer: Option<ExcludeNewer>,
pub(crate) link_mode: LinkMode, pub(crate) link_mode: LinkMode,
@ -1645,7 +1645,7 @@ pub(crate) struct ResolverInstallerSettingsRef<'a> {
pub(crate) index_strategy: IndexStrategy, pub(crate) index_strategy: IndexStrategy,
pub(crate) keyring_provider: KeyringProviderType, pub(crate) keyring_provider: KeyringProviderType,
pub(crate) resolution: ResolutionMode, pub(crate) resolution: ResolutionMode,
pub(crate) prerelease: PreReleaseMode, pub(crate) prerelease: PrereleaseMode,
pub(crate) config_setting: &'a ConfigSettings, pub(crate) config_setting: &'a ConfigSettings,
pub(crate) exclude_newer: Option<ExcludeNewer>, pub(crate) exclude_newer: Option<ExcludeNewer>,
pub(crate) link_mode: LinkMode, pub(crate) link_mode: LinkMode,
@ -1788,7 +1788,7 @@ pub(crate) struct PipSettings {
pub(crate) strict: bool, pub(crate) strict: bool,
pub(crate) dependency_mode: DependencyMode, pub(crate) dependency_mode: DependencyMode,
pub(crate) resolution: ResolutionMode, pub(crate) resolution: ResolutionMode,
pub(crate) prerelease: PreReleaseMode, pub(crate) prerelease: PrereleaseMode,
pub(crate) output_file: Option<PathBuf>, pub(crate) output_file: Option<PathBuf>,
pub(crate) no_strip_extras: bool, pub(crate) no_strip_extras: bool,
pub(crate) no_strip_markers: bool, pub(crate) no_strip_markers: bool,

View File

@ -7523,7 +7523,7 @@ fn universal_nested_disjoint_local_requirement() -> Result<()> {
Ok(()) Ok(())
} }
// Requested distinct prerelease strategies with disjoint markers. /// Requested distinct pre-release strategies with disjoint markers.
#[test] #[test]
fn universal_disjoint_prereleases() -> Result<()> { fn universal_disjoint_prereleases() -> Result<()> {
static EXCLUDE_NEWER: &str = "2024-07-17T00:00:00Z"; static EXCLUDE_NEWER: &str = "2024-07-17T00:00:00Z";
@ -7559,8 +7559,8 @@ fn universal_disjoint_prereleases() -> Result<()> {
Ok(()) Ok(())
} }
// Requested distinct prerelease strategies with disjoint markers for a package /// Requested distinct pre-release strategies with disjoint markers for a package
// that is also present as a transitive dependency. /// that is also present as a transitive dependency.
#[test] #[test]
fn universal_transitive_disjoint_prerelease_requirement() -> Result<()> { fn universal_transitive_disjoint_prerelease_requirement() -> Result<()> {
static EXCLUDE_NEWER: &str = "2024-07-17T00:00:00Z"; static EXCLUDE_NEWER: &str = "2024-07-17T00:00:00Z";
@ -7603,7 +7603,7 @@ fn universal_transitive_disjoint_prerelease_requirement() -> Result<()> {
Ok(()) Ok(())
} }
// Ensure that the global prerelease mode is respected across forks. /// Ensure that the global pre-release mode is respected across forks.
#[test] #[test]
fn universal_prerelease_mode() -> Result<()> { fn universal_prerelease_mode() -> Result<()> {
static EXCLUDE_NEWER: &str = "2024-07-17T00:00:00Z"; static EXCLUDE_NEWER: &str = "2024-07-17T00:00:00Z";
@ -7638,8 +7638,8 @@ fn universal_prerelease_mode() -> Result<()> {
Ok(()) Ok(())
} }
/// If a dependency requests a prerelease version with an overlapping marker expression, /// If a dependency requests a pre-release version with an overlapping marker expression,
/// we should prefer the prerelease version in both forks. /// we should prefer the pre-release version in both forks.
#[test] #[test]
fn universal_overlapping_prerelease_requirement() -> Result<()> { fn universal_overlapping_prerelease_requirement() -> Result<()> {
static EXCLUDE_NEWER: &str = "2024-07-17T00:00:00Z"; static EXCLUDE_NEWER: &str = "2024-07-17T00:00:00Z";
@ -7689,7 +7689,7 @@ fn universal_overlapping_prerelease_requirement() -> Result<()> {
Ok(()) Ok(())
} }
/// If a dependency requests distinct prerelease strategies with disjoint marker expressions, /// If a dependency requests distinct pre-release strategies with disjoint marker expressions,
/// we should fork the root requirement. /// we should fork the root requirement.
#[test] #[test]
fn universal_disjoint_prerelease_requirement() -> Result<()> { fn universal_disjoint_prerelease_requirement() -> Result<()> {
@ -7716,7 +7716,7 @@ fn universal_disjoint_prerelease_requirement() -> Result<()> {
"})?; "})?;
// Some marker expressions on the output here are missing due to https://github.com/astral-sh/uv/issues/5086, // Some marker expressions on the output here are missing due to https://github.com/astral-sh/uv/issues/5086,
// but the prerelease versions are still respected correctly. // but the pre-release versions are still respected correctly.
uv_snapshot!(context.filters(), windows_filters=false, context.pip_compile() uv_snapshot!(context.filters(), windows_filters=false, context.pip_compile()
.env("UV_EXCLUDE_NEWER", EXCLUDE_NEWER) .env("UV_EXCLUDE_NEWER", EXCLUDE_NEWER)
.arg("requirements.in") .arg("requirements.in")
@ -8418,7 +8418,7 @@ fn unsafe_package() -> Result<()> {
/// Resolve a package with a strict upper bound, allowing pre-releases. Per PEP 440, pre-releases /// Resolve a package with a strict upper bound, allowing pre-releases. Per PEP 440, pre-releases
/// that match the bound (e.g., `2.0.0rc1`) should be _not_ allowed. /// that match the bound (e.g., `2.0.0rc1`) should be _not_ allowed.
#[test] #[test]
fn pre_release_upper_bound_exclude() -> Result<()> { fn prerelease_upper_bound_exclude() -> Result<()> {
let context = TestContext::new("3.12"); let context = TestContext::new("3.12");
let requirements_in = context.temp_dir.child("requirements.in"); let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("flask<2.0.0")?; requirements_in.write_str("flask<2.0.0")?;
@ -8455,7 +8455,7 @@ fn pre_release_upper_bound_exclude() -> Result<()> {
/// Resolve a package with a strict upper bound that includes a pre-release. Per PEP 440, /// Resolve a package with a strict upper bound that includes a pre-release. Per PEP 440,
/// pre-releases _should_ be allowed. /// pre-releases _should_ be allowed.
#[test] #[test]
fn pre_release_upper_bound_include() -> Result<()> { fn prerelease_upper_bound_include() -> Result<()> {
let context = TestContext::new("3.12"); let context = TestContext::new("3.12");
let requirements_in = context.temp_dir.child("requirements.in"); let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("flask<2.0.0rc4")?; requirements_in.write_str("flask<2.0.0rc4")?;
@ -8529,7 +8529,7 @@ fn pre_alias() -> Result<()> {
/// Allow a pre-release for a version specifier in a constraint file. /// Allow a pre-release for a version specifier in a constraint file.
#[test] #[test]
fn pre_release_constraint() -> Result<()> { fn prerelease_constraint() -> Result<()> {
let context = TestContext::new("3.12"); let context = TestContext::new("3.12");
let requirements_in = context.temp_dir.child("requirements.in"); let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("flask")?; requirements_in.write_str("flask")?;
@ -10349,7 +10349,7 @@ requires-python = ">3.8"
/// Allow pre-releases for dependencies of source path requirements. /// Allow pre-releases for dependencies of source path requirements.
#[test] #[test]
fn pre_release_path_requirement() -> Result<()> { fn prerelease_path_requirement() -> Result<()> {
let context = TestContext::new("3.12"); let context = TestContext::new("3.12");
// Create an a package that requires a pre-release version of `flask`. // Create an a package that requires a pre-release version of `flask`.
@ -10403,7 +10403,7 @@ requires-python = ">3.8"
/// Allow pre-releases for dependencies of editable requirements. /// Allow pre-releases for dependencies of editable requirements.
#[test] #[test]
fn pre_release_editable_requirement() -> Result<()> { fn prerelease_editable_requirement() -> Result<()> {
let context = TestContext::new("3.12"); let context = TestContext::new("3.12");
// Create an a package that requires a pre-release version of `flask`.r // Create an a package that requires a pre-release version of `flask`.r

6
uv.schema.json generated
View File

@ -216,7 +216,7 @@
"description": "The strategy to use when considering pre-release versions.\n\nBy default, uv will accept pre-releases for packages that _only_ publish pre-releases, along with first-party requirements that contain an explicit pre-release marker in the declared specifiers (`if-necessary-or-explicit`).", "description": "The strategy to use when considering pre-release versions.\n\nBy default, uv will accept pre-releases for packages that _only_ publish pre-releases, along with first-party requirements that contain an explicit pre-release marker in the declared specifiers (`if-necessary-or-explicit`).",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/PreReleaseMode" "$ref": "#/definitions/PrereleaseMode"
}, },
{ {
"type": "null" "type": "null"
@ -808,7 +808,7 @@
"description": "The strategy to use when considering pre-release versions.\n\nBy default, uv will accept pre-releases for packages that _only_ publish pre-releases, along with first-party requirements that contain an explicit pre-release marker in the declared specifiers (`if-necessary-or-explicit`).", "description": "The strategy to use when considering pre-release versions.\n\nBy default, uv will accept pre-releases for packages that _only_ publish pre-releases, along with first-party requirements that contain an explicit pre-release marker in the declared specifiers (`if-necessary-or-explicit`).",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/PreReleaseMode" "$ref": "#/definitions/PrereleaseMode"
}, },
{ {
"type": "null" "type": "null"
@ -934,7 +934,7 @@
}, },
"additionalProperties": false "additionalProperties": false
}, },
"PreReleaseMode": { "PrereleaseMode": {
"oneOf": [ "oneOf": [
{ {
"description": "Disallow all pre-release versions.", "description": "Disallow all pre-release versions.",