diff --git a/crates/puffin-resolver/src/pubgrub/report.rs b/crates/puffin-resolver/src/pubgrub/report.rs index e428b2dfdf59..a1716b88589e 100644 --- a/crates/puffin-resolver/src/pubgrub/report.rs +++ b/crates/puffin-resolver/src/pubgrub/report.rs @@ -31,6 +31,23 @@ impl ReportFormatter> for PubGrubReportFormatter< format!("we are solving dependencies of {package} {version}") } External::NoVersions(package, set) => { + if matches!(package, PubGrubPackage::Python(_)) { + // We assume there is _only_ one available Python version as Puffin only supports + // resolution for a single Python version; if this is not the case for some reason + // we'll just fall back to the usual verbose message in production but panic in + // debug builds + if let Some([version]) = self.available_versions.get(package).map(Vec::as_slice) + { + return format!( + "{package} {version} does not satisfy {}", + PackageRange::compatibility(package, set) + ); + } + debug_assert!( + false, + "Unexpected value for available Python versions will degrade error message" + ); + } let set = self.simplify_set(set, package); if set.as_ref() == &Range::full() { format!("there are no versions of {package}") diff --git a/crates/puffin/tests/pip_compile.rs b/crates/puffin/tests/pip_compile.rs index 980a19bf9429..88a63d4b7a19 100644 --- a/crates/puffin/tests/pip_compile.rs +++ b/crates/puffin/tests/pip_compile.rs @@ -687,9 +687,9 @@ fn compile_python_37() -> Result<()> { ----- stderr ----- × No solution found when resolving dependencies: - ╰─▶ Because there are no versions of Python that satisfy Python>=3.8 - and black==23.10.1 depends on Python>=3.8, we can conclude that - black==23.10.1 cannot be used. + ╰─▶ Because Python 3.7.17 does not satisfy Python>=3.8 and black==23.10.1 + depends on Python>=3.8, we can conclude that black==23.10.1 cannot be + used. And because root depends on black==23.10.1 we can conclude that the requirements are unsatisfiable. "###); diff --git a/crates/puffin/tests/pip_install_scenarios.rs b/crates/puffin/tests/pip_install_scenarios.rs index c6d91243f9ce..1d3e0ba0aa8e 100644 --- a/crates/puffin/tests/pip_install_scenarios.rs +++ b/crates/puffin/tests/pip_install_scenarios.rs @@ -2529,7 +2529,7 @@ fn requires_python_version_does_not_exist() -> Result<()> { ----- stderr ----- × No solution found when resolving dependencies: - ╰─▶ Because there are no versions of Python that satisfy Python>=4.0 and a==1.0.0 depends on Python>=4.0, we can conclude that a==1.0.0 cannot be used. + ╰─▶ Because Python 3.7 does not satisfy Python>=4.0 and a==1.0.0 depends on Python>=4.0, we can conclude that a==1.0.0 cannot be used. And because root depends on a==1.0.0 we can conclude that the requirements are unsatisfiable. "###); }); @@ -2585,7 +2585,7 @@ fn requires_python_version_less_than_current() -> Result<()> { ----- stderr ----- × No solution found when resolving dependencies: - ╰─▶ Because there are no versions of Python that satisfy Python<=3.8 and a==1.0.0 depends on Python<=3.8, we can conclude that a==1.0.0 cannot be used. + ╰─▶ Because Python 3.9 does not satisfy Python<=3.8 and a==1.0.0 depends on Python<=3.8, we can conclude that a==1.0.0 cannot be used. And because root depends on a==1.0.0 we can conclude that the requirements are unsatisfiable. "###); }); @@ -2641,7 +2641,7 @@ fn requires_python_version_greater_than_current() -> Result<()> { ----- stderr ----- × No solution found when resolving dependencies: - ╰─▶ Because there are no versions of Python that satisfy Python>=3.10 and a==1.0.0 depends on Python>=3.10, we can conclude that a==1.0.0 cannot be used. + ╰─▶ Because Python 3.9 does not satisfy Python>=3.10 and a==1.0.0 depends on Python>=3.10, we can conclude that a==1.0.0 cannot be used. And because root depends on a==1.0.0 we can conclude that the requirements are unsatisfiable. "###); }); @@ -2846,22 +2846,22 @@ fn requires_python_version_greater_than_current_excluded() -> Result<()> { ----- stderr ----- × No solution found when resolving dependencies: - ╰─▶ Because there are no versions of Python that satisfy Python>=3.10,<3.11 and there are no versions of Python that satisfy Python>=3.12, we can conclude that any of: + ╰─▶ Because Python 3.9 does not satisfy Python>=3.10,<3.11 and Python 3.9 does not satisfy Python>=3.12, we can conclude that any of: Python>=3.10,<3.11 Python>=3.12 are incompatible. - And because there are no versions of Python that satisfy Python>=3.11,<3.12 we can conclude that Python>=3.10 are incompatible. + And because Python 3.9 does not satisfy Python>=3.11,<3.12 we can conclude that Python>=3.10 are incompatible. And because a==2.0.0 depends on Python>=3.10 and there are no versions of a that satisfy any of: a>2.0.0,<3.0.0 a>3.0.0,<4.0.0 a>4.0.0 we can conclude that a>=2.0.0,<3.0.0 cannot be used. (1) - Because there are no versions of Python that satisfy Python>=3.11,<3.12 and there are no versions of Python that satisfy Python>=3.12, we can conclude that Python>=3.11 are incompatible. + Because Python 3.9 does not satisfy Python>=3.11,<3.12 and Python 3.9 does not satisfy Python>=3.12, we can conclude that Python>=3.11 are incompatible. And because a==3.0.0 depends on Python>=3.11 we can conclude that a==3.0.0 cannot be used. And because we know from (1) that a>=2.0.0,<3.0.0 cannot be used, we can conclude that a>=2.0.0,<4.0.0 cannot be used. (2) - Because there are no versions of Python that satisfy Python>=3.12 and a==4.0.0 depends on Python>=3.12, we can conclude that a==4.0.0 cannot be used. + Because Python 3.9 does not satisfy Python>=3.12 and a==4.0.0 depends on Python>=3.12, we can conclude that a==4.0.0 cannot be used. And because we know from (2) that a>=2.0.0,<4.0.0 cannot be used, we can conclude that a>=2.0.0 cannot be used. And because root depends on a>=2.0.0 we can conclude that the requirements are unsatisfiable. "###);