Skip to content

Commit

Permalink
feat: add proper unit testing for PyPI installation (#2617)
Browse files Browse the repository at this point in the history
## Description

This adds proper unit testing, for PyPI installations and adds a test
harness to test these things. This is a much more efficient and smaller
way of testing the functionality, specifically the need to
install/re-install then doing full integration tests.

## Checklist

- [x] Tests for direct url archives
- [x] Test for vcs installs.
- [x] See if we need to remove integration tests, because some of it is
tested here.

---------

Co-authored-by: Bas Zalmstra <[email protected]>
  • Loading branch information
tdejager and baszalmstra authored Dec 4, 2024
1 parent cba5830 commit d4d3c6d
Show file tree
Hide file tree
Showing 8 changed files with 1,735 additions and 911 deletions.
1,451 changes: 590 additions & 861 deletions examples/pypi-source-deps/pixi.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/pypi-source-deps/pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ rich = "~=13.7"

# With https
flask = { git = "https://github.com/pallets/flask" }
requests = { git = "https://github.com/psf/requests.git", rev = "0106aced5faa299e6ede89d1230bd6784f2c3660" }
requests = { git = "https://github.com/psf/requests.git", rev = "147c8511ddbfa5e8f71bbf5c18ede0c4ceb3bba4" }
# TODO: will support later -> or use branch = '' or tag = '' to specify a branch or tag

# You can also directly add a source dependency from file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ dependencies:
- pip:
- rich~=13.7
- flask @ git+https://github.com/pallets/flask
- requests @ git+https://github.com/psf/requests.git@0106aced5faa299e6ede89d1230bd6784f2c3660
- requests @ git+https://github.com/psf/requests.git@147c8511ddbfa5e8f71bbf5c18ede0c4ceb3bba4
- -e ./minimal-project
- click @ https://github.com/pallets/click/releases/download/8.1.7/click-8.1.7-py3-none-any.whl
- pytest @ git+https://github.com/pytest-dev/pytest.git
1 change: 0 additions & 1 deletion src/install_pypi/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ pub fn convert_to_dist(
filename_decoded.as_ref(),
pkg.requires_python.clone(),
)?;

// Recreate the filename from the extracted last component
// If this errors this is not a valid wheel filename
// and we should consider it a sdist
Expand Down
34 changes: 19 additions & 15 deletions src/install_pypi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ pub async fn update_python_distributions(
}

// Download, build, and unzip any missing distributions.
let wheels = if remote.is_empty() {
let remote_dists = if remote.is_empty() {
Vec::new()
} else {
let start = std::time::Instant::now();
Expand Down Expand Up @@ -328,7 +328,7 @@ pub async fn update_python_distributions(
)
.with_reporter(UvReporter::new(options));

let wheels = preparer
let remote_dists = preparer
.prepare(
remote.iter().map(|(d, _)| d.clone()).collect(),
&uv_context.in_flight,
Expand All @@ -337,17 +337,17 @@ pub async fn update_python_distributions(
.into_diagnostic()
.context("Failed to prepare distributions")?;

let s = if wheels.len() == 1 { "" } else { "s" };
let s = if remote_dists.len() == 1 { "" } else { "s" };
tracing::info!(
"{}",
format!(
"Prepared {} in {}",
format!("{} package{}", wheels.len(), s),
format!("{} package{}", remote_dists.len(), s),
elapsed(start.elapsed())
)
);

wheels
remote_dists
};

// Remove any unnecessary packages.
Expand Down Expand Up @@ -408,8 +408,12 @@ pub async fn update_python_distributions(
}

// Install the resolved distributions.
let local_iter = local.iter().map(|(d, _)| d.clone());
let wheels = wheels.into_iter().chain(local_iter).collect::<Vec<_>>();
// At this point we have all the wheels we need to install available to link locally
let local_dists = local.iter().map(|(d, _)| d.clone());
let all_dists = remote_dists
.into_iter()
.chain(local_dists)
.collect::<Vec<_>>();

// Figure what wheels needed to be re-installed because of an installer mismatch
// we want to handle these somewhat differently and warn the user about them
Expand All @@ -427,7 +431,7 @@ pub async fn update_python_distributions(
// Verify if pypi wheels will override existing conda packages
// and warn if they are
if let Ok(Some(clobber_packages)) =
pypi_conda_clobber.clobber_on_installation(wheels.clone(), &venv)
pypi_conda_clobber.clobber_on_installation(all_dists.clone(), &venv)
{
let packages_names = clobber_packages.iter().join(", ");

Expand All @@ -452,27 +456,27 @@ pub async fn update_python_distributions(
}

let options = UvReporterOptions::new()
.with_length(wheels.len() as u64)
.with_capacity(wheels.len() + 30)
.with_starting_tasks(wheels.iter().map(|d| format!("{}", d.name())))
.with_length(all_dists.len() as u64)
.with_capacity(all_dists.len() + 30)
.with_starting_tasks(all_dists.iter().map(|d| format!("{}", d.name())))
.with_top_level_message("Installing distributions");

if !wheels.is_empty() {
if !all_dists.is_empty() {
let start = std::time::Instant::now();
uv_installer::Installer::new(&venv)
.with_link_mode(LinkMode::default())
.with_installer_name(Some(consts::PIXI_UV_INSTALLER.to_string()))
.with_reporter(UvReporter::new(options))
.install(wheels.clone())
.install(all_dists.clone())
.await
.unwrap();

let s = if wheels.len() == 1 { "" } else { "s" };
let s = if all_dists.len() == 1 { "" } else { "s" };
tracing::info!(
"{}",
format!(
"Installed {} in {}",
format!("{} package{}", wheels.len(), s),
format!("{} package{}", all_dists.len(), s),
elapsed(start.elapsed())
)
);
Expand Down
Loading

0 comments on commit d4d3c6d

Please sign in to comment.