From a2efd74209f2ae7b5ada27bcbc40356ac471aa32 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Mon, 22 Jan 2024 14:31:06 -0600 Subject: [PATCH] Add complex Python requirement scenarios (#1041) Follows #1011 with some more scenarios --- crates/puffin/tests/pip_compile_scenarios.rs | 273 ++++++++++++++++++- crates/puffin/tests/pip_install_scenarios.rs | 2 +- scripts/scenarios/update.py | 2 +- 3 files changed, 268 insertions(+), 9 deletions(-) diff --git a/crates/puffin/tests/pip_compile_scenarios.rs b/crates/puffin/tests/pip_compile_scenarios.rs index a56417ae5..2c447b9e1 100644 --- a/crates/puffin/tests/pip_compile_scenarios.rs +++ b/crates/puffin/tests/pip_compile_scenarios.rs @@ -1,7 +1,7 @@ //! DO NOT EDIT //! //! Generated with ./scripts/scenarios/update.py -//! Scenarios from +//! Scenarios from //! #![cfg(all(feature = "python", feature = "pypi"))] @@ -16,14 +16,14 @@ use common::{create_venv, BIN_NAME, INSTA_FILTERS}; mod common; -/// requires-python-version-greater-than-current-resolver-override +/// requires-incompatible-python-version-compatible-override /// /// The user requires a package which requires a Python version greater than the /// current version, but they use an alternative Python version for package /// resolution. /// /// ```text -/// b6505624 +/// 818d78ce /// ├── environment /// │ └── python3.9 /// ├── root @@ -34,18 +34,18 @@ mod common; /// └── requires python>=3.10 (incompatible with environment) /// ``` #[test] -fn requires_python_version_greater_than_current_resolver_override() -> Result<()> { +fn requires_incompatible_python_version_compatible_override() -> Result<()> { let temp_dir = assert_fs::TempDir::new()?; let cache_dir = assert_fs::TempDir::new()?; let venv = create_venv(&temp_dir, &cache_dir, "python3.9"); // In addition to the standard filters, swap out package names for more realistic messages let mut filters = INSTA_FILTERS.to_vec(); - filters.push((r"a-b6505624", "albatross")); - filters.push((r"-b6505624", "")); + filters.push((r"a-818d78ce", "albatross")); + filters.push((r"-818d78ce", "")); let requirements_in = temp_dir.child("requirements.in"); - requirements_in.write_str("a-b6505624==1.0.0")?; + requirements_in.write_str("a-818d78ce==1.0.0")?; insta::with_settings!({ filters => filters @@ -76,3 +76,262 @@ fn requires_python_version_greater_than_current_resolver_override() -> Result<() Ok(()) } + +/// requires-compatible-python-version-incompatible-override +/// +/// The user requires a package which requires a compatible Python version, but they +/// request an incompatible Python version for package resolution. +/// +/// ```text +/// e94b8bc2 +/// ├── environment +/// │ └── python3.11 +/// ├── root +/// │ └── requires a==1.0.0 +/// │ └── satisfied by a-1.0.0 +/// └── a +/// └── a-1.0.0 +/// └── requires python>=3.10 +/// ``` +#[test] +fn requires_compatible_python_version_incompatible_override() -> Result<()> { + let temp_dir = assert_fs::TempDir::new()?; + let cache_dir = assert_fs::TempDir::new()?; + let venv = create_venv(&temp_dir, &cache_dir, "python3.11"); + + // In addition to the standard filters, swap out package names for more realistic messages + let mut filters = INSTA_FILTERS.to_vec(); + filters.push((r"a-e94b8bc2", "albatross")); + filters.push((r"-e94b8bc2", "")); + + let requirements_in = temp_dir.child("requirements.in"); + requirements_in.write_str("a-e94b8bc2==1.0.0")?; + + insta::with_settings!({ + filters => filters + }, { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .arg("pip") + .arg("compile") + .arg("requirements.in") + .arg("--python-version=3.9") + .arg("--extra-index-url") + .arg("https://test.pypi.org/simple") + .arg("--cache-dir") + .arg(cache_dir.path()) + .env("VIRTUAL_ENV", venv.as_os_str()) + .env("PUFFIN_NO_WRAP", "1") + .current_dir(&temp_dir), @r###" + success: false + exit_code: 1 + ----- stdout ----- + + ----- stderr ----- + × No solution found when resolving dependencies: + ╰─▶ Because the requested Python version (3.9.18) does not satisfy Python>=3.10 and albatross==1.0.0 depends on Python>=3.10, we can conclude that albatross==1.0.0 cannot be used. + And because you require albatross==1.0.0 we can conclude that the requirements are unsatisfiable. + "###); + }); + + Ok(()) +} + +/// requires-incompatible-python-version-compatible-override-no-wheels +/// +/// The user requires a package which requires a incompatible Python version, but +/// they request a compatible Python version for package resolution. There are only +/// source distributions available for the package. +/// +/// ```text +/// 367303df +/// ├── environment +/// │ └── python3.9 +/// ├── root +/// │ └── requires a==1.0.0 +/// │ └── satisfied by a-1.0.0 +/// └── a +/// └── a-1.0.0 +/// └── requires python>=3.10 (incompatible with environment) +/// ``` +#[test] +fn requires_incompatible_python_version_compatible_override_no_wheels() -> Result<()> { + let temp_dir = assert_fs::TempDir::new()?; + let cache_dir = assert_fs::TempDir::new()?; + let venv = create_venv(&temp_dir, &cache_dir, "python3.9"); + + // In addition to the standard filters, swap out package names for more realistic messages + let mut filters = INSTA_FILTERS.to_vec(); + filters.push((r"a-367303df", "albatross")); + filters.push((r"-367303df", "")); + + let requirements_in = temp_dir.child("requirements.in"); + requirements_in.write_str("a-367303df==1.0.0")?; + + // Since there are no wheels for the package and it is not compatible with the + // local installation, we cannot build the source distribution to determine its + // dependencies. + insta::with_settings!({ + filters => filters + }, { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .arg("pip") + .arg("compile") + .arg("requirements.in") + .arg("--python-version=3.11") + .arg("--extra-index-url") + .arg("https://test.pypi.org/simple") + .arg("--cache-dir") + .arg(cache_dir.path()) + .env("VIRTUAL_ENV", venv.as_os_str()) + .env("PUFFIN_NO_WRAP", "1") + .current_dir(&temp_dir), @r###" + success: false + exit_code: 1 + ----- stdout ----- + + ----- stderr ----- + × No solution found when resolving dependencies: + ╰─▶ Because the current Python version (3.9.18) does not satisfy Python>=3.10 and albatross==1.0.0 depends on Python>=3.10, we can conclude that albatross==1.0.0 cannot be used. + And because you require albatross==1.0.0 we can conclude that the requirements are unsatisfiable. + "###); + }); + + Ok(()) +} + +/// requires-incompatible-python-version-compatible-override-no-compatible-wheels +/// +/// The user requires a package which requires a incompatible Python version, but +/// they request a compatible Python version for package resolution. There is a +/// wheel available for the package, but it does not have a compatible tag. +/// +/// ```text +/// 7d66d27e +/// ├── environment +/// │ └── python3.9 +/// ├── root +/// │ └── requires a==1.0.0 +/// │ └── satisfied by a-1.0.0 +/// └── a +/// └── a-1.0.0 +/// └── requires python>=3.10 (incompatible with environment) +/// ``` +#[test] +fn requires_incompatible_python_version_compatible_override_no_compatible_wheels() -> Result<()> { + let temp_dir = assert_fs::TempDir::new()?; + let cache_dir = assert_fs::TempDir::new()?; + let venv = create_venv(&temp_dir, &cache_dir, "python3.9"); + + // In addition to the standard filters, swap out package names for more realistic messages + let mut filters = INSTA_FILTERS.to_vec(); + filters.push((r"a-7d66d27e", "albatross")); + filters.push((r"-7d66d27e", "")); + + let requirements_in = temp_dir.child("requirements.in"); + requirements_in.write_str("a-7d66d27e==1.0.0")?; + + // Since there are no compatible wheels for the package and it is not compatible + // with the local installation, we cannot build the source distribution to + // determine its dependencies. + insta::with_settings!({ + filters => filters + }, { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .arg("pip") + .arg("compile") + .arg("requirements.in") + .arg("--python-version=3.11") + .arg("--extra-index-url") + .arg("https://test.pypi.org/simple") + .arg("--cache-dir") + .arg(cache_dir.path()) + .env("VIRTUAL_ENV", venv.as_os_str()) + .env("PUFFIN_NO_WRAP", "1") + .current_dir(&temp_dir), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: Package `albatross` was not found in the registry. + "###); + }); + + Ok(()) +} + +/// requires-incompatible-python-version-compatible-override-other-wheel +/// +/// The user requires a package which requires a incompatible Python version, but +/// they request a compatible Python version for package resolution. There are only +/// source distributions available for the compatible version of the package, but +/// there is an incompatible version with a wheel available. +/// +/// ```text +/// 47c905cb +/// ├── environment +/// │ └── python3.9 +/// ├── root +/// │ └── requires a +/// │ ├── satisfied by a-1.0.0 +/// │ └── satisfied by a-2.0.0 +/// └── a +/// ├── a-1.0.0 +/// │ └── requires python>=3.10 (incompatible with environment) +/// └── a-2.0.0 +/// └── requires python>=3.12 (incompatible with environment) +/// ``` +#[test] +fn requires_incompatible_python_version_compatible_override_other_wheel() -> Result<()> { + let temp_dir = assert_fs::TempDir::new()?; + let cache_dir = assert_fs::TempDir::new()?; + let venv = create_venv(&temp_dir, &cache_dir, "python3.9"); + + // In addition to the standard filters, swap out package names for more realistic messages + let mut filters = INSTA_FILTERS.to_vec(); + filters.push((r"a-47c905cb", "albatross")); + filters.push((r"-47c905cb", "")); + + let requirements_in = temp_dir.child("requirements.in"); + requirements_in.write_str("a-47c905cb")?; + + // Since there are no wheels for the version of the package compatible with the + // target and it is not compatible with the local installation, we cannot build the + // source distribution to determine its dependencies. The other version has wheels + // available, but is not compatible with the target version and cannot be used. + insta::with_settings!({ + filters => filters + }, { + assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME)) + .arg("pip") + .arg("compile") + .arg("requirements.in") + .arg("--python-version=3.11") + .arg("--extra-index-url") + .arg("https://test.pypi.org/simple") + .arg("--cache-dir") + .arg(cache_dir.path()) + .env("VIRTUAL_ENV", venv.as_os_str()) + .env("PUFFIN_NO_WRAP", "1") + .current_dir(&temp_dir), @r###" + success: false + exit_code: 1 + ----- stdout ----- + + ----- stderr ----- + × No solution found when resolving dependencies: + ╰─▶ Because the current Python version (3.9.18) does not satisfy Python>=3.10 and albatross==1.0.0 depends on Python>=3.10, we can conclude that albatross==1.0.0 cannot be used. + And because there are no versions of albatross that satisfy any of: + albatross<1.0.0 + albatross>1.0.0,<2.0.0 + albatross>2.0.0 + we can conclude that albatross<2.0.0 cannot be used. (1) + + Because the requested Python version (3.11.6) does not satisfy Python>=3.12 and albatross==2.0.0 depends on Python>=3.12, we can conclude that albatross==2.0.0 cannot be used. + And because we know from (1) that albatross<2.0.0 cannot be used, we can conclude that all versions of albatross cannot be used. + And because you require albatross we can conclude that the requirements are unsatisfiable. + "###); + }); + + Ok(()) +} diff --git a/crates/puffin/tests/pip_install_scenarios.rs b/crates/puffin/tests/pip_install_scenarios.rs index 9588b44d0..2c046e86f 100644 --- a/crates/puffin/tests/pip_install_scenarios.rs +++ b/crates/puffin/tests/pip_install_scenarios.rs @@ -1,7 +1,7 @@ //! DO NOT EDIT //! //! Generated with ./scripts/scenarios/update.py -//! Scenarios from +//! Scenarios from //! #![cfg(all(feature = "python", feature = "pypi"))] diff --git a/scripts/scenarios/update.py b/scripts/scenarios/update.py index b34740053..841e945ce 100755 --- a/scripts/scenarios/update.py +++ b/scripts/scenarios/update.py @@ -46,7 +46,7 @@ import textwrap from pathlib import Path -PACKSE_COMMIT = "9a836122ad43eb9c8115ef09f3beb7779512cd78" +PACKSE_COMMIT = "78f34eec66acfba9c723285764dc1f4b841f4961" TOOL_ROOT = Path(__file__).parent TEMPLATES = TOOL_ROOT / "templates" INSTALL_TEMPLATE = TEMPLATES / "install.mustache"