mirror of https://github.com/astral-sh/uv
Avoid un-strict syncing by-default for build isolation (#6606)
## Summary Closes https://github.com/astral-sh/uv/issues/6580. Closes https://github.com/astral-sh/uv/issues/6599.
This commit is contained in:
parent
a7850d2a1c
commit
023acbe4b0
|
|
@ -2261,10 +2261,7 @@ pub struct SyncArgs {
|
|||
/// Do not remove extraneous packages present in the environment.
|
||||
///
|
||||
/// When enabled, uv will make the minimum necessary changes to satisfy the requirements.
|
||||
///
|
||||
/// By default, syncing will remove any extraneous packages from the environment, unless
|
||||
/// `--no-build-isolation` is enabled, in which case extra packages are considered necessary for
|
||||
/// builds.
|
||||
/// By default, syncing will remove any extraneous packages from the environment
|
||||
#[arg(long, overrides_with("exact"), alias = "no-exact")]
|
||||
pub inexact: bool,
|
||||
|
||||
|
|
|
|||
|
|
@ -621,6 +621,7 @@ impl PythonPinSettings {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The resolved settings to use for a `sync` invocation.
|
||||
#[allow(clippy::struct_excessive_bools, dead_code)]
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -668,16 +669,6 @@ impl SyncSettings {
|
|||
filesystem,
|
||||
);
|
||||
|
||||
let exact = flag(exact, inexact).unwrap_or(true);
|
||||
|
||||
// By default, sync with exact semantics, unless the user set `--no-build-isolation`;
|
||||
// otherwise, we'll end up removing build dependencies.
|
||||
let modifications = if !exact || settings.no_build_isolation {
|
||||
Modifications::Sufficient
|
||||
} else {
|
||||
Modifications::Exact
|
||||
};
|
||||
|
||||
Self {
|
||||
locked,
|
||||
frozen,
|
||||
|
|
@ -689,7 +680,11 @@ impl SyncSettings {
|
|||
no_install_project,
|
||||
no_install_workspace,
|
||||
no_install_package,
|
||||
modifications,
|
||||
modifications: if flag(exact, inexact).unwrap_or(true) {
|
||||
Modifications::Exact
|
||||
} else {
|
||||
Modifications::Sufficient
|
||||
},
|
||||
package,
|
||||
python,
|
||||
refresh: Refresh::from(refresh),
|
||||
|
|
|
|||
|
|
@ -428,6 +428,7 @@ fn virtual_workspace_dev_dependencies() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Use a `pip install` step to pre-install build dependencies for `--no-build-isolation`.
|
||||
#[test]
|
||||
fn sync_build_isolation() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
|
@ -479,9 +480,17 @@ fn sync_build_isolation() -> Result<()> {
|
|||
----- stderr -----
|
||||
Resolved 2 packages in [TIME]
|
||||
Prepared 2 packages in [TIME]
|
||||
Uninstalled 7 packages in [TIME]
|
||||
Installed 2 packages in [TIME]
|
||||
- hatchling==1.22.4
|
||||
- packaging==24.0
|
||||
- pathspec==0.12.1
|
||||
- pluggy==1.4.0
|
||||
+ project==0.1.0 (from file://[TEMP_DIR]/)
|
||||
- setuptools==69.2.0
|
||||
+ source-distribution==0.0.1 (from https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz)
|
||||
- trove-classifiers==2024.3.3
|
||||
- wheel==0.43.0
|
||||
"###);
|
||||
|
||||
assert!(context.temp_dir.child("uv.lock").exists());
|
||||
|
|
@ -489,6 +498,7 @@ fn sync_build_isolation() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Use a `pip install` step to pre-install build dependencies for `--no-build-isolation-package`.
|
||||
#[test]
|
||||
fn sync_build_isolation_package() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
|
@ -575,6 +585,118 @@ fn sync_build_isolation_package() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Use dedicated extra groups to install dependencies for `--no-build-isolation-package`.
|
||||
#[test]
|
||||
fn sync_build_isolation_extra() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||
pyproject_toml.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = []
|
||||
|
||||
[project.optional-dependencies]
|
||||
build = ["hatchling"]
|
||||
compile = ["source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz"]
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools >= 40.9.0"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.uv]
|
||||
no-build-isolation-package = ["source-distribution"]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
// Running `uv sync` should fail for the `compile` extra.
|
||||
let filters = std::iter::once((r"exit code: 1", "exit status: 1"))
|
||||
.chain(context.filters())
|
||||
.collect::<Vec<_>>();
|
||||
uv_snapshot!(&filters, context.sync().arg("--extra").arg("compile"), @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 7 packages in [TIME]
|
||||
error: Failed to prepare distributions
|
||||
Caused by: Failed to fetch wheel: source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz
|
||||
Caused by: Build backend failed to build wheel through `build_wheel()` with exit status: 1
|
||||
--- stdout:
|
||||
|
||||
--- stderr:
|
||||
Traceback (most recent call last):
|
||||
File "<string>", line 8, in <module>
|
||||
ModuleNotFoundError: No module named 'hatchling'
|
||||
---
|
||||
"###);
|
||||
|
||||
// Running `uv sync` with `--all-extras` should also fail.
|
||||
uv_snapshot!(&filters, context.sync().arg("--all-extras"), @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 7 packages in [TIME]
|
||||
error: Failed to prepare distributions
|
||||
Caused by: Failed to fetch wheel: source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz
|
||||
Caused by: Build backend failed to build wheel through `build_wheel()` with exit status: 1
|
||||
--- stdout:
|
||||
|
||||
--- stderr:
|
||||
Traceback (most recent call last):
|
||||
File "<string>", line 8, in <module>
|
||||
ModuleNotFoundError: No module named 'hatchling'
|
||||
---
|
||||
"###);
|
||||
|
||||
// Install the build dependencies.
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--extra").arg("build"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 7 packages in [TIME]
|
||||
Prepared 6 packages in [TIME]
|
||||
Installed 6 packages in [TIME]
|
||||
+ hatchling==1.22.4
|
||||
+ packaging==24.0
|
||||
+ pathspec==0.12.1
|
||||
+ pluggy==1.4.0
|
||||
+ project==0.1.0 (from file://[TEMP_DIR]/)
|
||||
+ trove-classifiers==2024.3.3
|
||||
"###);
|
||||
|
||||
// Running `uv sync` for the `compile` extra should succeed, and remove the build dependencies.
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--extra").arg("compile"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 7 packages in [TIME]
|
||||
Prepared 1 package in [TIME]
|
||||
Uninstalled 5 packages in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
- hatchling==1.22.4
|
||||
- packaging==24.0
|
||||
- pathspec==0.12.1
|
||||
- pluggy==1.4.0
|
||||
+ source-distribution==0.0.1 (from https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz)
|
||||
- trove-classifiers==2024.3.3
|
||||
"###);
|
||||
|
||||
assert!(context.temp_dir.child("uv.lock").exists());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Avoid using incompatible versions for build dependencies that are also part of the resolved
|
||||
/// environment. This is a very subtle issue, but: when locking, we don't enforce platform
|
||||
/// compatibility. So, if we reuse the resolver state to install, and the install itself has to
|
||||
|
|
|
|||
|
|
@ -1098,9 +1098,7 @@ uv sync [OPTIONS]
|
|||
|
||||
</dd><dt><code>--inexact</code></dt><dd><p>Do not remove extraneous packages present in the environment.</p>
|
||||
|
||||
<p>When enabled, uv will make the minimum necessary changes to satisfy the requirements.</p>
|
||||
|
||||
<p>By default, syncing will remove any extraneous packages from the environment, unless <code>--no-build-isolation</code> is enabled, in which case extra packages are considered necessary for builds.</p>
|
||||
<p>When enabled, uv will make the minimum necessary changes to satisfy the requirements. By default, syncing will remove any extraneous packages from the environment</p>
|
||||
|
||||
</dd><dt><code>--keyring-provider</code> <i>keyring-provider</i></dt><dd><p>Attempt to use <code>keyring</code> for authentication for index URLs.</p>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue