Respect --isolated in uv python install (#4938)

We ignore Python version files when `--isolated` is used, logging that
we skipped them if they exist.
This commit is contained in:
Zanie Blue 2024-07-10 11:36:25 -04:00 committed by GitHub
parent acfb57b072
commit a4044be95b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 41 additions and 18 deletions

View file

@ -13,9 +13,11 @@ pub use crate::pointer_size::PointerSize;
pub use crate::prefix::Prefix; pub use crate::prefix::Prefix;
pub use crate::python_version::PythonVersion; pub use crate::python_version::PythonVersion;
pub use crate::target::Target; pub use crate::target::Target;
pub use crate::version_files::{request_from_version_file, requests_from_version_file}; pub use crate::version_files::{
request_from_version_file, requests_from_version_file, version_file_exists,
versions_file_exists, PYTHON_VERSIONS_FILENAME, PYTHON_VERSION_FILENAME,
};
pub use crate::virtualenv::{Error as VirtualEnvError, PyVenvConfiguration, VirtualEnvironment}; pub use crate::virtualenv::{Error as VirtualEnvError, PyVenvConfiguration, VirtualEnvironment};
mod discovery; mod discovery;
pub mod downloads; pub mod downloads;
mod environment; mod environment;

View file

@ -4,6 +4,12 @@ use tracing::debug;
use crate::PythonRequest; use crate::PythonRequest;
/// The file name for Python version pins.
pub static PYTHON_VERSION_FILENAME: &str = ".python-version";
/// The file name for multiple Python version declarations.
pub static PYTHON_VERSIONS_FILENAME: &str = ".python-versions";
/// Read [`PythonRequest`]s from a version file, if present. /// Read [`PythonRequest`]s from a version file, if present.
/// ///
/// Prefers `.python-versions` then `.python-version`. /// Prefers `.python-versions` then `.python-version`.
@ -41,12 +47,16 @@ pub async fn request_from_version_file() -> Result<Option<PythonRequest>, io::Er
} }
} }
pub fn versions_file_exists() -> Result<bool, io::Error> {
PathBuf::from(PYTHON_VERSIONS_FILENAME).try_exists()
}
async fn read_versions_file() -> Result<Option<Vec<String>>, io::Error> { async fn read_versions_file() -> Result<Option<Vec<String>>, io::Error> {
if !PathBuf::from(".python-versions").try_exists()? { if !versions_file_exists()? {
return Ok(None); return Ok(None);
} }
debug!("Reading requests from `.python-versions`"); debug!("Reading requests from `{PYTHON_VERSIONS_FILENAME}`");
let lines: Vec<String> = fs::tokio::read_to_string(".python-versions") let lines: Vec<String> = fs::tokio::read_to_string(PYTHON_VERSIONS_FILENAME)
.await? .await?
.lines() .lines()
.map(ToString::to_string) .map(ToString::to_string)
@ -54,12 +64,16 @@ async fn read_versions_file() -> Result<Option<Vec<String>>, io::Error> {
Ok(Some(lines)) Ok(Some(lines))
} }
pub fn version_file_exists() -> Result<bool, io::Error> {
PathBuf::from(PYTHON_VERSION_FILENAME).try_exists()
}
async fn read_version_file() -> Result<Option<String>, io::Error> { async fn read_version_file() -> Result<Option<String>, io::Error> {
if !PathBuf::from(".python-version").try_exists()? { if !version_file_exists()? {
return Ok(None); return Ok(None);
} }
debug!("Reading requests from `.python-version`"); debug!("Reading requests from `{PYTHON_VERSION_FILENAME}`");
Ok(fs::tokio::read_to_string(".python-version") Ok(fs::tokio::read_to_string(PYTHON_VERSION_FILENAME)
.await? .await?
.lines() .lines()
.next() .next()

View file

@ -1,18 +1,22 @@
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::fmt::Write; use std::fmt::Write;
use std::path::PathBuf;
use anyhow::Result; use anyhow::Result;
use fs_err as fs; use fs_err as fs;
use futures::StreamExt; use futures::StreamExt;
use itertools::Itertools; use itertools::Itertools;
use owo_colors::OwoColorize; use owo_colors::OwoColorize;
use tracing::debug;
use uv_cache::Cache; use uv_cache::Cache;
use uv_client::Connectivity; use uv_client::Connectivity;
use uv_configuration::PreviewMode; use uv_configuration::PreviewMode;
use uv_fs::Simplified; use uv_fs::Simplified;
use uv_python::downloads::{self, DownloadResult, ManagedPythonDownload, PythonDownloadRequest}; use uv_python::downloads::{self, DownloadResult, ManagedPythonDownload, PythonDownloadRequest};
use uv_python::managed::{ManagedPythonInstallation, ManagedPythonInstallations}; use uv_python::managed::{ManagedPythonInstallation, ManagedPythonInstallations};
use uv_python::{requests_from_version_file, PythonRequest}; use uv_python::{
requests_from_version_file, PythonRequest, PYTHON_VERSIONS_FILENAME, PYTHON_VERSION_FILENAME,
};
use uv_warnings::warn_user_once; use uv_warnings::warn_user_once;
use crate::commands::reporters::PythonDownloadReporter; use crate::commands::reporters::PythonDownloadReporter;
@ -43,15 +47,17 @@ pub(crate) async fn install(
let targets = targets.into_iter().collect::<BTreeSet<_>>(); let targets = targets.into_iter().collect::<BTreeSet<_>>();
let requests: Vec<_> = if targets.is_empty() { let requests: Vec<_> = if targets.is_empty() {
// Read from the version file, unless `isolated` was requested // Read from the version file, unless `isolated` was requested
if let Some(requests) = if isolated { let version_file_requests = if isolated {
if PathBuf::from(PYTHON_VERSION_FILENAME).exists() {
debug!("Ignoring `.python-version` file due to isolated mode");
} else if PathBuf::from(PYTHON_VERSIONS_FILENAME).exists() {
debug!("Ignoring `.python-versions` file due to isolated mode");
}
None None
} else { } else {
requests_from_version_file().await? requests_from_version_file().await?
} { };
requests version_file_requests.unwrap_or_else(|| vec![PythonRequest::Any])
} else {
vec![PythonRequest::Any]
}
} else { } else {
targets targets
.iter() .iter()

View file

@ -3,6 +3,7 @@
use anyhow::Result; use anyhow::Result;
use assert_cmd::prelude::*; use assert_cmd::prelude::*;
use assert_fs::prelude::*; use assert_fs::prelude::*;
use uv_python::{PYTHON_VERSIONS_FILENAME, PYTHON_VERSION_FILENAME};
use crate::common::{uv_snapshot, TestContext}; use crate::common::{uv_snapshot, TestContext};
@ -109,7 +110,7 @@ fn create_venv_reads_request_from_python_version_file() {
// With a version file, we should prefer that version // With a version file, we should prefer that version
context context
.temp_dir .temp_dir
.child(".python-version") .child(PYTHON_VERSION_FILENAME)
.write_str("3.12") .write_str("3.12")
.unwrap(); .unwrap();
@ -150,7 +151,7 @@ fn create_venv_reads_request_from_python_versions_file() {
// With a versions file, we should prefer the first listed version // With a versions file, we should prefer the first listed version
context context
.temp_dir .temp_dir
.child(".python-versions") .child(PYTHON_VERSIONS_FILENAME)
.write_str("3.12\n3.11") .write_str("3.12\n3.11")
.unwrap(); .unwrap();
@ -176,7 +177,7 @@ fn create_venv_explicit_request_takes_priority_over_python_version_file() {
context context
.temp_dir .temp_dir
.child(".python-version") .child(PYTHON_VERSION_FILENAME)
.write_str("3.12") .write_str("3.12")
.unwrap(); .unwrap();