Skip to content

Commit

Permalink
Add basic testing of managed Python installs (#8462)
Browse files Browse the repository at this point in the history
With a change like #8458, we really
need tests for these.

I'm just going to take the possible performance hit of these slow tests
and deal with optimizing them separately.
  • Loading branch information
zanieb authored Oct 24, 2024
1 parent 6caeb6a commit b713877
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 3 deletions.
4 changes: 3 additions & 1 deletion crates/uv/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ ignored = [
]

[features]
default = ["python", "pypi", "git", "performance", "crates-io"]
default = ["python", "python-managed", "pypi", "git", "performance", "crates-io"]
# Use better memory allocators, etc. — also turns-on self-update.
performance = [
"performance-memory-allocator",
Expand All @@ -133,6 +133,8 @@ performance-flate2-backend = ["dep:uv-performance-flate2-backend"]
python = []
# Introduces a dependency on a local Python installation with specific patch versions.
python-patch = []
# Introduces a dependency on managed Python installations.
python-managed = []
# Introduces a dependency on PyPI.
pypi = []
# Introduces a dependency on Git.
Expand Down
23 changes: 23 additions & 0 deletions crates/uv/tests/it/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,15 @@ impl TestContext {
self
}

/// Adds a filter that ignores platform information in a Python installation key.
pub fn with_filtered_python_keys(mut self) -> Self {
self.filters.push((
r"((?:cpython|pypy)-\d+\.\d+(:?\.\d+)?[a-z]?(:?\+[a-z]+)?)-.*".to_string(),
"$1-[PLATFORM]".to_string(),
));
self
}

/// Discover the path to the XDG state directory. We use this, rather than the OS-specific
/// temporary directory, because on macOS (and Windows on GitHub Actions), they involve
/// symlinks. (On macOS, the temporary directory is, like `/var/...`, which resolves to
Expand Down Expand Up @@ -633,6 +642,20 @@ impl TestContext {
command
}

/// Create a `uv python install` command with options shared across scenarios.
pub fn python_install(&self) -> Command {
let mut command = Command::new(get_bin());
let managed = self.temp_dir.join("managed");
command
.arg("python")
.arg("install")
.env(EnvVars::UV_PREVIEW, "1")
.env(EnvVars::UV_PYTHON_INSTALL_DIR, managed)
.current_dir(&self.temp_dir);
self.add_shared_args(&mut command, true);
command
}

/// Create a `uv python pin` command with options shared across scenarios.
pub fn python_pin(&self) -> Command {
let mut command = Command::new(get_bin());
Expand Down
7 changes: 5 additions & 2 deletions crates/uv/tests/it/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,13 @@ mod publish;

mod python_dir;

#[cfg(all(feature = "python", feature = "pypi"))]
#[cfg(feature = "python")]
mod python_find;

#[cfg(all(feature = "python", feature = "pypi"))]
#[cfg(feature = "python-managed")]
mod python_install;

#[cfg(feature = "python")]
mod python_pin;

#[cfg(all(feature = "python", feature = "pypi"))]
Expand Down
82 changes: 82 additions & 0 deletions crates/uv/tests/it/python_install.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use crate::common::{uv_snapshot, TestContext};

#[test]
fn python_install() {
let context: TestContext = TestContext::new_with_versions(&[]).with_filtered_python_keys();

// Install the latest version
uv_snapshot!(context.filters(), context.python_install(), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Searching for Python installations
Installed Python 3.13.0 in [TIME]
+ cpython-3.13.0-[PLATFORM]
"###);

// Should be a no-op when already installed
uv_snapshot!(context.filters(), context.python_install(), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Searching for Python installations
Installed Python 3.13.0 in [TIME]
+ cpython-3.13.0-[PLATFORM]
"###);

// Similarly, when a requested version is already installed
uv_snapshot!(context.filters(), context.python_install().arg("3.13"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Searching for Python versions matching: Python 3.13
Installed Python 3.13.0 in [TIME]
+ cpython-3.13.0-[PLATFORM]
"###);
}

#[test]
fn python_install_freethreaded() {
let context: TestContext = TestContext::new_with_versions(&[]).with_filtered_python_keys();

// Install the latest version
uv_snapshot!(context.filters(), context.python_install().arg("3.13t"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Searching for Python versions matching: Python 3.13t
Installed Python 3.13.0 in [TIME]
+ cpython-3.13.0+freethreaded-[PLATFORM]
"###);

// Should be distinct from 3.13
uv_snapshot!(context.filters(), context.python_install().arg("3.13"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Searching for Python versions matching: Python 3.13
Installed Python 3.13.0 in [TIME]
+ cpython-3.13.0-[PLATFORM]
"###);

// Should not work with older Python versions
uv_snapshot!(context.filters(), context.python_install().arg("3.12t"), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
Searching for Python versions matching: Python 3.12t
error: No download found for request: cpython-3.12t-[PLATFORM]
"###);
}

0 comments on commit b713877

Please sign in to comment.