From a4044be95bc9d73c9384dc7946193fb003c70562 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 10 Jul 2024 11:36:25 -0400 Subject: [PATCH] Respect `--isolated` in `uv python install` (#4938) We ignore Python version files when `--isolated` is used, logging that we skipped them if they exist. --- crates/uv-python/src/lib.rs | 6 ++++-- crates/uv-python/src/version_files.rs | 26 ++++++++++++++++++------ crates/uv/src/commands/python/install.rs | 20 +++++++++++------- crates/uv/tests/venv.rs | 7 ++++--- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/crates/uv-python/src/lib.rs b/crates/uv-python/src/lib.rs index 25f05a5931d1..025f87d03b03 100644 --- a/crates/uv-python/src/lib.rs +++ b/crates/uv-python/src/lib.rs @@ -13,9 +13,11 @@ pub use crate::pointer_size::PointerSize; pub use crate::prefix::Prefix; pub use crate::python_version::PythonVersion; 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}; - mod discovery; pub mod downloads; mod environment; diff --git a/crates/uv-python/src/version_files.rs b/crates/uv-python/src/version_files.rs index 0a245be185dd..7a8d82a91bb2 100644 --- a/crates/uv-python/src/version_files.rs +++ b/crates/uv-python/src/version_files.rs @@ -4,6 +4,12 @@ use tracing::debug; 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. /// /// Prefers `.python-versions` then `.python-version`. @@ -41,12 +47,16 @@ pub async fn request_from_version_file() -> Result, io::Er } } +pub fn versions_file_exists() -> Result { + PathBuf::from(PYTHON_VERSIONS_FILENAME).try_exists() +} + async fn read_versions_file() -> Result>, io::Error> { - if !PathBuf::from(".python-versions").try_exists()? { + if !versions_file_exists()? { return Ok(None); } - debug!("Reading requests from `.python-versions`"); - let lines: Vec = fs::tokio::read_to_string(".python-versions") + debug!("Reading requests from `{PYTHON_VERSIONS_FILENAME}`"); + let lines: Vec = fs::tokio::read_to_string(PYTHON_VERSIONS_FILENAME) .await? .lines() .map(ToString::to_string) @@ -54,12 +64,16 @@ async fn read_versions_file() -> Result>, io::Error> { Ok(Some(lines)) } +pub fn version_file_exists() -> Result { + PathBuf::from(PYTHON_VERSION_FILENAME).try_exists() +} + async fn read_version_file() -> Result, io::Error> { - if !PathBuf::from(".python-version").try_exists()? { + if !version_file_exists()? { return Ok(None); } - debug!("Reading requests from `.python-version`"); - Ok(fs::tokio::read_to_string(".python-version") + debug!("Reading requests from `{PYTHON_VERSION_FILENAME}`"); + Ok(fs::tokio::read_to_string(PYTHON_VERSION_FILENAME) .await? .lines() .next() diff --git a/crates/uv/src/commands/python/install.rs b/crates/uv/src/commands/python/install.rs index c23a239f6b23..26519a97f091 100644 --- a/crates/uv/src/commands/python/install.rs +++ b/crates/uv/src/commands/python/install.rs @@ -1,18 +1,22 @@ use std::collections::BTreeSet; use std::fmt::Write; +use std::path::PathBuf; use anyhow::Result; use fs_err as fs; use futures::StreamExt; use itertools::Itertools; use owo_colors::OwoColorize; +use tracing::debug; use uv_cache::Cache; use uv_client::Connectivity; use uv_configuration::PreviewMode; use uv_fs::Simplified; use uv_python::downloads::{self, DownloadResult, ManagedPythonDownload, PythonDownloadRequest}; 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 crate::commands::reporters::PythonDownloadReporter; @@ -43,15 +47,17 @@ pub(crate) async fn install( let targets = targets.into_iter().collect::>(); let requests: Vec<_> = if targets.is_empty() { // 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 } else { requests_from_version_file().await? - } { - requests - } else { - vec![PythonRequest::Any] - } + }; + version_file_requests.unwrap_or_else(|| vec![PythonRequest::Any]) } else { targets .iter() diff --git a/crates/uv/tests/venv.rs b/crates/uv/tests/venv.rs index 6624c73c08a0..0f6a19163f48 100644 --- a/crates/uv/tests/venv.rs +++ b/crates/uv/tests/venv.rs @@ -3,6 +3,7 @@ use anyhow::Result; use assert_cmd::prelude::*; use assert_fs::prelude::*; +use uv_python::{PYTHON_VERSIONS_FILENAME, PYTHON_VERSION_FILENAME}; 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 context .temp_dir - .child(".python-version") + .child(PYTHON_VERSION_FILENAME) .write_str("3.12") .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 context .temp_dir - .child(".python-versions") + .child(PYTHON_VERSIONS_FILENAME) .write_str("3.12\n3.11") .unwrap(); @@ -176,7 +177,7 @@ fn create_venv_explicit_request_takes_priority_over_python_version_file() { context .temp_dir - .child(".python-version") + .child(PYTHON_VERSION_FILENAME) .write_str("3.12") .unwrap();