@@ -11,11 +11,14 @@ use flate2::write::GzEncoder;
1111use fs_err::File;
1212use indoc::indoc;
1313use url::Url;
14+ use wiremock::matchers::{method, path};
15+ use wiremock::{Mock, MockServer, ResponseTemplate};
1416
15- use crate::common::{download_to_disk, packse_index_url, uv_snapshot, TestContext};
1617use uv_fs::Simplified;
1718use uv_static::EnvVars;
1819
20+ use crate::common::{download_to_disk, packse_index_url, uv_snapshot, TestContext};
21+
1922#[test]
2023fn compile_requirements_in() -> Result<()> {
2124 let context = TestContext::new("3.12");
@@ -9508,7 +9511,7 @@ fn universal_marker_propagation() -> Result<()> {
95089511 .arg("requirements.in")
95099512 .arg("-p")
95109513 .arg("3.8")
9511- .arg("--universal"), @r### "
9514+ .arg("--universal"), @r"
95129515 success: true
95139516 exit_code: 0
95149517 ----- stdout -----
@@ -9536,9 +9539,11 @@ fn universal_marker_propagation() -> Result<()> {
95369539 # via jinja2
95379540 mpmath==1.3.0
95389541 # via sympy
9539- networkx==3.2.1
9542+ networkx==3.1 ; python_full_version < '3.9'
9543+ # via torch
9544+ networkx==3.2 ; python_full_version >= '3.9'
95409545 # via torch
9541- numpy==1.26.3 ; python_full_version < '3.9'
9546+ numpy==1.24.4 ; python_full_version < '3.9'
95429547 # via torchvision
95439548 numpy==1.26.4 ; python_full_version >= '3.9'
95449549 # via torchvision
@@ -9576,8 +9581,8 @@ fn universal_marker_propagation() -> Result<()> {
95769581
95779582 ----- stderr -----
95789583 warning: The requested Python version 3.8 is not available; 3.12.[X] will be used to build dependencies instead.
9579- Resolved 25 packages in [TIME]
9580- "###
9584+ Resolved 26 packages in [TIME]
9585+ "
95819586 );
95829587
95839588 Ok(())
@@ -17223,3 +17228,75 @@ fn pep_751_compile_no_emit_package() -> Result<()> {
1722317228
1722417229 Ok(())
1722517230}
17231+
17232+ /// Check that we reject versions that have an incompatible `Requires-Python`, but don't
17233+ /// have a `data-requires-python` key on the index page.
17234+ #[tokio::test]
17235+ async fn index_has_no_requires_python() -> Result<()> {
17236+ let context = TestContext::new_with_versions(&["3.9", "3.12"]);
17237+ let server = MockServer::start().await;
17238+
17239+ // Unlike PyPI, https://download.pytorch.org/whl/cpu/networkx/ does not contain the
17240+ // `data-requires-python` key.
17241+ let networkx_page = r#"
17242+ <!DOCTYPE html>
17243+ <html>
17244+ <body>
17245+ <h1>Links for networkx</h1>
17246+ <a href="https://download.pytorch.org/whl/networkx-3.0-py3-none-any.whl#sha256=58058d66b1818043527244fab9d41a51fcd7dcc271748015f3c181b8a90c8e2e">networkx-3.0-py3-none-any.whl</a><br/>
17247+ <a href="https://download.pytorch.org/whl/networkx-3.2.1-py3-none-any.whl#sha256=f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2">networkx-3.2.1-py3-none-any.whl</a><br/>
17248+ <a href="https://download.pytorch.org/whl/networkx-3.3-py3-none-any.whl#sha256=28575580c6ebdaf4505b22c6256a2b9de86b316dc63ba9e93abde3d78dfdbcf2">networkx-3.3-py3-none-any.whl</a><br/>
17249+ </body>
17250+ </html>
17251+ "#;
17252+ Mock::given(method("GET"))
17253+ .and(path("/networkx/"))
17254+ .respond_with(ResponseTemplate::new(200).set_body_raw(networkx_page, "text/html"))
17255+ .mount(&server)
17256+ .await;
17257+
17258+ let requirements_in = context.temp_dir.child("requirements.in");
17259+ requirements_in.write_str("networkx >3.0,<=3.3")?;
17260+
17261+ uv_snapshot!(context
17262+ .pip_compile()
17263+ .env_remove(EnvVars::UV_EXCLUDE_NEWER)
17264+ .arg("--python")
17265+ .arg("3.9")
17266+ .arg("--index-url")
17267+ .arg(server.uri())
17268+ .arg("requirements.in"), @r"
17269+ success: true
17270+ exit_code: 0
17271+ ----- stdout -----
17272+ # This file was autogenerated by uv via the following command:
17273+ # uv pip compile --cache-dir [CACHE_DIR] --python 3.9 requirements.in
17274+ networkx==3.2.1
17275+ # via -r requirements.in
17276+
17277+ ----- stderr -----
17278+ Resolved 1 package in [TIME]
17279+ ");
17280+
17281+ uv_snapshot!(context
17282+ .pip_compile()
17283+ .env_remove(EnvVars::UV_EXCLUDE_NEWER)
17284+ .arg("--python")
17285+ .arg("3.12")
17286+ .arg("--index-url")
17287+ .arg(server.uri())
17288+ .arg("requirements.in"), @r"
17289+ success: true
17290+ exit_code: 0
17291+ ----- stdout -----
17292+ # This file was autogenerated by uv via the following command:
17293+ # uv pip compile --cache-dir [CACHE_DIR] --python 3.12 requirements.in
17294+ networkx==3.3
17295+ # via -r requirements.in
17296+
17297+ ----- stderr -----
17298+ Resolved 1 package in [TIME]
17299+ ");
17300+
17301+ Ok(())
17302+ }
0 commit comments