diff --git a/crates/uv-requirements/src/pyproject.rs b/crates/uv-requirements/src/pyproject.rs index 00527008e..0c32ed606 100644 --- a/crates/uv-requirements/src/pyproject.rs +++ b/crates/uv-requirements/src/pyproject.rs @@ -20,6 +20,7 @@ use thiserror::Error; use url::Url; use distribution_types::{ParsedUrlError, Requirement, RequirementSource, Requirements}; +use pep440_rs::VersionSpecifiers; use pep508_rs::{VerbatimUrl, VersionOrUrl}; use uv_configuration::PreviewMode; use uv_fs::Simplified; @@ -50,8 +51,6 @@ pub enum LoweringError { PathToUrl(PathBuf), #[error("Package is not included as workspace package in `tool.uv.workspace`")] UndeclaredWorkspacePackage, - #[error("Must specify a version constraint")] - UnconstrainedVersion, #[error("Can only specify one of rev, tag, or branch")] MoreThanOneGitRef, #[error("Unable to combine options in `tool.uv.sources`")] @@ -283,7 +282,6 @@ impl Pep621Metadata { let requirements = lower_requirements( &project.dependencies.unwrap_or_default(), &project.optional_dependencies.unwrap_or_default(), - &project.name, project_dir, &project_sources.unwrap_or_default(), workspace_sources, @@ -322,7 +320,6 @@ impl Pep621Metadata { pub(crate) fn lower_requirements( dependencies: &[String], optional_dependencies: &IndexMap>, - project_name: &PackageName, project_dir: &Path, project_sources: &HashMap, workspace_sources: &HashMap, @@ -336,7 +333,6 @@ pub(crate) fn lower_requirements( let name = requirement.name.clone(); lower_requirement( requirement, - project_name, project_dir, project_sources, workspace_sources, @@ -356,7 +352,6 @@ pub(crate) fn lower_requirements( let name = requirement.name.clone(); lower_requirement( requirement, - project_name, project_dir, project_sources, workspace_sources, @@ -378,7 +373,6 @@ pub(crate) fn lower_requirements( /// Combine `project.dependencies` or `project.optional-dependencies` with `tool.uv.sources`. pub(crate) fn lower_requirement( requirement: pep508_rs::Requirement, - project_name: &PackageName, project_dir: &Path, project_sources: &HashMap, workspace_sources: &HashMap, @@ -389,6 +383,7 @@ pub(crate) fn lower_requirement( .get(&requirement.name) .or(workspace_sources.get(&requirement.name)) .cloned(); + if !matches!( source, Some(Source::Workspace { @@ -403,12 +398,7 @@ pub(crate) fn lower_requirement( let Some(source) = source else { // Support recursive editable inclusions. - // TODO(konsti): This is a workspace feature. - return if requirement.version_or_url.is_none() && &requirement.name != project_name { - Err(LoweringError::UnconstrainedVersion) - } else { - Ok(Requirement::from_pep508(requirement)?) - }; + return Ok(Requirement::from_pep508(requirement)?); }; if preview.is_disabled() { @@ -488,7 +478,10 @@ pub(crate) fn lower_requirement( path_source(path, project_dir, editable)? } Source::Registry { index } => match requirement.version_or_url { - None => return Err(LoweringError::UnconstrainedVersion), + None => RequirementSource::Registry { + specifier: VersionSpecifiers::empty(), + index: Some(index), + }, Some(VersionOrUrl::VersionSpecifier(version)) => RequirementSource::Registry { specifier: version, index: Some(index), @@ -765,24 +758,6 @@ mod test { "###); } - #[test] - fn missing_constraint() { - let input = indoc! {r#" - [project] - name = "foo" - version = "0.0.0" - dependencies = [ - "tqdm", - ] - "#}; - - assert_snapshot!(format_err(input), @r###" - error: Failed to parse `pyproject.toml` - Caused by: Failed to parse entry for: `tqdm` - Caused by: Must specify a version constraint - "###); - } - #[test] fn invalid_syntax() { let input = indoc! {r#"