Include pre-release Python versions in uv python list (#7290)

Follows https://github.com/astral-sh/uv/pull/7278

Closes https://github.com/astral-sh/uv/issues/7280

`uv python list` should show installed pre-release versions, even though
we don't select them by default (as defined by #7300 and
https://github.com/astral-sh/uv/pull/7278)
This commit is contained in:
Zanie Blue 2024-09-11 14:46:16 -05:00 committed by GitHub
parent ebd73d83f8
commit c50eb12c51
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 27 additions and 8 deletions

View file

@ -96,6 +96,10 @@ pub struct PythonDownloadRequest {
arch: Option<Arch>, arch: Option<Arch>,
os: Option<Os>, os: Option<Os>,
libc: Option<Libc>, libc: Option<Libc>,
/// Whether to allow pre-releases or not. If not set, defaults to true if [`Self::version`] is
/// not None, and false otherwise.
prereleases: Option<bool>,
} }
impl PythonDownloadRequest { impl PythonDownloadRequest {
@ -105,6 +109,7 @@ impl PythonDownloadRequest {
arch: Option<Arch>, arch: Option<Arch>,
os: Option<Os>, os: Option<Os>,
libc: Option<Libc>, libc: Option<Libc>,
prereleases: Option<bool>,
) -> Self { ) -> Self {
Self { Self {
version, version,
@ -112,6 +117,7 @@ impl PythonDownloadRequest {
arch, arch,
os, os,
libc, libc,
prereleases,
} }
} }
@ -145,6 +151,12 @@ impl PythonDownloadRequest {
self self
} }
#[must_use]
pub fn with_prereleases(mut self, prereleases: bool) -> Self {
self.prereleases = Some(prereleases);
self
}
/// Construct a new [`PythonDownloadRequest`] from a [`PythonRequest`] if possible. /// Construct a new [`PythonDownloadRequest`] from a [`PythonRequest`] if possible.
/// ///
/// Returns [`None`] if the request kind is not compatible with a download, e.g., it is /// Returns [`None`] if the request kind is not compatible with a download, e.g., it is
@ -196,6 +208,7 @@ impl PythonDownloadRequest {
Some(Arch::from_env()), Some(Arch::from_env()),
Some(Os::from_env()), Some(Os::from_env()),
Some(Libc::from_env()?), Some(Libc::from_env()?),
None,
)) ))
} }
@ -252,20 +265,22 @@ impl PythonDownloadRequest {
return false; return false;
} }
} }
// If we don't allow pre-releases, don't match a key with a pre-release tag
if !self.allows_prereleases() && !key.prerelease.is_empty() {
return false;
}
true true
} }
/// Whether this request is satisfied by a Python download. /// Whether this request is satisfied by a Python download.
///
/// Note that unlike [`Self::satisfied_by_key`], this method will not match a pre-release
/// unless a version is included in the request.
pub fn satisfied_by_download(&self, download: &ManagedPythonDownload) -> bool { pub fn satisfied_by_download(&self, download: &ManagedPythonDownload) -> bool {
if self.version.is_none() && !download.key().prerelease.is_empty() {
return false;
}
self.satisfied_by_key(download.key()) self.satisfied_by_key(download.key())
} }
pub fn allows_prereleases(&self) -> bool {
self.prereleases.unwrap_or_else(|| self.version.is_some())
}
pub fn satisfied_by_interpreter(&self, interpreter: &Interpreter) -> bool { pub fn satisfied_by_interpreter(&self, interpreter: &Interpreter) -> bool {
if let Some(version) = self.version() { if let Some(version) = self.version() {
if !version.matches_interpreter(interpreter) { if !version.matches_interpreter(interpreter) {
@ -375,7 +390,7 @@ impl FromStr for PythonDownloadRequest {
return Err(Error::TooManyParts(s.to_string())); return Err(Error::TooManyParts(s.to_string()));
} }
Ok(Self::new(version, implementation, arch, os, libc)) Ok(Self::new(version, implementation, arch, os, libc, None))
} }
} }

View file

@ -50,7 +50,9 @@ pub(crate) async fn list(
None None
} }
} }
}; }
// Include pre-release versions
.map(|request| request.with_prereleases(true));
let downloads = download_request let downloads = download_request
.as_ref() .as_ref()

View file

@ -75,6 +75,8 @@ async fn do_uninstall(
anyhow::anyhow!("Cannot uninstall managed Python for request: {request}") anyhow::anyhow!("Cannot uninstall managed Python for request: {request}")
}) })
}) })
// Always include pre-releases in uninstalls
.map(|result| result.map(|request| request.with_prereleases(true)))
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;
let installed_installations: Vec<_> = installations.find_all()?.collect(); let installed_installations: Vec<_> = installations.find_all()?.collect();