From e859ad65fd0b214672b9adc5e89b38270945649b Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Fri, 21 Mar 2025 12:21:16 -0500 Subject: [PATCH 1/2] Add `uv python list` test cases --- crates/uv/tests/it/common/mod.rs | 33 +++ crates/uv/tests/it/main.rs | 3 + crates/uv/tests/it/python_list.rs | 344 ++++++++++++++++++++++++++++++ 3 files changed, 380 insertions(+) create mode 100644 crates/uv/tests/it/python_list.rs diff --git a/crates/uv/tests/it/common/mod.rs b/crates/uv/tests/it/common/mod.rs index 7407cba7c98b2..d57918bf9d31b 100644 --- a/crates/uv/tests/it/common/mod.rs +++ b/crates/uv/tests/it/common/mod.rs @@ -224,6 +224,27 @@ impl TestContext { self } + /// Add extra filtering for ` -> ` symlink display for Python versions in the test + /// context, e.g., for use in `uv python list`. + #[must_use] + pub fn with_filtered_python_symlinks(mut self) -> Self { + for (version, executable) in &self.python_versions { + if fs_err::symlink_metadata(executable).unwrap().is_symlink() { + self.filters.extend( + Self::path_patterns(executable.read_link().unwrap()) + .into_iter() + .map(|pattern| (format! {" -> {pattern}"}, String::new())), + ); + } + // Drop links that are byproducts of the test context too + self.filters.push(( + regex::escape(&format!(" -> [PYTHON-{version}]")), + String::new(), + )); + } + self + } + /// Add extra standard filtering for a given path. #[must_use] pub fn with_filtered_path(mut self, path: &Path, name: &str) -> Self { @@ -803,6 +824,18 @@ impl TestContext { command } + /// Create a `uv python list` command with options shared across scenarios. + pub fn python_list(&self) -> Command { + let mut command = self.new_command(); + command + .arg("python") + .arg("list") + .env(EnvVars::UV_PYTHON_INSTALL_DIR, "") + .current_dir(&self.temp_dir); + self.add_shared_options(&mut command, false); + command + } + /// Create a `uv python install` command with options shared across scenarios. pub fn python_install(&self) -> Command { let mut command = self.new_command(); diff --git a/crates/uv/tests/it/main.rs b/crates/uv/tests/it/main.rs index 5ffe6349e7223..9632c9a3b66a4 100644 --- a/crates/uv/tests/it/main.rs +++ b/crates/uv/tests/it/main.rs @@ -72,6 +72,9 @@ mod python_dir; #[cfg(feature = "python")] mod python_find; +#[cfg(feature = "python")] +mod python_list; + #[cfg(feature = "python-managed")] mod python_install; diff --git a/crates/uv/tests/it/python_list.rs b/crates/uv/tests/it/python_list.rs new file mode 100644 index 0000000000000..dc8fa5dd28294 --- /dev/null +++ b/crates/uv/tests/it/python_list.rs @@ -0,0 +1,344 @@ +use uv_python::platform::{Arch, Os}; +use uv_static::EnvVars; + +use crate::common::{uv_snapshot, TestContext}; + +#[test] +fn python_list() { + let mut context: TestContext = TestContext::new_with_versions(&["3.11", "3.12"]) + .with_filtered_python_symlinks() + .with_filtered_python_keys(); + + uv_snapshot!(context.filters(), context.python_list().env(EnvVars::UV_TEST_PYTHON_PATH, ""), @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + "); + + // We show all interpreters + uv_snapshot!(context.filters(), context.python_list(), @r" + success: true + exit_code: 0 + ----- stdout ----- + cpython-3.12.[X]-[PLATFORM] [PYTHON-3.12] + cpython-3.11.[X]-[PLATFORM] [PYTHON-3.11] + + ----- stderr ----- + "); + + // Request Python 3.12 + uv_snapshot!(context.filters(), context.python_list().arg("3.12"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument '3.12' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); + + // Request Python 3.11 + uv_snapshot!(context.filters(), context.python_list().arg("3.11"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument '3.11' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); + + // Request CPython + uv_snapshot!(context.filters(), context.python_list().arg("cpython"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument 'cpython' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); + + // Request CPython 3.12 + uv_snapshot!(context.filters(), context.python_list().arg("cpython@3.12"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument 'cpython@3.12' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); + + // Request CPython 3.12 via partial key syntax + uv_snapshot!(context.filters(), context.python_list().arg("cpython-3.12"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument 'cpython-3.12' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); + + // Request CPython 3.12 for the current platform + let os = Os::from_env(); + let arch = Arch::from_env(); + + uv_snapshot!(context.filters(), context.python_list().arg(format!("cpython-3.12-{os}-{arch}")), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument 'cpython-3.12-macos-aarch64' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); + + // Request PyPy (which should be missing) + uv_snapshot!(context.filters(), context.python_list().arg("pypy"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument 'pypy' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); + + // Swap the order of the Python versions + context.python_versions.reverse(); + + uv_snapshot!(context.filters(), context.python_list(), @r" + success: true + exit_code: 0 + ----- stdout ----- + cpython-3.12.[X]-[PLATFORM] [PYTHON-3.12] + cpython-3.11.[X]-[PLATFORM] [PYTHON-3.11] + + ----- stderr ----- + "); + + // Request Python 3.11 + uv_snapshot!(context.filters(), context.python_list().arg("3.11"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument '3.11' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); +} + +#[test] +fn python_list_pin() { + let context: TestContext = TestContext::new_with_versions(&["3.11", "3.12"]) + .with_filtered_python_symlinks() + .with_filtered_python_keys(); + + // Pin to a version + uv_snapshot!(context.filters(), context.python_pin().arg("3.12"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + Pinned `.python-version` to `3.12` + + ----- stderr ----- + "###); + + // The pin should not affect the listing + uv_snapshot!(context.filters(), context.python_list(), @r" + success: true + exit_code: 0 + ----- stdout ----- + cpython-3.12.[X]-[PLATFORM] [PYTHON-3.12] + cpython-3.11.[X]-[PLATFORM] [PYTHON-3.11] + + ----- stderr ----- + "); + + // So `--no-config` has no effect + uv_snapshot!(context.filters(), context.python_list().arg("--no-config"), @r" + success: true + exit_code: 0 + ----- stdout ----- + cpython-3.12.[X]-[PLATFORM] [PYTHON-3.12] + cpython-3.11.[X]-[PLATFORM] [PYTHON-3.11] + + ----- stderr ----- + "); +} + +#[test] +fn python_list_venv() { + let context: TestContext = TestContext::new_with_versions(&["3.11", "3.12"]) + .with_filtered_python_symlinks() + .with_filtered_python_keys() + .with_filtered_exe_suffix() + .with_filtered_python_names() + .with_filtered_virtualenv_bin(); + + // Create a virtual environment + uv_snapshot!(context.filters(), context.venv().arg("--python").arg("3.12").arg("-q"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + "###); + + // We should not display the virtual environment + uv_snapshot!(context.filters(), context.python_list(), @r" + success: true + exit_code: 0 + ----- stdout ----- + cpython-3.12.[X]-[PLATFORM] [PYTHON-3.12] + cpython-3.11.[X]-[PLATFORM] [PYTHON-3.11] + + ----- stderr ----- + "); + + // Same if the `VIRTUAL_ENV` is not set (the test context includes it by default) + uv_snapshot!(context.filters(), context.python_list().env_remove(EnvVars::VIRTUAL_ENV), @r" + success: true + exit_code: 0 + ----- stdout ----- + cpython-3.12.[X]-[PLATFORM] [PYTHON-3.12] + cpython-3.11.[X]-[PLATFORM] [PYTHON-3.11] + + ----- stderr ----- + "); +} + +#[cfg(unix)] +#[test] +fn python_list_unsupported_version() { + let context: TestContext = TestContext::new_with_versions(&["3.12"]) + .with_filtered_python_symlinks() + .with_filtered_python_keys(); + + // Request a low version + uv_snapshot!(context.filters(), context.python_list().arg("3.6"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument '3.6' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); + + // Request a low version with a patch + uv_snapshot!(context.filters(), context.python_list().arg("3.6.9"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument '3.6.9' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); + + // Request a really low version + uv_snapshot!(context.filters(), context.python_list().arg("2.6"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument '2.6' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); + + // Request a really low version with a patch + uv_snapshot!(context.filters(), context.python_list().arg("2.6.8"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument '2.6.8' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); + + // Request a future version + uv_snapshot!(context.filters(), context.python_list().arg("4.2"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument '4.2' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); + + // Request a low version with a range + uv_snapshot!(context.filters(), context.python_list().arg("<3.0"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument '<3.0' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); + + // Request free-threaded Python on unsupported version + uv_snapshot!(context.filters(), context.python_list().arg("3.12t"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: unexpected argument '3.12t' found + + Usage: uv python list [OPTIONS] + + For more information, try '--help'. + "); +} From 6c81efd73c738d9df77769135bb30a5781b8237d Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Fri, 21 Mar 2025 13:31:13 -0500 Subject: [PATCH 2/2] Drop `list ` tests --- crates/uv/tests/it/python_list.rs | 208 ------------------------------ 1 file changed, 208 deletions(-) diff --git a/crates/uv/tests/it/python_list.rs b/crates/uv/tests/it/python_list.rs index dc8fa5dd28294..63c41abc8090d 100644 --- a/crates/uv/tests/it/python_list.rs +++ b/crates/uv/tests/it/python_list.rs @@ -1,4 +1,3 @@ -use uv_python::platform::{Arch, Os}; use uv_static::EnvVars; use crate::common::{uv_snapshot, TestContext}; @@ -28,107 +27,6 @@ fn python_list() { ----- stderr ----- "); - // Request Python 3.12 - uv_snapshot!(context.filters(), context.python_list().arg("3.12"), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument '3.12' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); - - // Request Python 3.11 - uv_snapshot!(context.filters(), context.python_list().arg("3.11"), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument '3.11' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); - - // Request CPython - uv_snapshot!(context.filters(), context.python_list().arg("cpython"), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument 'cpython' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); - - // Request CPython 3.12 - uv_snapshot!(context.filters(), context.python_list().arg("cpython@3.12"), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument 'cpython@3.12' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); - - // Request CPython 3.12 via partial key syntax - uv_snapshot!(context.filters(), context.python_list().arg("cpython-3.12"), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument 'cpython-3.12' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); - - // Request CPython 3.12 for the current platform - let os = Os::from_env(); - let arch = Arch::from_env(); - - uv_snapshot!(context.filters(), context.python_list().arg(format!("cpython-3.12-{os}-{arch}")), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument 'cpython-3.12-macos-aarch64' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); - - // Request PyPy (which should be missing) - uv_snapshot!(context.filters(), context.python_list().arg("pypy"), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument 'pypy' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); - // Swap the order of the Python versions context.python_versions.reverse(); @@ -236,109 +134,3 @@ fn python_list_venv() { ----- stderr ----- "); } - -#[cfg(unix)] -#[test] -fn python_list_unsupported_version() { - let context: TestContext = TestContext::new_with_versions(&["3.12"]) - .with_filtered_python_symlinks() - .with_filtered_python_keys(); - - // Request a low version - uv_snapshot!(context.filters(), context.python_list().arg("3.6"), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument '3.6' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); - - // Request a low version with a patch - uv_snapshot!(context.filters(), context.python_list().arg("3.6.9"), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument '3.6.9' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); - - // Request a really low version - uv_snapshot!(context.filters(), context.python_list().arg("2.6"), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument '2.6' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); - - // Request a really low version with a patch - uv_snapshot!(context.filters(), context.python_list().arg("2.6.8"), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument '2.6.8' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); - - // Request a future version - uv_snapshot!(context.filters(), context.python_list().arg("4.2"), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument '4.2' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); - - // Request a low version with a range - uv_snapshot!(context.filters(), context.python_list().arg("<3.0"), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument '<3.0' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); - - // Request free-threaded Python on unsupported version - uv_snapshot!(context.filters(), context.python_list().arg("3.12t"), @r" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: unexpected argument '3.12t' found - - Usage: uv python list [OPTIONS] - - For more information, try '--help'. - "); -}