mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 13:25:00 +00:00
Default to current Python minor if Requires-Python
is absent (#4070)
## Summary If `Requires-Python` is omitted in `uv lock` or `uv run`, we now warn and default to `>=` the current minor version. Closes https://github.com/astral-sh/uv/issues/4050.
This commit is contained in:
parent
0b6d5b37dc
commit
e5f95186de
17 changed files with 92 additions and 15 deletions
|
@ -392,6 +392,14 @@ impl VersionSpecifier {
|
|||
}
|
||||
}
|
||||
|
||||
/// `>=<version>`
|
||||
pub fn greater_than_equal_version(version: Version) -> Self {
|
||||
Self {
|
||||
operator: Operator::GreaterThanEqual,
|
||||
version,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the operator, e.g. `>=` in `>= 2.0.0`
|
||||
pub fn operator(&self) -> &Operator {
|
||||
&self.operator
|
||||
|
|
|
@ -826,7 +826,7 @@ mod tests {
|
|||
"root": "[ROOT]/albatross-in-example/examples/bird-feeder",
|
||||
"project": {
|
||||
"name": "bird-feeder",
|
||||
"requires-python": null,
|
||||
"requires-python": ">=3.12",
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
|
@ -861,7 +861,7 @@ mod tests {
|
|||
"root": "[ROOT]/albatross-project-in-excluded/excluded/bird-feeder",
|
||||
"project": {
|
||||
"name": "bird-feeder",
|
||||
"requires-python": null,
|
||||
"requires-python": ">=3.12",
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
|
@ -895,7 +895,7 @@ mod tests {
|
|||
"root": "[ROOT]/albatross-root-workspace",
|
||||
"project": {
|
||||
"name": "albatross",
|
||||
"requires-python": null,
|
||||
"requires-python": ">=3.12",
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
|
@ -904,7 +904,7 @@ mod tests {
|
|||
"root": "[ROOT]/albatross-root-workspace/packages/bird-feeder",
|
||||
"project": {
|
||||
"name": "bird-feeder",
|
||||
"requires-python": null,
|
||||
"requires-python": ">=3.12",
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
|
@ -913,7 +913,7 @@ mod tests {
|
|||
"root": "[ROOT]/albatross-root-workspace/packages/seeds",
|
||||
"project": {
|
||||
"name": "seeds",
|
||||
"requires-python": null,
|
||||
"requires-python": ">=3.12",
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
|
@ -953,7 +953,7 @@ mod tests {
|
|||
"root": "[ROOT]/albatross-virtual-workspace/packages/albatross",
|
||||
"project": {
|
||||
"name": "albatross",
|
||||
"requires-python": null,
|
||||
"requires-python": ">=3.12",
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
|
@ -962,7 +962,7 @@ mod tests {
|
|||
"root": "[ROOT]/albatross-virtual-workspace/packages/bird-feeder",
|
||||
"project": {
|
||||
"name": "bird-feeder",
|
||||
"requires-python": null,
|
||||
"requires-python": ">=3.12",
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
|
@ -971,7 +971,7 @@ mod tests {
|
|||
"root": "[ROOT]/albatross-virtual-workspace/packages/seeds",
|
||||
"project": {
|
||||
"name": "seeds",
|
||||
"requires-python": null,
|
||||
"requires-python": ">=3.12",
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
|
@ -1005,7 +1005,7 @@ mod tests {
|
|||
"root": "[ROOT]/albatross-just-project",
|
||||
"project": {
|
||||
"name": "albatross",
|
||||
"requires-python": null,
|
||||
"requires-python": ">=3.12",
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
|
|
|
@ -209,16 +209,22 @@ impl Interpreter {
|
|||
Some(ExternallyManaged { error })
|
||||
}
|
||||
|
||||
/// Returns the Python version.
|
||||
/// Returns the `python_full_version` marker corresponding to this Python version.
|
||||
#[inline]
|
||||
pub fn python_full_version(&self) -> &StringVersion {
|
||||
self.markers.python_full_version()
|
||||
}
|
||||
|
||||
/// Returns the full Python version.
|
||||
#[inline]
|
||||
pub fn python_version(&self) -> &Version {
|
||||
&self.markers.python_full_version().version
|
||||
}
|
||||
|
||||
/// Returns the `python_full_version` marker corresponding to this Python version.
|
||||
/// Returns the full minor Python version.
|
||||
#[inline]
|
||||
pub fn python_full_version(&self) -> &StringVersion {
|
||||
self.markers.python_full_version()
|
||||
pub fn python_minor_version(&self) -> Version {
|
||||
Version::new(self.python_version().release().iter().take(2).copied())
|
||||
}
|
||||
|
||||
/// Return the major version of this Python version.
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use anstream::eprint;
|
||||
use anyhow::Result;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use distribution_types::{IndexLocations, UnresolvedRequirementSpecification};
|
||||
use install_wheel_rs::linker::LinkMode;
|
||||
use pep440_rs::{VersionSpecifier, VersionSpecifiers};
|
||||
use uv_cache::Cache;
|
||||
use uv_client::RegistryClientBuilder;
|
||||
use uv_configuration::{
|
||||
|
@ -91,11 +93,27 @@ pub(super) async fn do_lock(
|
|||
let source_trees = vec![];
|
||||
let project_name = project.project_name().clone();
|
||||
|
||||
// Determine the supported Python range. If no range is defined, and warn and default to the
|
||||
// current minor version.
|
||||
let requires_python = if let Some(requires_python) =
|
||||
project.current_project().project().requires_python.as_ref()
|
||||
{
|
||||
Cow::Borrowed(requires_python)
|
||||
} else {
|
||||
let requires_python = VersionSpecifiers::from(
|
||||
VersionSpecifier::greater_than_equal_version(venv.interpreter().python_minor_version()),
|
||||
);
|
||||
warn_user!(
|
||||
"No `requires-python` field found in `{}`. Defaulting to `{requires_python}`.",
|
||||
project.current_project().project().name,
|
||||
);
|
||||
Cow::Owned(requires_python)
|
||||
};
|
||||
|
||||
// Determine the tags, markers, and interpreter to use for resolution.
|
||||
let interpreter = venv.interpreter();
|
||||
let tags = venv.interpreter().tags()?;
|
||||
let markers = venv.interpreter().markers();
|
||||
let requires_python = project.current_project().project().requires_python.as_ref();
|
||||
|
||||
// Initialize the registry client.
|
||||
// TODO(zanieb): Support client options e.g. offline, tls, etc.
|
||||
|
@ -164,7 +182,7 @@ pub(super) async fn do_lock(
|
|||
interpreter,
|
||||
tags,
|
||||
None,
|
||||
requires_python,
|
||||
Some(&requires_python),
|
||||
&client,
|
||||
&flat_index,
|
||||
&index,
|
||||
|
|
|
@ -19,6 +19,7 @@ fn lock_wheel_registry() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["anyio==3.7.0"]
|
||||
"#,
|
||||
)?;
|
||||
|
@ -41,6 +42,7 @@ fn lock_wheel_registry() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[distribution]]
|
||||
name = "anyio"
|
||||
|
@ -143,6 +145,7 @@ fn lock_sdist_registry() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["source-distribution==0.0.1"]
|
||||
"#,
|
||||
)?;
|
||||
|
@ -165,6 +168,7 @@ fn lock_sdist_registry() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[distribution]]
|
||||
name = "project"
|
||||
|
@ -200,6 +204,7 @@ fn lock_sdist_git() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@0.0.1"]
|
||||
"#,
|
||||
)?;
|
||||
|
@ -222,6 +227,7 @@ fn lock_sdist_git() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[distribution]]
|
||||
name = "project"
|
||||
|
@ -271,6 +277,7 @@ fn lock_wheel_url() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["anyio @ https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl"]
|
||||
"#,
|
||||
)?;
|
||||
|
@ -293,6 +300,7 @@ fn lock_wheel_url() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[distribution]]
|
||||
name = "anyio"
|
||||
|
@ -394,6 +402,7 @@ fn lock_sdist_url() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["anyio @ https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz"]
|
||||
"#,
|
||||
)?;
|
||||
|
@ -416,6 +425,7 @@ fn lock_sdist_url() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[distribution]]
|
||||
name = "anyio"
|
||||
|
@ -517,6 +527,7 @@ fn lock_extra() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["anyio==3.7.0"]
|
||||
|
||||
[project.optional-dependencies]
|
||||
|
@ -542,6 +553,7 @@ fn lock_extra() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[distribution]]
|
||||
name = "anyio"
|
||||
|
@ -671,6 +683,7 @@ fn lock_preference() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["iniconfig<2"]
|
||||
"#,
|
||||
)?;
|
||||
|
@ -693,6 +706,7 @@ fn lock_preference() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[distribution]]
|
||||
name = "iniconfig"
|
||||
|
@ -721,6 +735,7 @@ fn lock_preference() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["iniconfig"]
|
||||
"#,
|
||||
)?;
|
||||
|
@ -744,6 +759,7 @@ fn lock_preference() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[distribution]]
|
||||
name = "iniconfig"
|
||||
|
@ -785,6 +801,7 @@ fn lock_preference() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[distribution]]
|
||||
name = "iniconfig"
|
||||
|
@ -822,6 +839,7 @@ fn lock_git_sha() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@0dacfd662c64cb4ceb16e6cf65a157a8b715b979"]
|
||||
"#,
|
||||
)?;
|
||||
|
@ -844,6 +862,7 @@ fn lock_git_sha() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[distribution]]
|
||||
name = "project"
|
||||
|
@ -876,6 +895,7 @@ fn lock_git_sha() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@main"]
|
||||
"#,
|
||||
)?;
|
||||
|
@ -900,6 +920,7 @@ fn lock_git_sha() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[distribution]]
|
||||
name = "project"
|
||||
|
@ -942,6 +963,7 @@ fn lock_git_sha() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[distribution]]
|
||||
name = "project"
|
||||
|
|
|
@ -44,6 +44,7 @@ fn fork_basic() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.8"
|
||||
dependencies = [
|
||||
'''fork-basic-a>=2; sys_platform == "linux"''',
|
||||
'''fork-basic-a<2; sys_platform == "darwin"''',
|
||||
|
@ -72,6 +73,7 @@ fn fork_basic() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.8"
|
||||
|
||||
[[distribution]]
|
||||
name = "package-a"
|
||||
|
@ -151,6 +153,7 @@ fn fork_marker_accrue() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.8"
|
||||
dependencies = [
|
||||
'''fork-marker-accrue-a==1.0.0; implementation_name == "cpython"''',
|
||||
'''fork-marker-accrue-b==1.0.0; implementation_name == "pypy"''',
|
||||
|
@ -179,6 +182,7 @@ fn fork_marker_accrue() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.8"
|
||||
|
||||
[[distribution]]
|
||||
name = "package-a"
|
||||
|
@ -277,6 +281,7 @@ fn fork_marker_selection() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.8"
|
||||
dependencies = [
|
||||
'''fork-marker-selection-a''',
|
||||
'''fork-marker-selection-b>=2; sys_platform == "linux"''',
|
||||
|
@ -306,6 +311,7 @@ fn fork_marker_selection() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.8"
|
||||
|
||||
[[distribution]]
|
||||
name = "package-a"
|
||||
|
@ -426,6 +432,7 @@ fn fork_marker_track() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.8"
|
||||
dependencies = [
|
||||
'''fork-marker-track-a''',
|
||||
'''fork-marker-track-b>=2.8; sys_platform == "linux"''',
|
||||
|
@ -455,6 +462,7 @@ fn fork_marker_track() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.8"
|
||||
|
||||
[[distribution]]
|
||||
name = "package-a"
|
||||
|
@ -575,6 +583,7 @@ fn fork_non_fork_marker_transitive() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.8"
|
||||
dependencies = [
|
||||
'''fork-non-fork-marker-transitive-a==1.0.0''',
|
||||
'''fork-non-fork-marker-transitive-b==1.0.0''',
|
||||
|
@ -603,6 +612,7 @@ fn fork_non_fork_marker_transitive() -> Result<()> {
|
|||
assert_snapshot!(
|
||||
lock, @r###"
|
||||
version = 1
|
||||
requires-python = ">=3.8"
|
||||
|
||||
[[distribution]]
|
||||
name = "package-a"
|
||||
|
@ -698,6 +708,7 @@ fn fork_non_local_fork_marker_direct() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.8"
|
||||
dependencies = [
|
||||
'''fork-non-local-fork-marker-direct-a==1.0.0; sys_platform == "linux"''',
|
||||
'''fork-non-local-fork-marker-direct-b==1.0.0; sys_platform == "darwin"''',
|
||||
|
@ -771,6 +782,7 @@ fn fork_non_local_fork_marker_transitive() -> Result<()> {
|
|||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.8"
|
||||
dependencies = [
|
||||
'''fork-non-local-fork-marker-transitive-a==1.0.0''',
|
||||
'''fork-non-local-fork-marker-transitive-b==1.0.0''',
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[project]
|
||||
name = "bird-feeder"
|
||||
version = "1.0.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["anyio>=4.3.0,<5"]
|
||||
|
||||
[build-system]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[project]
|
||||
name = "albatross"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["tqdm>=4,<5"]
|
||||
|
||||
[build-system]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[project]
|
||||
name = "albatross"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["tqdm>=4,<5"]
|
||||
|
||||
[build-system]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[project]
|
||||
name = "bird-feeder"
|
||||
version = "1.0.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["anyio>=4.3.0,<5"]
|
||||
|
||||
[build-system]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[project]
|
||||
name = "albatross"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["tqdm>=4,<5"]
|
||||
|
||||
[tool.uv.workspace]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[project]
|
||||
name = "bird-feeder"
|
||||
version = "1.0.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["anyio>=4.3.0,<5", "seeds"]
|
||||
|
||||
[tool.uv.sources]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[project]
|
||||
name = "seeds"
|
||||
version = "1.0.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["idna==3.6"]
|
||||
|
||||
[build-system]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[project]
|
||||
name = "albatross"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["bird-feeder", "tqdm>=4,<5"]
|
||||
|
||||
[tool.uv.sources]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[project]
|
||||
name = "albatross"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["bird-feeder", "tqdm>=4,<5"]
|
||||
|
||||
[tool.uv.sources]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[project]
|
||||
name = "bird-feeder"
|
||||
version = "1.0.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["anyio>=4.3.0,<5", "seeds"]
|
||||
|
||||
[tool.uv.sources]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[project]
|
||||
name = "seeds"
|
||||
version = "1.0.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["idna==3.6"]
|
||||
|
||||
[build-system]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue