mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-25 21:37:51 +00:00
Allow virtual packages with --no-build (#12314)
## Summary Closes #12311.
This commit is contained in:
parent
149102a4e7
commit
7ac6c6963d
4 changed files with 157 additions and 16 deletions
|
|
@ -639,6 +639,7 @@ impl SourceDist {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the [`Version`] of the distribution, if it is known.
|
||||
pub fn version(&self) -> Option<&Version> {
|
||||
match self {
|
||||
Self::Registry(source_dist) => Some(&source_dist.version),
|
||||
|
|
@ -646,7 +647,7 @@ impl SourceDist {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return true if the distribution is editable.
|
||||
/// Returns `true` if the distribution is editable.
|
||||
pub fn is_editable(&self) -> bool {
|
||||
match self {
|
||||
Self::Directory(DirectorySourceDist { editable, .. }) => *editable,
|
||||
|
|
@ -654,7 +655,15 @@ impl SourceDist {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return true if the distribution refers to a local file or directory.
|
||||
/// Returns `true` if the distribution is virtual.
|
||||
pub fn is_virtual(&self) -> bool {
|
||||
match self {
|
||||
Self::Directory(DirectorySourceDist { r#virtual, .. }) => *r#virtual,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the distribution refers to a local file or directory.
|
||||
pub fn is_local(&self) -> bool {
|
||||
matches!(self, Self::Directory(_) | Self::Path(_))
|
||||
}
|
||||
|
|
@ -668,7 +677,7 @@ impl SourceDist {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the source tree of the distribution, if available.
|
||||
/// Returns the source tree of the distribution, if available.
|
||||
pub fn source_tree(&self) -> Option<&Path> {
|
||||
match self {
|
||||
Self::Directory(dist) => Some(&dist.install_path),
|
||||
|
|
|
|||
|
|
@ -2196,8 +2196,11 @@ impl Package {
|
|||
};
|
||||
}
|
||||
|
||||
if !no_build {
|
||||
if let Some(sdist) = self.to_source_dist(workspace_root)? {
|
||||
// Even with `--no-build`, allow virtual packages. (In the future, we may want to allow
|
||||
// any local source tree, or at least editable source trees, which we allow in
|
||||
// `uv pip`.)
|
||||
if !no_build || sdist.is_virtual() {
|
||||
return Ok(Dist::Source(sdist));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23005,14 +23005,16 @@ fn lock_no_build_static_metadata() -> Result<()> {
|
|||
"###);
|
||||
|
||||
// Install from the lockfile.
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--no-build").arg("--frozen"), @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--no-build").arg("--frozen"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: Distribution `dummy==0.1.0 @ virtual+.` can't be installed because it is marked as `--no-build` but has no binary distribution
|
||||
"###);
|
||||
Prepared 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ iniconfig==2.0.0
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3544,6 +3544,133 @@ fn no_install_project_no_build() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn virtual_no_build() -> 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 = ["anyio==3.7.0"]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
// Generate a lockfile.
|
||||
context.lock().assert().success();
|
||||
|
||||
// Clear the cache.
|
||||
fs_err::remove_dir_all(&context.cache_dir)?;
|
||||
|
||||
// `--no-build` should not raise an error, since we don't install virtual projects.
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--no-build"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 4 packages in [TIME]
|
||||
Prepared 3 packages in [TIME]
|
||||
Installed 3 packages in [TIME]
|
||||
+ anyio==3.7.0
|
||||
+ idna==3.6
|
||||
+ sniffio==1.3.1
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn virtual_no_build_dynamic_cached() -> 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"
|
||||
dynamic = ["dependencies"]
|
||||
|
||||
[tool.setuptools.dynamic]
|
||||
dependencies = {file = ["requirements.txt"]}
|
||||
"#,
|
||||
)?;
|
||||
|
||||
context
|
||||
.temp_dir
|
||||
.child("requirements.txt")
|
||||
.write_str("anyio==3.7.0")?;
|
||||
|
||||
// Generate a lockfile.
|
||||
context.lock().assert().success();
|
||||
|
||||
// `--no-build` should not raise an error, since we don't build or install the project (given
|
||||
// that it's virtual and the metadata is cached).
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--no-build"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 4 packages in [TIME]
|
||||
Prepared 3 packages in [TIME]
|
||||
Installed 3 packages in [TIME]
|
||||
+ anyio==3.7.0
|
||||
+ idna==3.6
|
||||
+ sniffio==1.3.1
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn virtual_no_build_dynamic_no_cache() -> 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"
|
||||
dynamic = ["dependencies"]
|
||||
|
||||
[tool.setuptools.dynamic]
|
||||
dependencies = {file = ["requirements.txt"]}
|
||||
"#,
|
||||
)?;
|
||||
|
||||
context
|
||||
.temp_dir
|
||||
.child("requirements.txt")
|
||||
.write_str("anyio==3.7.0")?;
|
||||
|
||||
// Generate a lockfile.
|
||||
context.lock().assert().success();
|
||||
|
||||
// Clear the cache.
|
||||
fs_err::remove_dir_all(&context.cache_dir)?;
|
||||
|
||||
// `--no-build` should raise an error, since we need to build the project.
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--no-build"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: Failed to generate package metadata for `project==0.1.0 @ virtual+.`
|
||||
Caused by: Building source distributions for `project` is disabled
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Convert from a package to a virtual project.
|
||||
#[test]
|
||||
fn convert_to_virtual() -> Result<()> {
|
||||
|
|
@ -4815,25 +4942,25 @@ fn no_build_error() -> Result<()> {
|
|||
error: Distribution `django-allauth==0.51.0 @ registry+https://pypi.org/simple` can't be installed because it is marked as `--no-build` but has no binary distribution
|
||||
"###);
|
||||
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--no-build"), @r###"
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--no-build"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 19 packages in [TIME]
|
||||
error: Distribution `project==0.1.0 @ virtual+.` can't be installed because it is marked as `--no-build` but has no binary distribution
|
||||
"###);
|
||||
error: Distribution `django-allauth==0.51.0 @ registry+https://pypi.org/simple` can't be installed because it is marked as `--no-build` but has no binary distribution
|
||||
");
|
||||
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BUILD", "1"), @r###"
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BUILD", "1"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 19 packages in [TIME]
|
||||
error: Distribution `project==0.1.0 @ virtual+.` can't be installed because it is marked as `--no-build` but has no binary distribution
|
||||
"###);
|
||||
error: Distribution `django-allauth==0.51.0 @ registry+https://pypi.org/simple` can't be installed because it is marked as `--no-build` but has no binary distribution
|
||||
");
|
||||
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BUILD_PACKAGE", "django-allauth"), @r###"
|
||||
success: false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue