From 10b13f04105caca2dbb2784122a001e5d67fa5ee Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Mon, 17 Jun 2024 16:03:48 -0500 Subject: [PATCH 1/2] Move virtual environment test context into main context --- .github/workflows/ci.yml | 2 +- crates/uv/tests/common/mod.rs | 270 +++++++++++++++-------------- crates/uv/tests/pip_compile.rs | 15 +- crates/uv/tests/pip_install.rs | 6 +- crates/uv/tests/run.rs | 2 + crates/uv/tests/venv.rs | 299 +++++++++++---------------------- 6 files changed, 252 insertions(+), 342 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fa0ecdbc155f..83af129b7ad9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -168,7 +168,7 @@ jobs: steps: - name: Create Dev Drive using ReFS run: | - $Volume = New-VHD -Path C:/uv_dev_drive.vhdx -SizeBytes 10GB | + $Volume = New-VHD -Path C:/uv_dev_drive.vhdx -SizeBytes 12GB | Mount-VHD -Passthru | Initialize-Disk -Passthru | New-Partition -AssignDriveLetter -UseMaximumSize | diff --git a/crates/uv/tests/common/mod.rs b/crates/uv/tests/common/mod.rs index bf7e6c1f3922..38e82fd39940 100644 --- a/crates/uv/tests/common/mod.rs +++ b/crates/uv/tests/common/mod.rs @@ -5,9 +5,9 @@ use assert_cmd::assert::{Assert, OutputAssertExt}; use assert_cmd::Command; use assert_fs::assert::PathAssert; use assert_fs::fixture::{ChildPath, PathChild}; +use predicates::prelude::predicate; use regex::Regex; use std::borrow::BorrowMut; -use std::collections::VecDeque; use std::env; use std::ffi::OsString; use std::iter::Iterator; @@ -54,28 +54,52 @@ pub const INSTA_FILTERS: &[(&str, &str)] = &[ /// * Set the current directory to a temporary directory (`temp_dir`). /// * Set the cache dir to a different temporary directory (`cache_dir`). /// * Set a cutoff for versions used in the resolution so the snapshots don't change after a new release. -/// * Set the venv to a fresh `.venv` in `temp_dir`. -#[derive(Debug)] +/// * Set the venv to a fresh `.venv` in `temp_dir` pub struct TestContext { pub temp_dir: assert_fs::TempDir, pub cache_dir: assert_fs::TempDir, - pub venv: PathBuf, - pub python_version: String, + pub venv: ChildPath, pub workspace_root: PathBuf, - // Additional Python versions - python_versions: Vec<(PythonVersion, PathBuf)>, + /// The Python version used for the virtual environment, if any. + pub python_version: Option, + + // All the Python versions available during this test context. + pub python_versions: Vec<(PythonVersion, PathBuf)>, // Standard filters for this test context - filters: VecDeque<(String, String)>, + filters: Vec<(String, String)>, } impl TestContext { + /// Create a new test context with a virtual environment. + /// + /// See [`TestContext::new_with_versions`] if multiple versions are needed or + /// if creation of the virtual environment should be deferred. pub fn new(python_version: &str) -> Self { + let new = Self::new_with_versions(&[python_version]); + new.create_venv(); + new + } + + /// Create a new test context with multiple Python versions. + /// + /// Does not create a virtual environment by default, but the first Python version + /// can be used to create a virtual environment with [`TestContext::create_venv`]. + /// + /// See [`TestContext::new`] if only a single version is desired. + pub fn new_with_versions(python_versions: &[&str]) -> Self { let temp_dir = assert_fs::TempDir::new().expect("Failed to create temp dir"); let cache_dir = assert_fs::TempDir::new().expect("Failed to create cache dir"); - let python = get_toolchain(python_version); - let venv = create_venv_from_executable(&temp_dir, &cache_dir, &python); + + let venv = temp_dir.child(".venv"); + let python_version = python_versions + .first() + .map(|version| PythonVersion::from_str(version).unwrap()); + + let site_packages = python_version + .as_ref() + .map(|version| site_packages_path(&venv, &format!("python{version}"))); // The workspace root directory is not available without walking up the tree // https://github.com/rust-lang/cargo/issues/3946 @@ -86,28 +110,51 @@ impl TestContext { .expect("CARGO_MANIFEST_DIR should be doubly nested in workspace") .to_path_buf(); - let site_packages = site_packages_path(&venv, &format!("python{python_version}")); - - let python_version = - PythonVersion::from_str(python_version).expect("Tests must use valid Python versions"); + let python_versions: Vec<_> = python_versions + .iter() + .map(|version| PythonVersion::from_str(version).unwrap()) + .zip( + python_toolchains_for_versions(&temp_dir, python_versions) + .expect("Failed to find test Python versions"), + ) + .collect(); - let mut filters = VecDeque::new(); + let mut filters = Vec::new(); filters.extend( Self::path_patterns(&cache_dir) .into_iter() .map(|pattern| (pattern, "[CACHE_DIR]/".to_string())), ); - filters.extend( - Self::path_patterns(&site_packages) - .into_iter() - .map(|pattern| (pattern, "[SITE_PACKAGES]/".to_string())), - ); + if let Some(ref site_packages) = site_packages { + filters.extend( + Self::path_patterns(site_packages) + .into_iter() + .map(|pattern| (pattern, "[SITE_PACKAGES]/".to_string())), + ); + } filters.extend( Self::path_patterns(&venv) .into_iter() .map(|pattern| (pattern, "[VENV]/".to_string())), ); + for (version, executable) in &python_versions { + // Add filtering for the interpreter path + filters.extend( + Self::path_patterns(executable) + .into_iter() + .map(|pattern| (format!("{pattern}python.*"), format!("[PYTHON-{version}]"))), + ); + + // Add Python patch version filtering unless explicitly requested to ensure + // snapshots are patch version agnostic when it is not a part of the test. + if version.patch().is_none() { + filters.push(( + format!(r"({})\.\d+", regex::escape(version.to_string().as_str())), + "$1.[X]".to_string(), + )); + } + } filters.extend( Self::path_patterns(&temp_dir) .into_iter() @@ -119,16 +166,24 @@ impl TestContext { .map(|pattern| (pattern, "[WORKSPACE]/".to_string())), ); - // Account for [`Simplified::user_display`] which is relative to the command working directory - filters.push_back(( - Self::path_pattern( - site_packages - .strip_prefix(&temp_dir) - .expect("The test site-packages directory is always in the tempdir"), - ), - "[SITE_PACKAGES]/".to_string(), + // Make virtual environment activation cross-platform + filters.push(( + r"Activate with: (?:.*)\\Scripts\\activate".to_string(), + "Activate with: source .venv/bin/activate".to_string(), )); - filters.push_back(( + + // Account for [`Simplified::user_display`] which is relative to the command working directory + if let Some(site_packages) = site_packages { + filters.push(( + Self::path_pattern( + site_packages + .strip_prefix(&temp_dir) + .expect("The test site-packages directory is always in the tempdir"), + ), + "[SITE_PACKAGES]/".to_string(), + )); + }; + filters.push(( Self::path_pattern( venv.strip_prefix(&temp_dir) .expect("The test virtual environment directory is always in the tempdir"), @@ -138,67 +193,22 @@ impl TestContext { // Filter non-deterministic temporary directory names // Note we apply this _after_ all the full paths to avoid breaking their matching - filters.push_back((r"(\\|\/)\.tmp.*(\\|\/)".to_string(), "/[TMP]/".to_string())); + filters.push((r"(\\|\/)\.tmp.*(\\|\/)".to_string(), "/[TMP]/".to_string())); // Account for platform prefix differences `file://` (Unix) vs `file:///` (Windows) - filters.push_back((r"file:///".to_string(), "file://".to_string())); + filters.push((r"file:///".to_string(), "file://".to_string())); // Destroy any remaining UNC prefixes (Windows only) - filters.push_back((r"\\\\\?\\".to_string(), String::new())); + filters.push((r"\\\\\?\\".to_string(), String::new())); - let mut result = Self { + Self { temp_dir, cache_dir, venv, - python_version: python_version.to_string(), - filters, - python_versions: Vec::new(), workspace_root, - }; - - result.add_filters_for_python_version(&python_version, python); - - result - } - - pub fn new_with_versions(python_versions: &[&str]) -> Self { - let mut context = Self::new( - python_versions - .first() - .expect("At least one test Python version must be provided"), - ); - - let python_versions: Vec<_> = python_versions - .iter() - .map(|version| PythonVersion::from_str(version).unwrap()) - .zip( - python_toolchains_for_versions(&context.temp_dir, python_versions) - .expect("Failed to find test Python versions"), - ) - .collect(); - - for (version, path) in &python_versions { - context.add_filters_for_python_version(version, path.clone()); - } - - context.python_versions = python_versions; - - context - } - - fn add_filters_for_python_version(&mut self, version: &PythonVersion, executable: PathBuf) { - // Add filtering for the interpreter path - for pattern in Self::path_patterns(executable) { - self.filters - .push_front((format!("{pattern}python.*"), format!("[PYTHON-{version}]"))); - } - // Add Python patch version filtering unless explicitly requested to ensure - // snapshots are patch version agnostic when it is not a part of the test. - if version.patch().is_none() { - self.filters.push_back(( - format!(r"({})\.\d+", regex::escape(version.to_string().as_str())), - "$1.[X]".to_string(), - )); + python_version, + python_versions, + filters, } } @@ -223,6 +233,7 @@ impl TestContext { .arg(self.cache_dir.path()) .env("VIRTUAL_ENV", self.venv.as_os_str()) .env("UV_NO_WRAP", "1") + .env("UV_TOOLCHAIN_DIR", "") .env("UV_TEST_PYTHON_PATH", &self.python_path()) .current_dir(self.temp_dir.path()); @@ -235,6 +246,22 @@ impl TestContext { cmd } + /// Create a `uv venv` command + pub fn venv(&self) -> std::process::Command { + let mut command = std::process::Command::new(get_bin()); + command + .arg("venv") + .arg("--exclude-newer") + .arg(EXCLUDE_NEWER) + .env("UV_CACHE_DIR", self.cache_dir.path()) + .env("UV_TOOLCHAIN_DIR", "") + .env("UV_TEST_PYTHON_PATH", &self.python_path()) + .env("UV_NO_WRAP", "1") + .env("UV_STACK_SIZE", (2 * 1024 * 1024).to_string()) + .current_dir(self.temp_dir.as_os_str()); + command + } + /// Create a `pip install` command with options shared across scenarios. pub fn install(&self) -> std::process::Command { let mut command = self.install_without_exclude_newer(); @@ -257,6 +284,7 @@ impl TestContext { .arg(self.cache_dir.path()) .env("VIRTUAL_ENV", self.venv.as_os_str()) .env("UV_NO_WRAP", "1") + .env("UV_TOOLCHAIN_DIR", "") .env("UV_TEST_PYTHON_PATH", &self.python_path()) .current_dir(&self.temp_dir); @@ -277,8 +305,10 @@ impl TestContext { .arg("--cache-dir") .arg(self.cache_dir.path()) .env("VIRTUAL_ENV", self.venv.as_os_str()) + .env("UV_TOOLCHAIN_DIR", "") .env("UV_TEST_PYTHON_PATH", &self.python_path()) .env("UV_NO_WRAP", "1") + .env("UV_TOOLCHAIN_DIR", "") .env("UV_TEST_PYTHON_PATH", &self.python_path()) .current_dir(&self.temp_dir); @@ -297,6 +327,7 @@ impl TestContext { command .arg("--exclude-newer") .arg(EXCLUDE_NEWER) + .env("UV_TOOLCHAIN_DIR", "") .env("UV_TEST_PYTHON_PATH", &self.python_path()); command } @@ -315,6 +346,7 @@ impl TestContext { .arg(self.cache_dir.path()) .env("VIRTUAL_ENV", self.venv.as_os_str()) .env("UV_NO_WRAP", "1") + .env("UV_TOOLCHAIN_DIR", "") .env("UV_TEST_PYTHON_PATH", &self.python_path()) .current_dir(&self.temp_dir); @@ -327,10 +359,6 @@ impl TestContext { command } - pub fn toolchains_dir(&self) -> ChildPath { - self.temp_dir.child("toolchains") - } - /// Create a `uv toolchain find` command with options shared across scenarios. pub fn toolchain_find(&self) -> std::process::Command { let mut command = std::process::Command::new(get_bin()); @@ -341,9 +369,10 @@ impl TestContext { .arg(self.cache_dir.path()) .env("VIRTUAL_ENV", self.venv.as_os_str()) .env("UV_NO_WRAP", "1") + .env("UV_TOOLCHAIN_DIR", "") .env("UV_TEST_PYTHON_PATH", &self.python_path()) .env("UV_PREVIEW", "1") - .env("UV_TOOLCHAIN_DIR", self.toolchains_dir().as_os_str()) + .env("UV_TOOLCHAIN_DIR", "") .current_dir(&self.temp_dir); if cfg!(all(windows, debug_assertions)) { @@ -376,6 +405,7 @@ impl TestContext { .arg(self.cache_dir.path()) .env("VIRTUAL_ENV", self.venv.as_os_str()) .env("UV_NO_WRAP", "1") + .env("UV_TOOLCHAIN_DIR", "") .env("UV_TEST_PYTHON_PATH", &self.python_path()) .current_dir(&self.temp_dir); @@ -497,7 +527,7 @@ impl TestContext { ) } - fn python_path(&self) -> OsString { + pub fn python_path(&self) -> OsString { std::env::join_paths(self.python_versions.iter().map(|(_, path)| path)).unwrap() } @@ -522,33 +552,29 @@ impl TestContext { pub fn site_packages(&self) -> PathBuf { site_packages_path( &self.venv, - &format!("{}{}", self.python_kind(), self.python_version), + &format!( + "{}{}", + self.python_kind(), + self.python_version.as_ref().expect( + "A Python version must be provided to retrieve the test site packages path" + ) + ), ) } /// Reset the virtual environment in the test context. pub fn reset_venv(&self) { - create_venv_from_executable( - &self.temp_dir, - &self.cache_dir, - &get_toolchain(&self.python_version), - ); + self.create_venv(); } /// Create a new virtual environment named `.venv` in the test context. - fn create_venv(&mut self, python: &str) -> PathBuf { - let parent = self.temp_dir.to_path_buf(); - self.create_venv_in_parent(parent, python) - } - - /// Create a new virtual environment named `.venv` in the given directory. - fn create_venv_in_parent>(&mut self, path: P, python: &str) -> PathBuf { - let executable = get_toolchain(python); - self.add_filters_for_python_version( - &PythonVersion::from_str(python).unwrap(), - executable.clone(), + fn create_venv(&self) { + let executable = get_toolchain( + self.python_version + .as_ref() + .expect("A Python version must be provided to create a test virtual environment"), ); - create_venv_from_executable(&ChildPath::new(path.as_ref()), &self.cache_dir, &executable) + create_venv_from_executable(&self.venv, &self.cache_dir, &executable); } } @@ -562,11 +588,11 @@ pub fn site_packages_path(venv: &Path, python: &str) -> PathBuf { } } -pub fn venv_bin_path(venv: &Path) -> PathBuf { +pub fn venv_bin_path>(venv: &P) -> PathBuf { if cfg!(unix) { - venv.join("bin") + venv.as_ref().join("bin") } else if cfg!(windows) { - venv.join("Scripts") + venv.as_ref().join("Scripts") } else { unimplemented!("Only Windows and Unix are supported") } @@ -583,14 +609,11 @@ pub fn venv_to_interpreter(venv: &Path) -> PathBuf { } /// Get the path to the python interpreter for a specific toolchain version. -pub fn get_toolchain(python: &str) -> PathBuf { +pub fn get_toolchain(version: &PythonVersion) -> PathBuf { InstalledToolchains::from_settings() .map(|installed_toolchains| { installed_toolchains - .find_version( - &PythonVersion::from_str(python) - .expect("Tests should use a valid Python version"), - ) + .find_version(version) .expect("Tests are run on a supported platform") .next() .as_ref() @@ -599,31 +622,26 @@ pub fn get_toolchain(python: &str) -> PathBuf { // We'll search for the request Python on the PATH if not found in the toolchain versions // We hack this into a `PathBuf` to satisfy the compiler but it's just a string .unwrap_or_default() - .unwrap_or(PathBuf::from(python)) + .unwrap_or(PathBuf::from(version.to_string())) } -/// Create a virtual environment named `.venv` in a temporary directory with the given -/// Python executable. -pub fn create_venv_from_executable< - Parent: assert_fs::prelude::PathChild + AsRef, ->( - temp_dir: &Parent, +/// Create a virtual environment at the given path. +pub fn create_venv_from_executable>( + path: P, cache_dir: &assert_fs::TempDir, python: &Path, -) -> PathBuf { - let venv = temp_dir.child(".venv"); +) { Command::new(get_bin()) .arg("venv") - .arg(venv.as_os_str()) + .arg(path.as_ref().as_os_str()) .arg("--cache-dir") .arg(cache_dir.path()) .arg("--python") .arg(python) - .current_dir(temp_dir) + .current_dir(path.as_ref().parent().unwrap()) .assert() .success(); - venv.assert(predicates::path::is_dir()); - venv.to_path_buf() + ChildPath::new(path.as_ref()).assert(predicate::path::is_dir()); } /// Returns the uv binary that cargo built before launching the tests. diff --git a/crates/uv/tests/pip_compile.rs b/crates/uv/tests/pip_compile.rs index cc78fbb42217..8bffc83829e7 100644 --- a/crates/uv/tests/pip_compile.rs +++ b/crates/uv/tests/pip_compile.rs @@ -127,24 +127,23 @@ fn missing_requirements_in() { fn missing_venv() -> Result<()> { let context = TestContext::new("3.12"); context.temp_dir.child("requirements.in").touch()?; - fs_err::remove_dir_all(context.temp_dir.child(".venv").path())?; + fs_err::remove_dir_all(context.venv.path())?; uv_snapshot!(context.filters(), context.compile() .arg("requirements.in"), @r###" - success: false - exit_code: 2 + success: true + exit_code: 0 ----- stdout ----- + # This file was autogenerated by uv via the following command: + # uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z requirements.in ----- stderr ----- warning: Requirements file requirements.in does not contain any dependencies - error: No Python interpreters found in provided path, active virtual environment, or search path + Resolved 0 packages in [TIME] "### ); - context - .temp_dir - .child(".venv") - .assert(predicates::path::missing()); + context.venv.assert(predicates::path::missing()); Ok(()) } diff --git a/crates/uv/tests/pip_install.rs b/crates/uv/tests/pip_install.rs index f1df1bf5c4b0..00a233c5f03a 100644 --- a/crates/uv/tests/pip_install.rs +++ b/crates/uv/tests/pip_install.rs @@ -3954,7 +3954,7 @@ fn install_package_basic_auth_from_keyring() { .arg("subprocess") .arg("--strict") .env("KEYRING_TEST_CREDENTIALS", r#"{"pypi-proxy.fly.dev": {"public": "heron"}}"#) - .env("PATH", venv_bin_path(context.venv.as_path())), @r###" + .env("PATH", venv_bin_path(&context.venv)), @r###" success: true exit_code: 0 ----- stdout ----- @@ -4001,7 +4001,7 @@ fn install_package_basic_auth_from_keyring_wrong_password() { .arg("subprocess") .arg("--strict") .env("KEYRING_TEST_CREDENTIALS", r#"{"pypi-proxy.fly.dev": {"public": "foobar"}}"#) - .env("PATH", venv_bin_path(context.venv.as_path())), @r###" + .env("PATH", venv_bin_path(&context.venv)), @r###" success: false exit_code: 2 ----- stdout ----- @@ -4042,7 +4042,7 @@ fn install_package_basic_auth_from_keyring_wrong_username() { .arg("subprocess") .arg("--strict") .env("KEYRING_TEST_CREDENTIALS", r#"{"pypi-proxy.fly.dev": {"other": "heron"}}"#) - .env("PATH", venv_bin_path(context.venv.as_path())), @r###" + .env("PATH", venv_bin_path(&context.venv)), @r###" success: false exit_code: 2 ----- stdout ----- diff --git a/crates/uv/tests/run.rs b/crates/uv/tests/run.rs index e92e40c062f4..0c94272758c2 100644 --- a/crates/uv/tests/run.rs +++ b/crates/uv/tests/run.rs @@ -51,6 +51,8 @@ fn run_with_python_version() -> Result<()> { 3.7.0 ----- stderr ----- + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Creating virtualenv at: [VENV]/ Resolved 5 packages in [TIME] Downloaded 4 packages in [TIME] Installed 4 packages in [TIME] diff --git a/crates/uv/tests/venv.rs b/crates/uv/tests/venv.rs index b9b00d37292d..c8b224662405 100644 --- a/crates/uv/tests/venv.rs +++ b/crates/uv/tests/venv.rs @@ -1,117 +1,19 @@ #![cfg(feature = "python")] -use std::process::Command; -use std::{ffi::OsString, str::FromStr}; - use anyhow::Result; use assert_cmd::prelude::*; -use assert_fs::fixture::ChildPath; use assert_fs::prelude::*; -#[cfg(windows)] -use uv_fs::Simplified; -use uv_toolchain::PythonVersion; -use crate::common::{get_bin, python_path_with_versions, uv_snapshot, TestContext, EXCLUDE_NEWER}; +use crate::common::{uv_snapshot, TestContext}; mod common; -struct VenvTestContext { - cache_dir: assert_fs::TempDir, - temp_dir: assert_fs::TempDir, - venv: ChildPath, - toolchain_dir: ChildPath, - python_path: OsString, - python_versions: Vec, -} - -impl VenvTestContext { - fn new(python_versions: &[&str]) -> Self { - let temp_dir = assert_fs::TempDir::new().unwrap(); - let python_path = python_path_with_versions(&temp_dir, python_versions) - .expect("Failed to create Python test path"); - - let toolchain_dir = temp_dir.child("toolchains"); - toolchain_dir.create_dir_all().unwrap(); - - // Canonicalize the virtual environment path for consistent snapshots across platforms - let venv = ChildPath::new(temp_dir.canonicalize().unwrap().join(".venv")); - - let python_versions = python_versions - .iter() - .map(|version| { - PythonVersion::from_str(version).expect("Tests should use valid Python versions") - }) - .collect::>(); - Self { - cache_dir: assert_fs::TempDir::new().unwrap(), - temp_dir, - toolchain_dir, - venv, - python_path, - python_versions, - } - } - - fn venv_command(&self) -> Command { - let mut command = Command::new(get_bin()); - command - .arg("venv") - .arg("--cache-dir") - .arg(self.cache_dir.path()) - .arg("--exclude-newer") - .arg(EXCLUDE_NEWER) - .env("UV_TOOLCHAIN_DIR", self.toolchain_dir.as_os_str()) - .env("UV_TEST_PYTHON_PATH", self.python_path.clone()) - .env("UV_NO_WRAP", "1") - .env("UV_STACK_SIZE", (2 * 1024 * 1024).to_string()) - .current_dir(self.temp_dir.as_os_str()); - command - } - - fn filters(&self) -> Vec<(String, String)> { - let mut filters = Vec::new(); - filters.extend( - TestContext::path_patterns(&self.temp_dir) - .into_iter() - .map(|pattern| (pattern, "[TEMP_DIR]/".to_string())), - ); - filters.push(( - r"interpreter at: .+".to_string(), - "interpreter at: [PATH]".to_string(), - )); - filters.push(( - r"Activate with: (?:.*)\\Scripts\\activate".to_string(), - "Activate with: source .venv/bin/activate".to_string(), - )); - - // Add Python patch version filtering unless one was explicitly requested to ensure - // snapshots are patch version agnostic when it is not a part of the test. - if self - .python_versions - .iter() - .all(|version| version.patch().is_none()) - { - for python_version in &self.python_versions { - filters.push(( - format!( - r"({})\.\d+", - regex::escape(python_version.to_string().as_str()) - ), - "$1.[X]".to_string(), - )); - } - } - - filters - } -} - #[test] fn create_venv() { - let context = VenvTestContext::new(&["3.12"]); + let context = TestContext::new_with_versions(&["3.12"]); // Create a virtual environment at `.venv`. - uv_snapshot!(context.filters(), context.venv_command() + uv_snapshot!(context.filters(), context.venv() .arg(context.venv.as_os_str()) .arg("--python") .arg("3.12"), @r###" @@ -120,16 +22,16 @@ fn create_venv() { ----- stdout ----- ----- stderr ----- - Using Python 3.12.[X] interpreter at: [PATH] - Creating virtualenv at: .venv - Activate with: source .venv/bin/activate + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Creating virtualenv at: [VENV]/ + Activate with: source [VENV]/bin/activate "### ); context.venv.assert(predicates::path::is_dir()); // Create a virtual environment at the same location, which should replace it. - uv_snapshot!(context.filters(), context.venv_command() + uv_snapshot!(context.filters(), context.venv() .arg(context.venv.as_os_str()) .arg("--python") .arg("3.12"), @r###" @@ -138,9 +40,9 @@ fn create_venv() { ----- stdout ----- ----- stderr ----- - Using Python 3.12.[X] interpreter at: [PATH] - Creating virtualenv at: .venv - Activate with: source .venv/bin/activate + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Creating virtualenv at: [VENV]/ + Activate with: source [VENV]/bin/activate "### ); @@ -149,8 +51,8 @@ fn create_venv() { #[test] fn create_venv_defaults_to_cwd() { - let context = VenvTestContext::new(&["3.12"]); - uv_snapshot!(context.filters(), context.venv_command() + let context = TestContext::new_with_versions(&["3.12"]); + uv_snapshot!(context.filters(), context.venv() .arg("--python") .arg("3.12"), @r###" success: true @@ -158,9 +60,9 @@ fn create_venv_defaults_to_cwd() { ----- stdout ----- ----- stderr ----- - Using Python 3.12.[X] interpreter at: [PATH] - Creating virtualenv at: .venv - Activate with: source .venv/bin/activate + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Creating virtualenv at: [VENV]/ + Activate with: source [VENV]/bin/activate "### ); @@ -169,27 +71,27 @@ fn create_venv_defaults_to_cwd() { #[test] fn create_venv_ignores_virtual_env_variable() { - let context = VenvTestContext::new(&["3.12"]); + let context = TestContext::new_with_versions(&["3.12"]); // We shouldn't care if `VIRTUAL_ENV` is set to an non-existent directory // because we ignore virtual environment interpreter sources (we require a system interpreter) - uv_snapshot!(context.filters(), context.venv_command() + uv_snapshot!(context.filters(), context.venv() .env("VIRTUAL_ENV", context.temp_dir.child("does-not-exist").as_os_str()), @r###" success: true exit_code: 0 ----- stdout ----- ----- stderr ----- - Using Python 3.12.[X] interpreter at: [PATH] - Creating virtualenv at: .venv - Activate with: source .venv/bin/activate + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Creating virtualenv at: [VENV]/ + Activate with: source [VENV]/bin/activate "### ); } #[test] fn seed() { - let context = VenvTestContext::new(&["3.12"]); - uv_snapshot!(context.filters(), context.venv_command() + let context = TestContext::new_with_versions(&["3.12"]); + uv_snapshot!(context.filters(), context.venv() .arg(context.venv.as_os_str()) .arg("--seed") .arg("--python") @@ -199,10 +101,10 @@ fn seed() { ----- stdout ----- ----- stderr ----- - Using Python 3.12.[X] interpreter at: [PATH] - Creating virtualenv at: .venv + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Creating virtualenv at: [VENV]/ + pip==24.0 - Activate with: source .venv/bin/activate + Activate with: source [VENV]/bin/activate "### ); @@ -211,8 +113,8 @@ fn seed() { #[test] fn seed_older_python_version() { - let context = VenvTestContext::new(&["3.10"]); - uv_snapshot!(context.filters(), context.venv_command() + let context = TestContext::new_with_versions(&["3.10"]); + uv_snapshot!(context.filters(), context.venv() .arg(context.venv.as_os_str()) .arg("--seed") .arg("--python") @@ -222,12 +124,12 @@ fn seed_older_python_version() { ----- stdout ----- ----- stderr ----- - Using Python 3.10.[X] interpreter at: [PATH] - Creating virtualenv at: .venv + Using Python 3.10.[X] interpreter at: [PYTHON-3.10] + Creating virtualenv at: [VENV]/ + pip==24.0 + setuptools==69.2.0 + wheel==0.43.0 - Activate with: source .venv/bin/activate + Activate with: source [VENV]/bin/activate "### ); @@ -236,9 +138,9 @@ fn seed_older_python_version() { #[test] fn create_venv_unknown_python_minor() { - let context = VenvTestContext::new(&["3.12"]); + let context = TestContext::new_with_versions(&["3.12"]); - let mut command = context.venv_command(); + let mut command = context.venv(); command .arg(context.venv.as_os_str()) // Request a version we know we'll never see @@ -274,9 +176,9 @@ fn create_venv_unknown_python_minor() { #[test] fn create_venv_unknown_python_patch() { - let context = VenvTestContext::new(&["3.12"]); + let context = TestContext::new_with_versions(&["3.12"]); - let mut command = context.venv_command(); + let mut command = context.venv(); command .arg(context.venv.as_os_str()) // Request a version we know we'll never see @@ -313,9 +215,9 @@ fn create_venv_unknown_python_patch() { #[cfg(feature = "python-patch")] #[test] fn create_venv_python_patch() { - let context = VenvTestContext::new(&["3.12.1"]); + let context = TestContext::new_with_versions(&["3.12.1"]); - uv_snapshot!(context.filters(), context.venv_command() + uv_snapshot!(context.filters(), context.venv() .arg(context.venv.as_os_str()) .arg("--python") .arg("3.12.1"), @r###" @@ -324,9 +226,9 @@ fn create_venv_python_patch() { ----- stdout ----- ----- stderr ----- - Using Python 3.12.1 interpreter at: [PATH] - Creating virtualenv at: .venv - Activate with: source .venv/bin/activate + Using Python 3.12.1 interpreter at: [PYTHON-3.12.1] + Creating virtualenv at: [VENV]/ + Activate with: source [VENV]/bin/activate "### ); @@ -335,12 +237,12 @@ fn create_venv_python_patch() { #[test] fn file_exists() -> Result<()> { - let context = VenvTestContext::new(&["3.12"]); + let context = TestContext::new_with_versions(&["3.12"]); // Create a file at `.venv`. Creating a virtualenv at the same path should fail. context.venv.touch()?; - uv_snapshot!(context.filters(), context.venv_command() + uv_snapshot!(context.filters(), context.venv() .arg(context.venv.as_os_str()) .arg("--python") .arg("3.12"), @r###" @@ -349,12 +251,12 @@ fn file_exists() -> Result<()> { ----- stdout ----- ----- stderr ----- - Using Python 3.12.[X] interpreter at: [PATH] - Creating virtualenv at: .venv + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Creating virtualenv at: [VENV]/ uv::venv::creation × Failed to create virtualenv - ╰─▶ File exists at `.venv` + ╰─▶ File exists at `[VENV]/` "### ); @@ -363,11 +265,11 @@ fn file_exists() -> Result<()> { #[test] fn empty_dir_exists() -> Result<()> { - let context = VenvTestContext::new(&["3.12"]); + let context = TestContext::new_with_versions(&["3.12"]); // Create an empty directory at `.venv`. Creating a virtualenv at the same path should succeed. context.venv.create_dir_all()?; - uv_snapshot!(context.filters(), context.venv_command() + uv_snapshot!(context.filters(), context.venv() .arg(context.venv.as_os_str()) .arg("--python") .arg("3.12"), @r###" @@ -376,9 +278,9 @@ fn empty_dir_exists() -> Result<()> { ----- stdout ----- ----- stderr ----- - Using Python 3.12.[X] interpreter at: [PATH] - Creating virtualenv at: .venv - Activate with: source .venv/bin/activate + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Creating virtualenv at: [VENV]/ + Activate with: source [VENV]/bin/activate "### ); @@ -389,13 +291,13 @@ fn empty_dir_exists() -> Result<()> { #[test] fn non_empty_dir_exists() -> Result<()> { - let context = VenvTestContext::new(&["3.12"]); + let context = TestContext::new_with_versions(&["3.12"]); // Create a non-empty directory at `.venv`. Creating a virtualenv at the same path should fail. context.venv.create_dir_all()?; context.venv.child("file").touch()?; - uv_snapshot!(context.filters(), context.venv_command() + uv_snapshot!(context.filters(), context.venv() .arg(context.venv.as_os_str()) .arg("--python") .arg("3.12"), @r###" @@ -404,12 +306,12 @@ fn non_empty_dir_exists() -> Result<()> { ----- stdout ----- ----- stderr ----- - Using Python 3.12.[X] interpreter at: [PATH] - Creating virtualenv at: .venv + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Creating virtualenv at: [VENV]/ uv::venv::creation × Failed to create virtualenv - ╰─▶ The directory `.venv` exists, but it's not a virtualenv + ╰─▶ The directory `[VENV]/` exists, but it's not a virtualenv "### ); @@ -418,14 +320,14 @@ fn non_empty_dir_exists() -> Result<()> { #[test] fn non_empty_dir_exists_allow_existing() -> Result<()> { - let context = VenvTestContext::new(&["3.12"]); + let context = TestContext::new_with_versions(&["3.12"]); // Create a non-empty directory at `.venv`. Creating a virtualenv at the same path should // succeed when `--allow-existing` is specified, but fail when it is not. context.venv.create_dir_all()?; context.venv.child("file").touch()?; - uv_snapshot!(context.filters(), context.venv_command() + uv_snapshot!(context.filters(), context.venv() .arg(context.venv.as_os_str()) .arg("--python") .arg("3.12"), @r###" @@ -434,16 +336,16 @@ fn non_empty_dir_exists_allow_existing() -> Result<()> { ----- stdout ----- ----- stderr ----- - Using Python 3.12.[X] interpreter at: [PATH] - Creating virtualenv at: .venv + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Creating virtualenv at: [VENV]/ uv::venv::creation × Failed to create virtualenv - ╰─▶ The directory `.venv` exists, but it's not a virtualenv + ╰─▶ The directory `[VENV]/` exists, but it's not a virtualenv "### ); - uv_snapshot!(context.filters(), context.venv_command() + uv_snapshot!(context.filters(), context.venv() .arg(context.venv.as_os_str()) .arg("--allow-existing") .arg("--python") @@ -453,15 +355,15 @@ fn non_empty_dir_exists_allow_existing() -> Result<()> { ----- stdout ----- ----- stderr ----- - Using Python 3.12.[X] interpreter at: [PATH] - Creating virtualenv at: .venv - Activate with: source .venv/bin/activate + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Creating virtualenv at: [VENV]/ + Activate with: source [VENV]/bin/activate "### ); // Running again should _also_ succeed, overwriting existing symlinks and respecting existing // directories. - uv_snapshot!(context.filters(), context.venv_command() + uv_snapshot!(context.filters(), context.venv() .arg(context.venv.as_os_str()) .arg("--allow-existing") .arg("--python") @@ -471,9 +373,9 @@ fn non_empty_dir_exists_allow_existing() -> Result<()> { ----- stdout ----- ----- stderr ----- - Using Python 3.12.[X] interpreter at: [PATH] - Creating virtualenv at: .venv - Activate with: source .venv/bin/activate + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Creating virtualenv at: [VENV]/ + Activate with: source [VENV]/bin/activate "### ); @@ -483,39 +385,39 @@ fn non_empty_dir_exists_allow_existing() -> Result<()> { #[test] #[cfg(windows)] fn windows_shims() -> Result<()> { - let context = VenvTestContext::new(&["3.9", "3.8"]); + let context = TestContext::new_with_versions(&["3.9", "3.8"]); let shim_path = context.temp_dir.child("shim"); - let py38 = std::env::split_paths(&context.python_path) + let py38 = context + .python_versions .last() .expect("python_path_with_versions to set up the python versions"); + // We want 3.8 and the first version should be 3.9. // Picking the last is necessary to prove that shims work because the python version selects // the python version from the first path segment by default, so we take the last to prove it's not // returning that version. - assert!(py38.to_str().unwrap().contains("3.8")); + assert!(py38.0.to_string().contains("3.8")); // Write the shim script that forwards the arguments to the python3.8 installation. fs_err::create_dir(&shim_path)?; fs_err::write( shim_path.child("python.bat"), - format!("@echo off\r\n{}/python.exe %*", py38.display()), + format!("@echo off\r\n{}/python.exe %*", py38.1.display()), )?; - // Create a virtual environment at `.venv`, passing the redundant `--clear` flag. - uv_snapshot!(context.filters(), context.venv_command() + // Create a virtual environment at `.venv` with the shim + uv_snapshot!(context.filters(), context.venv() .arg(context.venv.as_os_str()) - .arg("--clear") - .env("UV_TEST_PYTHON_PATH", format!("{};{}", shim_path.display(), context.python_path.simplified_display())), @r###" + .env("UV_TEST_PYTHON_PATH", format!("{};{}", shim_path.display(), context.python_path().to_string_lossy())), @r###" success: true exit_code: 0 ----- stdout ----- ----- stderr ----- - warning: virtualenv's `--clear` has no effect (uv always clears the virtual environment). - Using Python 3.8.[X] interpreter at: [PATH] - Creating virtualenv at: .venv - Activate with: source .venv/bin/activate + Using Python 3.8.[X] interpreter at: [PYTHON-3.8] + Creating virtualenv at: [VENV]/ + Activate with: source [VENV]/bin/activate "### ); @@ -526,10 +428,10 @@ fn windows_shims() -> Result<()> { #[test] fn virtualenv_compatibility() { - let context = VenvTestContext::new(&["3.12"]); + let context = TestContext::new_with_versions(&["3.12"]); // Create a virtual environment at `.venv`, passing the redundant `--clear` flag. - uv_snapshot!(context.filters(), context.venv_command() + uv_snapshot!(context.filters(), context.venv() .arg(context.venv.as_os_str()) .arg("--clear") .arg("--python") @@ -540,9 +442,9 @@ fn virtualenv_compatibility() { ----- stderr ----- warning: virtualenv's `--clear` has no effect (uv always clears the virtual environment). - Using Python 3.12.[X] interpreter at: [PATH] - Creating virtualenv at: .venv - Activate with: source .venv/bin/activate + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Creating virtualenv at: [VENV]/ + Activate with: source [VENV]/bin/activate "### ); @@ -552,10 +454,9 @@ fn virtualenv_compatibility() { #[test] fn verify_pyvenv_cfg() { let context = TestContext::new("3.12"); - let venv = context.temp_dir.child(".venv"); - let pyvenv_cfg = venv.child("pyvenv.cfg"); + let pyvenv_cfg = context.venv.child("pyvenv.cfg"); - venv.assert(predicates::path::is_dir()); + context.venv.assert(predicates::path::is_dir()); // Check pyvenv.cfg exists pyvenv_cfg.assert(predicates::path::is_file()); @@ -569,11 +470,11 @@ fn verify_pyvenv_cfg() { /// Ensure that a nested virtual environment uses the same `home` directory as the parent. #[test] fn verify_nested_pyvenv_cfg() -> Result<()> { - let context = VenvTestContext::new(&["3.12"]); + let context = TestContext::new_with_versions(&["3.12"]); // Create a virtual environment at `.venv`. context - .venv_command() + .venv() .arg(context.venv.as_os_str()) .arg("--python") .arg("3.12") @@ -595,7 +496,7 @@ fn verify_nested_pyvenv_cfg() -> Result<()> { // Now, create a virtual environment from within the virtual environment. let subvenv = context.temp_dir.child(".subvenv"); context - .venv_command() + .venv() .arg(subvenv.as_os_str()) .arg("--python") .arg("3.12") @@ -622,29 +523,19 @@ fn verify_nested_pyvenv_cfg() -> Result<()> { #[test] #[cfg(windows)] fn path_with_trailing_space_gives_proper_error() { - let context = VenvTestContext::new(&["3.12"]); + let context = TestContext::new_with_versions(&["3.12"]); - let mut filters = context.filters(); - filters.push(( - regex::escape(&context.cache_dir.path().display().to_string()).to_string(), - r"C:\Path\to\Cache\dir".to_string(), - )); - // Create a virtual environment at `.venv`. - uv_snapshot!(filters, Command::new(get_bin()) - .arg("venv") - .arg(context.venv.as_os_str()) - .arg("--python") - .arg("3.12") - .env("UV_CACHE_DIR", format!("{} ", context.cache_dir.path().display())) - .env("UV_TEST_PYTHON_PATH", context.python_path.clone()) - .current_dir(context.temp_dir.path()), @r###" + // Set a custom cache directory with a trailing space + uv_snapshot!(context.filters(), context.venv() + .env("UV_CACHE_DIR", format!("{} ", context.cache_dir.path().display())), @r###" success: false exit_code: 2 ----- stdout ----- ----- stderr ----- - error: failed to open file `C:\Path\to\Cache\dir \CACHEDIR.TAG` + error: failed to open file `[CACHE_DIR]/ /CACHEDIR.TAG` Caused by: The system cannot find the path specified. (os error 3) "### ); + // Note the extra trailing `/` in the snapshot is due to the filters, not the actual output. } From 2c7a1e6021bc1cb8519436bf8bb6b92e39f06fa7 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Tue, 18 Jun 2024 08:03:02 -0500 Subject: [PATCH 2/2] Remove filter for venv in working directory --- crates/uv/tests/common/mod.rs | 14 +++----- crates/uv/tests/lock.rs | 2 +- crates/uv/tests/run.rs | 6 ++-- crates/uv/tests/venv.rs | 60 +++++++++++++++++------------------ crates/uv/tests/workspace.rs | 4 +-- 5 files changed, 41 insertions(+), 45 deletions(-) diff --git a/crates/uv/tests/common/mod.rs b/crates/uv/tests/common/mod.rs index 38e82fd39940..c97bcf618793 100644 --- a/crates/uv/tests/common/mod.rs +++ b/crates/uv/tests/common/mod.rs @@ -92,7 +92,10 @@ impl TestContext { let temp_dir = assert_fs::TempDir::new().expect("Failed to create temp dir"); let cache_dir = assert_fs::TempDir::new().expect("Failed to create cache dir"); - let venv = temp_dir.child(".venv"); + // Canonicalize the temp dir for consistent snapshot behavior + let canonical_temp_dir = temp_dir.canonicalize().unwrap(); + let venv = ChildPath::new(canonical_temp_dir.join(".venv")); + let python_version = python_versions .first() .map(|version| PythonVersion::from_str(version).unwrap()); @@ -177,19 +180,12 @@ impl TestContext { filters.push(( Self::path_pattern( site_packages - .strip_prefix(&temp_dir) + .strip_prefix(&canonical_temp_dir) .expect("The test site-packages directory is always in the tempdir"), ), "[SITE_PACKAGES]/".to_string(), )); }; - filters.push(( - Self::path_pattern( - venv.strip_prefix(&temp_dir) - .expect("The test virtual environment directory is always in the tempdir"), - ), - "[VENV]/".to_string(), - )); // Filter non-deterministic temporary directory names // Note we apply this _after_ all the full paths to avoid breaking their matching diff --git a/crates/uv/tests/lock.rs b/crates/uv/tests/lock.rs index bc0378dcf574..cbddbb72bbeb 100644 --- a/crates/uv/tests/lock.rs +++ b/crates/uv/tests/lock.rs @@ -1894,7 +1894,7 @@ fn lock_requires_python() -> Result<()> { ----- stderr ----- warning: `uv sync` is experimental and may change without warning. - Removing virtual environment at: [VENV]/ + Removing virtual environment at: .venv error: No interpreter found for Python >=3.12 in provided path, active virtual environment, or search path "###); diff --git a/crates/uv/tests/run.rs b/crates/uv/tests/run.rs index 0c94272758c2..7ecef9b6676c 100644 --- a/crates/uv/tests/run.rs +++ b/crates/uv/tests/run.rs @@ -52,7 +52,7 @@ fn run_with_python_version() -> Result<()> { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - Creating virtualenv at: [VENV]/ + Creating virtualenv at: .venv Resolved 5 packages in [TIME] Downloaded 4 packages in [TIME] Installed 4 packages in [TIME] @@ -102,9 +102,9 @@ fn run_with_python_version() -> Result<()> { 3.6.0 ----- stderr ----- - Removing virtual environment at: [VENV]/ + Removing virtual environment at: .venv Using Python 3.11.[X] interpreter at: [PYTHON-3.11] - Creating virtualenv at: [VENV]/ + Creating virtualenv at: .venv Resolved 5 packages in [TIME] Downloaded 4 packages in [TIME] Installed 4 packages in [TIME] diff --git a/crates/uv/tests/venv.rs b/crates/uv/tests/venv.rs index c8b224662405..6990dc7c213c 100644 --- a/crates/uv/tests/venv.rs +++ b/crates/uv/tests/venv.rs @@ -23,8 +23,8 @@ fn create_venv() { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - Creating virtualenv at: [VENV]/ - Activate with: source [VENV]/bin/activate + Creating virtualenv at: .venv + Activate with: source .venv/bin/activate "### ); @@ -41,8 +41,8 @@ fn create_venv() { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - Creating virtualenv at: [VENV]/ - Activate with: source [VENV]/bin/activate + Creating virtualenv at: .venv + Activate with: source .venv/bin/activate "### ); @@ -61,8 +61,8 @@ fn create_venv_defaults_to_cwd() { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - Creating virtualenv at: [VENV]/ - Activate with: source [VENV]/bin/activate + Creating virtualenv at: .venv + Activate with: source .venv/bin/activate "### ); @@ -82,8 +82,8 @@ fn create_venv_ignores_virtual_env_variable() { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - Creating virtualenv at: [VENV]/ - Activate with: source [VENV]/bin/activate + Creating virtualenv at: .venv + Activate with: source .venv/bin/activate "### ); } @@ -102,9 +102,9 @@ fn seed() { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - Creating virtualenv at: [VENV]/ + Creating virtualenv at: .venv + pip==24.0 - Activate with: source [VENV]/bin/activate + Activate with: source .venv/bin/activate "### ); @@ -125,11 +125,11 @@ fn seed_older_python_version() { ----- stderr ----- Using Python 3.10.[X] interpreter at: [PYTHON-3.10] - Creating virtualenv at: [VENV]/ + Creating virtualenv at: .venv + pip==24.0 + setuptools==69.2.0 + wheel==0.43.0 - Activate with: source [VENV]/bin/activate + Activate with: source .venv/bin/activate "### ); @@ -227,8 +227,8 @@ fn create_venv_python_patch() { ----- stderr ----- Using Python 3.12.1 interpreter at: [PYTHON-3.12.1] - Creating virtualenv at: [VENV]/ - Activate with: source [VENV]/bin/activate + Creating virtualenv at: .venv + Activate with: source .venv/bin/activate "### ); @@ -252,11 +252,11 @@ fn file_exists() -> Result<()> { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - Creating virtualenv at: [VENV]/ + Creating virtualenv at: .venv uv::venv::creation × Failed to create virtualenv - ╰─▶ File exists at `[VENV]/` + ╰─▶ File exists at `.venv` "### ); @@ -279,8 +279,8 @@ fn empty_dir_exists() -> Result<()> { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - Creating virtualenv at: [VENV]/ - Activate with: source [VENV]/bin/activate + Creating virtualenv at: .venv + Activate with: source .venv/bin/activate "### ); @@ -307,11 +307,11 @@ fn non_empty_dir_exists() -> Result<()> { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - Creating virtualenv at: [VENV]/ + Creating virtualenv at: .venv uv::venv::creation × Failed to create virtualenv - ╰─▶ The directory `[VENV]/` exists, but it's not a virtualenv + ╰─▶ The directory `.venv` exists, but it's not a virtualenv "### ); @@ -337,11 +337,11 @@ fn non_empty_dir_exists_allow_existing() -> Result<()> { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - Creating virtualenv at: [VENV]/ + Creating virtualenv at: .venv uv::venv::creation × Failed to create virtualenv - ╰─▶ The directory `[VENV]/` exists, but it's not a virtualenv + ╰─▶ The directory `.venv` exists, but it's not a virtualenv "### ); @@ -356,8 +356,8 @@ fn non_empty_dir_exists_allow_existing() -> Result<()> { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - Creating virtualenv at: [VENV]/ - Activate with: source [VENV]/bin/activate + Creating virtualenv at: .venv + Activate with: source .venv/bin/activate "### ); @@ -374,8 +374,8 @@ fn non_empty_dir_exists_allow_existing() -> Result<()> { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - Creating virtualenv at: [VENV]/ - Activate with: source [VENV]/bin/activate + Creating virtualenv at: .venv + Activate with: source .venv/bin/activate "### ); @@ -416,8 +416,8 @@ fn windows_shims() -> Result<()> { ----- stderr ----- Using Python 3.8.[X] interpreter at: [PYTHON-3.8] - Creating virtualenv at: [VENV]/ - Activate with: source [VENV]/bin/activate + Creating virtualenv at: .venv + Activate with: source .venv/bin/activate "### ); @@ -443,8 +443,8 @@ fn virtualenv_compatibility() { ----- stderr ----- warning: virtualenv's `--clear` has no effect (uv always clears the virtual environment). Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - Creating virtualenv at: [VENV]/ - Activate with: source [VENV]/bin/activate + Creating virtualenv at: .venv + Activate with: source .venv/bin/activate "### ); diff --git a/crates/uv/tests/workspace.rs b/crates/uv/tests/workspace.rs index c7f84439d2ec..3722473e7ea1 100644 --- a/crates/uv/tests/workspace.rs +++ b/crates/uv/tests/workspace.rs @@ -419,7 +419,7 @@ fn test_uv_run_with_package_virtual_workspace() -> Result<()> { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON] - Creating virtualenv at: [VENV]/ + Creating virtualenv at: .venv Resolved 8 packages in [TIME] Downloaded 5 packages in [TIME] Installed 5 packages in [TIME] @@ -479,7 +479,7 @@ fn test_uv_run_with_package_root_workspace() -> Result<()> { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON] - Creating virtualenv at: [VENV]/ + Creating virtualenv at: .venv Resolved 8 packages in [TIME] Downloaded 5 packages in [TIME] Installed 5 packages in [TIME]