diff --git a/_typos.toml b/_typos.toml index eb5fee45af33..5e78f814e20b 100644 --- a/_typos.toml +++ b/_typos.toml @@ -13,6 +13,7 @@ extend-ignore-re = [ "eb1ba5f5", "github_pat_[0-9a-zA-Z_]+", "LICENSEs", + "astroid", ] [default.extend-identifiers] diff --git a/crates/uv-resolver/src/python_requirement.rs b/crates/uv-resolver/src/python_requirement.rs index 66cc7c9aa96e..caabeabf77c9 100644 --- a/crates/uv-resolver/src/python_requirement.rs +++ b/crates/uv-resolver/src/python_requirement.rs @@ -50,7 +50,19 @@ impl PythonRequirement { /// Narrow the [`PythonRequirement`] to the given version, if it's stricter (i.e., greater) /// than the current `Requires-Python` minimum. - pub fn narrow(&self, target: &RequiresPythonBound) -> Option { + pub fn narrow(&self, _target: &RequiresPythonBound) -> Option { + // This represents a "small revert" of the PR that added + // Requires-Python version narrowing[1]. But narrowing has + // led to at least one bug[2] whose fix is not clear. We + // decided to revert narrowing under the idea that it is better + // to be strict (i.e., fail to resolve in some cases, like + // universal_requires_python in uv/tests/pip_compile) than it + // is to output an incorrect lock, as in [2]. + // + // [1]: https://github.com/astral-sh/uv/pull/4707 + // [2]: https://github.com/astral-sh/uv/issues/4885 + None + /* let Some(PythonTarget::RequiresPython(requires_python)) = self.target.as_ref() else { return None; }; @@ -59,6 +71,7 @@ impl PythonRequirement { installed: self.installed.clone(), target: Some(PythonTarget::RequiresPython(requires_python)), }) + */ } /// Return the installed version of Python. diff --git a/crates/uv/tests/pip_compile.rs b/crates/uv/tests/pip_compile.rs index c9db3e355657..3d20c295f0f6 100644 --- a/crates/uv/tests/pip_compile.rs +++ b/crates/uv/tests/pip_compile.rs @@ -6624,6 +6624,14 @@ fn universal_multi_version() -> Result<()> { /// Perform a universal resolution that requires narrowing the supported Python range in one of the /// fork branches. +/// +/// Note that this test is currently asserted to be a failed resolution, which is part of +/// a small revert of the PR[1] that added Requires-Python version narrowing. This test +/// should ideally pass, but we aren't sure how to make it pass without producing +/// incorrect answers in other cases[2]. +/// +/// [1]: https://github.com/astral-sh/uv/pull/4707 +/// [2]: https://github.com/astral-sh/uv/issues/4885 #[test] fn universal_requires_python() -> Result<()> { let context = TestContext::new("3.12"); @@ -6633,6 +6641,53 @@ fn universal_requires_python() -> Result<()> { numpy <1.26 ; python_version < '3.9' "})?; + uv_snapshot!(context.filters(), windows_filters=false, context.pip_compile() + .arg("requirements.in") + .arg("-p") + .arg("3.8") + .arg("--universal"), @r###" + success: false + exit_code: 1 + ----- stdout ----- + + ----- stderr ----- + warning: The requested Python version 3.8 is not available; 3.12.[X] will be used to build dependencies instead. + × No solution found when resolving dependencies: + ╰─▶ Because only the following versions of numpy{python_version >= '3.9'} are available: + numpy{python_version >= '3.9'}<=1.26.0 + numpy{python_version >= '3.9'}==1.26.1 + numpy{python_version >= '3.9'}==1.26.2 + numpy{python_version >= '3.9'}==1.26.3 + numpy{python_version >= '3.9'}==1.26.4 + and the requested Python version (>=3.8) does not satisfy Python>=3.9, we can conclude that any of: + numpy{python_version >= '3.9'}>=1.26.0,<1.26.2 + numpy{python_version >= '3.9'}>1.26.2,<1.26.3 + numpy{python_version >= '3.9'}>1.26.3,<1.26.4 + numpy{python_version >= '3.9'}>1.26.4 + are incompatible. + And because the requested Python version (>=3.8) does not satisfy Python>=3.9 and you require numpy{python_version >= '3.9'}>=1.26, we can conclude that the requirements are unsatisfiable. + "### + ); + + Ok(()) +} + +// This test captures a case[1] that was broken by Requires-Python version +// narrowing[2] in the universal resolver. When version narrowing is enabled +// (at time of writing), the `requirements.txt` generated includes several +// duplicate and unconditional dependencies without marker expressions. +// +// [1]: https://github.com/astral-sh/uv/issues/4885 +// [2]: https://github.com/astral-sh/uv/pull/4707 +#[test] +fn universal_no_repeated_unconditional_distributions() -> Result<()> { + let context = TestContext::new("3.12"); + let requirements_in = context.temp_dir.child("requirements.in"); + requirements_in.write_str(indoc::indoc! {r" + pylint + sphinx + "})?; + uv_snapshot!(context.filters(), windows_filters=false, context.pip_compile() .arg("requirements.in") .arg("-p") @@ -6643,14 +6698,82 @@ fn universal_requires_python() -> Result<()> { ----- stdout ----- # This file was autogenerated by uv via the following command: # uv pip compile --cache-dir [CACHE_DIR] requirements.in -p 3.8 --universal - numpy==1.24.4 ; python_version < '3.9' + alabaster==0.7.13 + # via sphinx + astroid==3.1.0 + # via pylint + babel==2.14.0 + # via sphinx + certifi==2024.2.2 + # via requests + charset-normalizer==3.3.2 + # via requests + colorama==0.4.6 ; sys_platform == 'win32' + # via + # pylint + # sphinx + dill==0.3.8 + # via pylint + docutils==0.20.1 + # via sphinx + idna==3.6 + # via requests + imagesize==1.4.1 + # via sphinx + importlib-metadata==7.1.0 ; python_version < '3.10' + # via sphinx + isort==5.13.2 + # via pylint + jinja2==3.1.3 + # via sphinx + markupsafe==2.1.5 + # via jinja2 + mccabe==0.7.0 + # via pylint + packaging==24.0 + # via sphinx + platformdirs==4.2.0 + # via pylint + pygments==2.17.2 + # via sphinx + pylint==3.1.0 # via -r requirements.in - numpy==1.26.4 ; python_version >= '3.9' + pytz==2024.1 ; python_version < '3.9' + # via babel + requests==2.31.0 + # via sphinx + snowballstemmer==2.2.0 + # via sphinx + sphinx==7.1.2 # via -r requirements.in + sphinxcontrib-applehelp==1.0.4 + # via sphinx + sphinxcontrib-devhelp==1.0.2 + # via sphinx + sphinxcontrib-htmlhelp==2.0.1 + # via sphinx + sphinxcontrib-jsmath==1.0.1 + # via sphinx + sphinxcontrib-qthelp==1.0.3 + # via sphinx + sphinxcontrib-serializinghtml==1.1.5 + # via sphinx + tomli==2.0.1 ; python_version < '3.11' + # via pylint + tomlkit==0.12.4 + # via pylint + typing-extensions==4.10.0 ; python_version < '3.11' + # via + # astroid + # pylint + urllib3==2.2.1 + # via requests + zipp==3.18.1 ; python_version < '3.10' + # via importlib-metadata ----- stderr ----- warning: The requested Python version 3.8 is not available; 3.12.[X] will be used to build dependencies instead. - Resolved 2 packages in [TIME] + Resolved 34 packages in [TIME] "### );