mirror of https://github.com/astral-sh/uv
Enforce `requires-python` in `pylock.toml` (#14787)
## Summary Turns out we weren't validating this at install-time.
This commit is contained in:
parent
d768dedff6
commit
aafeda2253
|
|
@ -186,7 +186,7 @@ pub struct PylockToml {
|
|||
lock_version: Version,
|
||||
created_by: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
requires_python: Option<RequiresPython>,
|
||||
pub requires_python: Option<RequiresPython>,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||
pub extras: Vec<ExtraName>,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||
|
|
|
|||
|
|
@ -444,6 +444,17 @@ pub(crate) async fn pip_install(
|
|||
format!("Not a valid `pylock.toml` file: {}", pylock.user_display())
|
||||
})?;
|
||||
|
||||
// Verify that the Python version is compatible with the lock file.
|
||||
if let Some(requires_python) = lock.requires_python.as_ref() {
|
||||
if !requires_python.contains(interpreter.python_version()) {
|
||||
return Err(anyhow::anyhow!(
|
||||
"The requested interpreter resolved to Python {}, which is incompatible with the `pylock.toml`'s Python requirement: `{}`",
|
||||
interpreter.python_version(),
|
||||
requires_python,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the extras and groups specifications into a concrete form.
|
||||
let extras = extras.with_defaults(DefaultExtras::default());
|
||||
let extras = extras
|
||||
|
|
|
|||
|
|
@ -382,6 +382,17 @@ pub(crate) async fn pip_sync(
|
|||
format!("Not a valid `pylock.toml` file: {}", pylock.user_display())
|
||||
})?;
|
||||
|
||||
// Verify that the Python version is compatible with the lock file.
|
||||
if let Some(requires_python) = lock.requires_python.as_ref() {
|
||||
if !requires_python.contains(interpreter.python_version()) {
|
||||
return Err(anyhow::anyhow!(
|
||||
"The requested interpreter resolved to Python {}, which is incompatible with the `pylock.toml`'s Python requirement: `{}`",
|
||||
interpreter.python_version(),
|
||||
requires_python,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the extras and groups specifications into a concrete form.
|
||||
let extras = extras.with_defaults(DefaultExtras::default());
|
||||
let extras = extras
|
||||
|
|
|
|||
|
|
@ -11590,6 +11590,51 @@ requires_python = "==3.13.*"
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_requires_python() -> Result<()> {
|
||||
let context = TestContext::new_with_versions(&["3.12", "3.13"]);
|
||||
|
||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||
pyproject_toml.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = ["iniconfig"]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
context
|
||||
.export()
|
||||
.arg("-o")
|
||||
.arg("pylock.toml")
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
context
|
||||
.venv()
|
||||
.arg("--python")
|
||||
.arg("3.12")
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_install()
|
||||
.arg("--preview")
|
||||
.arg("-r")
|
||||
.arg("pylock.toml"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: The requested interpreter resolved to Python 3.12.[X], which is incompatible with the `pylock.toml`'s Python requirement: `>=3.13`
|
||||
"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test that uv doesn't hang if an index returns a distribution for the wrong package.
|
||||
#[tokio::test]
|
||||
async fn bogus_redirect() -> Result<()> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue