mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-02 04:48:18 +00:00
Reject match-runtime = true for dynamic packages (#15292)
## Summary If `match-runtime = true`, but we can't resolve a package's metadata statically, then we can't _know_ what the runtime version of the package will be -- because we can't resolve without building it. This PR makes that footgun clearer by raising an error. Closes https://github.com/astral-sh/uv/issues/15264.
This commit is contained in:
parent
7eb076aaef
commit
627c062cab
4 changed files with 60 additions and 6 deletions
|
|
@ -91,6 +91,10 @@ pub enum Error {
|
|||
NoSourceDistBuilds,
|
||||
#[error("Cyclic build dependency detected for `{0}`")]
|
||||
CyclicBuildDependency(PackageName),
|
||||
#[error(
|
||||
"Extra build requirement `{0}` was declared with `match-runtime = true`, but `{1}` does not declare static metadata, making runtime-matching impossible"
|
||||
)]
|
||||
UnmatchedRuntime(PackageName, PackageName),
|
||||
}
|
||||
|
||||
impl IsBuildBackendError for Error {
|
||||
|
|
@ -106,7 +110,8 @@ impl IsBuildBackendError for Error {
|
|||
| Self::Virtualenv(_)
|
||||
| Self::NoSourceDistBuild(_)
|
||||
| Self::NoSourceDistBuilds
|
||||
| Self::CyclicBuildDependency(_) => false,
|
||||
| Self::CyclicBuildDependency(_)
|
||||
| Self::UnmatchedRuntime(_, _) => false,
|
||||
Self::CommandFailed(_, _)
|
||||
| Self::BuildBackend(_)
|
||||
| Self::MissingHeader(_)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ use uv_configuration::Preview;
|
|||
use uv_configuration::{BuildKind, BuildOutput, SourceStrategy};
|
||||
use uv_distribution::BuildRequires;
|
||||
use uv_distribution_types::{
|
||||
ConfigSettings, ExtraBuildRequires, IndexLocations, Requirement, Resolution,
|
||||
ConfigSettings, ExtraBuildRequirement, ExtraBuildRequires, IndexLocations, Requirement,
|
||||
Resolution,
|
||||
};
|
||||
use uv_fs::LockedFile;
|
||||
use uv_fs::{PythonExt, Simplified};
|
||||
|
|
@ -326,13 +327,28 @@ impl SourceBuild {
|
|||
.or(fallback_package_version)
|
||||
.cloned();
|
||||
|
||||
let extra_build_dependencies: Vec<Requirement> = package_name
|
||||
let extra_build_dependencies = package_name
|
||||
.as_ref()
|
||||
.and_then(|name| extra_build_requires.get(name).cloned())
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(Requirement::from)
|
||||
.collect();
|
||||
.map(|requirement| {
|
||||
match requirement {
|
||||
ExtraBuildRequirement {
|
||||
requirement,
|
||||
match_runtime: true,
|
||||
} if requirement.source.is_empty() => {
|
||||
Err(Error::UnmatchedRuntime(
|
||||
requirement.name.clone(),
|
||||
// SAFETY: if `package_name` is `None`, the iterator is empty.
|
||||
package_name.clone().unwrap(),
|
||||
))
|
||||
}
|
||||
requirement => Ok(requirement),
|
||||
}
|
||||
})
|
||||
.map_ok(Requirement::from)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
// Create a virtual environment, or install into the shared environment if requested.
|
||||
let venv = if let Some(venv) = build_isolation.shared_environment(package_name.as_ref()) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue