Respect --no-sources for uv pip install workspace discovery (#11003)

This commit is contained in:
konsti 2025-01-28 00:10:27 +01:00 committed by GitHub
parent bbba2c7bce
commit c1a2ef12d2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 128 additions and 16 deletions

View file

@ -5,7 +5,7 @@ use uv_configuration::{LowerBound, SourceStrategy};
use uv_distribution_types::IndexLocations;
use uv_normalize::PackageName;
use uv_workspace::pyproject::ToolUvSources;
use uv_workspace::{DiscoveryOptions, ProjectWorkspace, Workspace};
use uv_workspace::{DiscoveryOptions, MemberDiscovery, ProjectWorkspace, Workspace};
use crate::metadata::{LoweredRequirement, MetadataError};
@ -39,10 +39,17 @@ impl BuildRequires {
sources: SourceStrategy,
lower_bound: LowerBound,
) -> Result<Self, MetadataError> {
let discovery = match sources {
SourceStrategy::Enabled => DiscoveryOptions::default(),
SourceStrategy::Disabled => DiscoveryOptions {
members: MemberDiscovery::None,
..Default::default()
},
};
// TODO(konsti): Cache workspace discovery.
let Some(project_workspace) =
ProjectWorkspace::from_maybe_project_root(install_path, &DiscoveryOptions::default())
.await?
ProjectWorkspace::from_maybe_project_root(install_path, &discovery).await?
else {
return Ok(Self::from_metadata23(metadata));
};

View file

@ -10,7 +10,7 @@ use uv_normalize::{ExtraName, GroupName, PackageName, DEV_DEPENDENCIES};
use uv_pep508::MarkerTree;
use uv_workspace::dependency_groups::FlatDependencyGroups;
use uv_workspace::pyproject::{Sources, ToolUvSources};
use uv_workspace::{DiscoveryOptions, ProjectWorkspace};
use uv_workspace::{DiscoveryOptions, MemberDiscovery, ProjectWorkspace};
use crate::metadata::{GitWorkspaceMember, LoweredRequirement, MetadataError};
use crate::Metadata;
@ -52,18 +52,17 @@ impl RequiresDist {
lower_bound: LowerBound,
) -> Result<Self, MetadataError> {
// TODO(konsti): Cache workspace discovery.
let discovery_options = if let Some(git_member) = &git_member {
DiscoveryOptions {
stop_discovery_at: Some(
git_member
.fetch_root
.parent()
.expect("git checkout has a parent"),
),
..Default::default()
}
} else {
DiscoveryOptions::default()
let discovery_options = DiscoveryOptions {
stop_discovery_at: git_member.map(|git_member| {
git_member
.fetch_root
.parent()
.expect("git checkout has a parent")
}),
members: match sources {
SourceStrategy::Enabled => MemberDiscovery::default(),
SourceStrategy::Disabled => MemberDiscovery::None,
},
};
let Some(project_workspace) =
ProjectWorkspace::from_maybe_project_root(install_path, &discovery_options).await?

View file

@ -8428,3 +8428,109 @@ fn direct_url_json_direct_url() -> Result<()> {
Ok(())
}
/// Regression test that we don't discover workspaces with `--no-sources`.
///
/// We have a workspace dependency shadowing a PyPI package and using this package's version to
/// check that by default we respect workspace package, but with `--no-sources`, we ignore them.
#[test]
fn no_sources_workspace_discovery() -> Result<()> {
let context = TestContext::new("3.12");
context.temp_dir.child("pyproject.toml").write_str(indoc! {
r#"
[project]
name = "foo"
version = "1.0.0"
dependencies = ["anyio"]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.uv.sources]
anyio = { workspace = true }
[tool.uv.workspace]
members = ["anyio"]
"#
})?;
context
.temp_dir
.child("src")
.child("foo")
.child("__init__.py")
.touch()?;
let anyio = context.temp_dir.child("anyio");
anyio.child("pyproject.toml").write_str(indoc! {
r#"
[project]
name = "anyio"
version = "2.0.0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
"#
})?;
anyio
.child("src")
.child("anyio")
.child("__init__.py")
.touch()?;
uv_snapshot!(context.filters(), context.pip_install()
.arg("."), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 2 packages in [TIME]
Prepared 2 packages in [TIME]
Installed 2 packages in [TIME]
+ anyio==2.0.0 (from file://[TEMP_DIR]/anyio)
+ foo==1.0.0 (from file://[TEMP_DIR]/)
"###
);
uv_snapshot!(context.filters(), context.pip_install()
.arg("--upgrade")
.arg("--no-sources")
.arg("."), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 4 packages in [TIME]
Prepared 3 packages in [TIME]
Uninstalled 1 package in [TIME]
Installed 3 packages in [TIME]
- anyio==2.0.0 (from file://[TEMP_DIR]/anyio)
+ anyio==4.3.0
+ idna==3.6
+ sniffio==1.3.1
"###
);
// Reverse direction: Check that we switch back to the workspace package with `--upgrade`.
uv_snapshot!(context.filters(), context.pip_install()
.arg("--upgrade")
.arg("."), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 2 packages in [TIME]
Prepared 1 package in [TIME]
Uninstalled 1 package in [TIME]
Installed 1 package in [TIME]
- anyio==4.3.0
+ anyio==2.0.0 (from file://[TEMP_DIR]/anyio)
"###
);
Ok(())
}