Track origin for setup.py files and friends (#3481)

## Summary

Ensures that we track the origins for requirements regardless of whether
they come from `pyproject.toml` or `setup.py` or `setup.cfg`.

Closes #3480.
This commit is contained in:
Charlie Marsh 2024-05-09 09:30:40 -04:00 committed by GitHub
parent 8b0fad3560
commit 3e4365301e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
40 changed files with 452 additions and 502 deletions

View file

@ -1,46 +1,38 @@
use std::collections::{BTreeMap, BTreeSet};
use std::path::PathBuf;
use url::Url;
use pep508_rs::VerbatimUrl;
use pep508_rs::{RequirementOrigin, VerbatimUrl};
use uv_fs::Simplified;
use uv_normalize::PackageName;
/// Source of a dependency, e.g., a `-r requirements.txt` file.
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum SourceAnnotation {
/// A `pyproject.toml` file.
PyProject {
path: PathBuf,
project_name: Option<String>,
},
/// A `-c constraints.txt` file.
Constraint(PathBuf),
Constraint(RequirementOrigin),
/// An `--override overrides.txt` file.
Override(PathBuf),
Override(RequirementOrigin),
/// A `-r requirements.txt` file.
Requirement(PathBuf),
Requirement(RequirementOrigin),
}
impl std::fmt::Display for SourceAnnotation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Requirement(path) => {
write!(f, "-r {}", path.user_display())
}
Self::Constraint(path) => {
write!(f, "-c {}", path.user_display())
}
Self::Override(path) => {
write!(f, "--override {}", path.user_display())
}
Self::PyProject { path, project_name } => {
if let Some(project_name) = project_name {
write!(f, "{} ({})", project_name, path.user_display())
} else {
write!(f, "{}", path.user_display())
Self::Requirement(origin) => match origin {
RequirementOrigin::File(path) => {
write!(f, "-r {}", path.user_display())
}
RequirementOrigin::Project(path, project_name) => {
write!(f, "{project_name} ({})", path.user_display())
}
},
Self::Constraint(origin) => {
write!(f, "-c {}", origin.path().user_display())
}
Self::Override(origin) => {
write!(f, "--override {}", origin.path().user_display())
}
}
}

View file

@ -5,7 +5,7 @@ use indexmap::IndexMap;
use url::Url;
use pep440_rs::VersionSpecifiers;
use pep508_rs::{MarkerEnvironment, MarkerTree, VerbatimUrl, VersionOrUrl};
use pep508_rs::{MarkerEnvironment, MarkerTree, RequirementOrigin, VerbatimUrl, VersionOrUrl};
use uv_git::GitReference;
use uv_normalize::{ExtraName, PackageName};
@ -28,7 +28,7 @@ pub struct Requirement {
pub extras: Vec<ExtraName>,
pub marker: Option<MarkerTree>,
pub source: RequirementSource,
pub path: Option<PathBuf>,
pub origin: Option<RequirementOrigin>,
}
impl Requirement {
@ -67,7 +67,7 @@ impl Requirement {
extras: requirement.extras,
marker: requirement.marker,
source,
path: requirement.source,
origin: requirement.origin,
})
}
}

View file

@ -139,7 +139,7 @@ impl From<&ResolvedDist> for Requirement {
extras: vec![],
marker: None,
source,
path: None,
origin: None,
}
}
}

View file

@ -14,8 +14,6 @@ pub struct UnresolvedRequirementSpecification {
pub requirement: UnresolvedRequirement,
/// Hashes of the downloadable packages.
pub hashes: Vec<String>,
/// Path of the source of the requirement
pub path: Option<String>,
}
/// A requirement read from a `requirements.txt` or `pyproject.toml` file.

View file

@ -26,7 +26,7 @@ use std::fmt::{Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
#[cfg(feature = "pyo3")]
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::path::Path;
use std::str::FromStr;
#[cfg(feature = "pyo3")]
@ -49,6 +49,7 @@ use pep440_rs::{Version, VersionSpecifier, VersionSpecifiers};
#[cfg(feature = "non-pep508-extensions")]
pub use unnamed::UnnamedRequirement;
// Parity with the crates.io version of pep508_rs
pub use origin::RequirementOrigin;
pub use uv_normalize::{ExtraName, InvalidNameError, PackageName};
pub use verbatim_url::{
expand_env_vars, split_scheme, strip_host, Scheme, VerbatimUrl, VerbatimUrlError,
@ -56,6 +57,7 @@ pub use verbatim_url::{
mod cursor;
mod marker;
mod origin;
#[cfg(feature = "non-pep508-extensions")]
mod unnamed;
mod verbatim_url;
@ -149,14 +151,14 @@ pub struct Requirement<T: Pep508Url = VerbatimUrl> {
/// Those are a nested and/or tree.
pub marker: Option<MarkerTree>,
/// The source file containing the requirement.
pub source: Option<PathBuf>,
pub origin: Option<RequirementOrigin>,
}
impl Requirement {
/// Set the source file containing the requirement.
#[must_use]
pub fn with_source(self, source: Option<PathBuf>) -> Self {
Self { source, ..self }
pub fn with_origin(self, origin: Option<RequirementOrigin>) -> Self {
Self { origin, ..self }
}
}
@ -492,7 +494,7 @@ impl<T: Pep508Url> Requirement<T> {
extras,
version_or_url,
marker,
source,
origin,
} = self;
Requirement {
name,
@ -505,7 +507,7 @@ impl<T: Pep508Url> Requirement<T> {
Some(VersionOrUrl::Url(url)) => Some(VersionOrUrl::Url(U::from(url))),
},
marker,
source,
origin,
}
}
}
@ -1029,7 +1031,7 @@ fn parse_pep508_requirement<T: Pep508Url>(
extras,
version_or_url: requirement_kind,
marker,
source: None,
origin: None,
})
}
@ -1171,7 +1173,7 @@ mod tests {
operator: MarkerOperator::LessThan,
r_value: MarkerValue::QuotedString("2.7".to_string()),
})),
source: None,
origin: None,
};
assert_eq!(requests, expected);
}
@ -1397,7 +1399,7 @@ mod tests {
extras: vec![],
marker: None,
version_or_url: Some(VersionOrUrl::Url(Url::parse(url).unwrap())),
source: None,
origin: None,
};
assert_eq!(pip_url, expected);
}

View file

@ -0,0 +1,22 @@
use std::path::{Path, PathBuf};
use uv_normalize::PackageName;
/// The origin of a dependency, e.g., a `-r requirements.txt` file.
#[derive(Hash, Debug, Clone, Eq, PartialEq, PartialOrd, Ord)]
pub enum RequirementOrigin {
/// The requirement was provided via a standalone file (e.g., a `requirements.txt` file).
File(PathBuf),
/// The requirement was provided via a local project (e.g., a `pyproject.toml` file).
Project(PathBuf, PackageName),
}
impl RequirementOrigin {
/// Returns the path of the requirement origin.
pub fn path(&self) -> &Path {
match self {
RequirementOrigin::File(path) => path.as_path(),
RequirementOrigin::Project(path, _) => path.as_path(),
}
}
}

View file

@ -1,5 +1,5 @@
use std::fmt::{Display, Formatter};
use std::path::{Path, PathBuf};
use std::path::Path;
use std::str::FromStr;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
@ -10,8 +10,8 @@ use uv_normalize::ExtraName;
use crate::marker::parse_markers_cursor;
use crate::{
expand_env_vars, parse_extras_cursor, split_extras, split_scheme, strip_host, Cursor,
MarkerEnvironment, MarkerTree, Pep508Error, Pep508ErrorSource, Scheme, VerbatimUrl,
VerbatimUrlError,
MarkerEnvironment, MarkerTree, Pep508Error, Pep508ErrorSource, RequirementOrigin, Scheme,
VerbatimUrl, VerbatimUrlError,
};
/// A PEP 508-like, direct URL dependency specifier without a package name.
@ -31,7 +31,7 @@ pub struct UnnamedRequirement {
/// Those are a nested and/or tree.
pub marker: Option<MarkerTree>,
/// The source file containing the requirement.
pub source: Option<PathBuf>,
pub origin: Option<RequirementOrigin>,
}
impl UnnamedRequirement {
@ -55,8 +55,8 @@ impl UnnamedRequirement {
/// Set the source file containing the requirement.
#[must_use]
pub fn with_source(self, source: Option<PathBuf>) -> Self {
Self { source, ..self }
pub fn with_origin(self, origin: Option<RequirementOrigin>) -> Self {
Self { origin, ..self }
}
}
@ -176,7 +176,7 @@ fn parse_unnamed_requirement(
url,
extras,
marker,
source: None,
origin: None,
})
}

View file

@ -48,8 +48,8 @@ use distribution_types::{
ParsedUrlError, Requirement, UnresolvedRequirement, UnresolvedRequirementSpecification,
};
use pep508_rs::{
expand_env_vars, split_scheme, strip_host, Extras, Pep508Error, Pep508ErrorSource, Scheme,
VerbatimUrl,
expand_env_vars, split_scheme, strip_host, Extras, Pep508Error, Pep508ErrorSource,
RequirementOrigin, Scheme, VerbatimUrl,
};
#[cfg(feature = "http")]
use uv_client::BaseClient;
@ -171,7 +171,7 @@ pub struct EditableRequirement {
/// The local path to the editable.
pub path: PathBuf,
/// The source file containing the requirement.
pub source: Option<PathBuf>,
pub origin: Option<RequirementOrigin>,
}
impl EditableRequirement {
@ -196,7 +196,7 @@ impl EditableRequirement {
/// We disallow URLs with schemes other than `file://` (e.g., `https://...`).
pub fn parse(
given: &str,
source: Option<&Path>,
origin: Option<&Path>,
working_dir: impl AsRef<Path>,
) -> Result<Self, RequirementsTxtParserError> {
// Identify the extras.
@ -275,7 +275,7 @@ impl EditableRequirement {
url,
extras,
path,
source: source.map(Path::to_path_buf),
origin: origin.map(Path::to_path_buf).map(RequirementOrigin::File),
})
}
@ -316,8 +316,6 @@ pub struct RequirementEntry {
pub requirement: RequirementsTxtRequirement,
/// Hashes of the downloadable packages.
pub hashes: Vec<String>,
/// Path of the original file (where existing)
pub path: Option<String>,
}
// We place the impl here instead of next to `UnresolvedRequirementSpecification` because
@ -337,7 +335,6 @@ impl TryFrom<RequirementEntry> for UnresolvedRequirementSpecification {
}
},
hashes: value.hashes,
path: value.path,
})
}
}
@ -711,7 +708,6 @@ fn parse_entry(
RequirementsTxtStatement::RequirementEntry(RequirementEntry {
requirement,
hashes,
path: requirements_txt.to_str().map(ToString::to_string),
})
} else if let Some(char) = s.peek() {
let (line, column) = calculate_row_column(content, s.cursor());
@ -829,7 +825,9 @@ fn parse_requirement_and_hashes(
}
let requirement = RequirementsTxtRequirement::parse(requirement, working_dir)
.map(|requirement| requirement.with_source(source.map(Path::to_path_buf)))
.map(|requirement| {
requirement.with_origin(source.map(Path::to_path_buf).map(RequirementOrigin::File))
})
.map_err(|err| match err {
RequirementsTxtRequirementError::ParsedUrl(err) => {
RequirementsTxtParserError::ParsedUrl {
@ -1815,15 +1813,14 @@ mod test {
extras: [],
version_or_url: None,
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/subdir/sibling.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/subdir/sibling.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/subdir/sibling.txt",
),
},
],
constraints: [],
@ -1880,15 +1877,14 @@ mod test {
extras: [],
version_or_url: None,
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/requirements.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/requirements.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/requirements.txt",
),
},
],
constraints: [],
@ -1968,8 +1964,10 @@ mod test {
},
extras: [],
path: "/foo/bar",
source: Some(
"<REQUIREMENTS_DIR>/grandchild.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/grandchild.txt",
),
),
},
],
@ -2077,15 +2075,14 @@ mod test {
extras: [],
version_or_url: None,
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/./sibling.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/./sibling.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/./sibling.txt",
),
},
RequirementEntry {
requirement: Named(
@ -2107,17 +2104,16 @@ mod test {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/requirements.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/requirements.txt",
),
),
},
),
hashes: [
"sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
],
path: Some(
"<REQUIREMENTS_DIR>/requirements.txt",
),
},
RequirementEntry {
requirement: Named(
@ -2139,17 +2135,16 @@ mod test {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/requirements.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/requirements.txt",
),
),
},
),
hashes: [
"sha256:fedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321",
],
path: Some(
"<REQUIREMENTS_DIR>/requirements.txt",
),
},
RequirementEntry {
requirement: Named(
@ -2171,15 +2166,14 @@ mod test {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/requirements.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/requirements.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/requirements.txt",
),
},
RequirementEntry {
requirement: Named(
@ -2201,15 +2195,14 @@ mod test {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/requirements.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/requirements.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/requirements.txt",
),
},
],
constraints: [],

View file

@ -1,9 +1,9 @@
use std::path::{Path, PathBuf};
use std::path::Path;
use thiserror::Error;
use distribution_types::ParsedUrlError;
use pep508_rs::{Pep508Error, Pep508ErrorSource, UnnamedRequirement};
use pep508_rs::{Pep508Error, Pep508ErrorSource, RequirementOrigin, UnnamedRequirement};
/// A requirement specifier in a `requirements.txt` file.
///
@ -21,10 +21,10 @@ pub enum RequirementsTxtRequirement {
impl RequirementsTxtRequirement {
/// Set the source file containing the requirement.
#[must_use]
pub fn with_source(self, path: Option<PathBuf>) -> Self {
pub fn with_origin(self, origin: Option<RequirementOrigin>) -> Self {
match self {
Self::Named(requirement) => Self::Named(requirement.with_source(path)),
Self::Unnamed(requirement) => Self::Unnamed(requirement.with_source(path)),
Self::Named(requirement) => Self::Named(requirement.with_origin(origin)),
Self::Unnamed(requirement) => Self::Unnamed(requirement.with_origin(origin)),
}
}
}

View file

@ -24,15 +24,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/basic.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/basic.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/basic.txt",
),
},
RequirementEntry {
requirement: Named(
@ -54,15 +53,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/basic.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/basic.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/basic.txt",
),
},
RequirementEntry {
requirement: Named(
@ -84,15 +82,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/basic.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/basic.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/basic.txt",
),
},
RequirementEntry {
requirement: Named(
@ -114,15 +111,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/basic.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/basic.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/basic.txt",
),
},
RequirementEntry {
requirement: Named(
@ -144,15 +140,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/basic.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/basic.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/basic.txt",
),
},
RequirementEntry {
requirement: Named(
@ -174,15 +169,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/basic.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/basic.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/basic.txt",
),
},
],
constraints: [],

View file

@ -24,15 +24,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/constraints-a.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/constraints-a.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/constraints-a.txt",
),
},
],
constraints: [
@ -54,8 +53,10 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/constraints-b.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/constraints-b.txt",
),
),
},
Requirement {
@ -76,8 +77,10 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/constraints-b.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/constraints-b.txt",
),
),
},
],

View file

@ -24,15 +24,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/constraints-b.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/constraints-b.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/constraints-b.txt",
),
},
RequirementEntry {
requirement: Named(
@ -54,15 +53,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/constraints-b.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/constraints-b.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/constraints-b.txt",
),
},
],
constraints: [],

View file

@ -13,15 +13,14 @@ RequirementsTxt {
extras: [],
version_or_url: None,
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/editable.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/editable.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/editable.txt",
),
},
RequirementEntry {
requirement: Named(
@ -59,15 +58,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/editable.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/editable.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/editable.txt",
),
},
],
constraints: [],

View file

@ -24,15 +24,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
},
RequirementEntry {
requirement: Named(
@ -54,15 +53,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
},
RequirementEntry {
requirement: Named(
@ -73,15 +71,14 @@ RequirementsTxt {
extras: [],
version_or_url: None,
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
},
RequirementEntry {
requirement: Named(
@ -111,15 +108,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
},
],
constraints: [],

View file

@ -13,15 +13,14 @@ RequirementsTxt {
extras: [],
version_or_url: None,
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/include-b.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/include-b.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/include-b.txt",
),
},
RequirementEntry {
requirement: Named(
@ -43,15 +42,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/include-a.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/include-a.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/include-a.txt",
),
},
],
constraints: [],

View file

@ -13,15 +13,14 @@ RequirementsTxt {
extras: [],
version_or_url: None,
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/include-b.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/include-b.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/include-b.txt",
),
},
],
constraints: [],

View file

@ -51,17 +51,16 @@ RequirementsTxt {
],
),
),
source: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
),
},
),
hashes: [
"sha256:2e1ccc9417d4da358b9de6f174e3ac094391ea1d4fbef2d667865d819dfd0afe",
],
path: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
},
RequirementEntry {
requirement: Named(
@ -110,17 +109,16 @@ RequirementsTxt {
],
),
),
source: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
),
},
),
hashes: [
"sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305",
],
path: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
},
RequirementEntry {
requirement: Named(
@ -180,17 +178,16 @@ RequirementsTxt {
],
),
),
source: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
),
},
),
hashes: [
"sha256:e4d039def5768a47e4afec8e89e83ec3ae5a26bf00ad851f914d1240b444d2b1",
],
path: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
},
RequirementEntry {
requirement: Named(
@ -239,8 +236,10 @@ RequirementsTxt {
],
),
),
source: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
),
},
),
@ -248,9 +247,6 @@ RequirementsTxt {
"sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5",
"sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a",
],
path: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
},
RequirementEntry {
requirement: Named(
@ -299,8 +295,10 @@ RequirementsTxt {
],
),
),
source: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
),
},
),
@ -310,9 +308,6 @@ RequirementsTxt {
"sha256:1a5c7d7d577e0eabfcf15eb87d1e19314c8c4f0e722a301f98e0e3a65e238b4e",
"sha256:1e5a38aa85bd660c53947bd28aeaafb6a97d70423606f1ccb044a03a1203fe4a",
],
path: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
},
],
constraints: [],

View file

@ -24,15 +24,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/small.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/small.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/small.txt",
),
},
RequirementEntry {
requirement: Named(
@ -54,15 +53,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/small.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/small.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/small.txt",
),
},
],
constraints: [],

View file

@ -13,15 +13,14 @@ RequirementsTxt {
extras: [],
version_or_url: None,
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/whitespace.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/whitespace.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/whitespace.txt",
),
},
RequirementEntry {
requirement: Named(
@ -59,15 +58,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/whitespace.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/whitespace.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/whitespace.txt",
),
},
],
constraints: [],

View file

@ -24,15 +24,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/basic.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/basic.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/basic.txt",
),
},
RequirementEntry {
requirement: Named(
@ -54,15 +53,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/basic.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/basic.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/basic.txt",
),
},
RequirementEntry {
requirement: Named(
@ -84,15 +82,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/basic.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/basic.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/basic.txt",
),
},
RequirementEntry {
requirement: Named(
@ -114,15 +111,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/basic.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/basic.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/basic.txt",
),
},
RequirementEntry {
requirement: Named(
@ -144,15 +140,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/basic.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/basic.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/basic.txt",
),
},
RequirementEntry {
requirement: Named(
@ -174,15 +169,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/basic.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/basic.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/basic.txt",
),
},
],
constraints: [],

View file

@ -24,15 +24,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/constraints-a.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/constraints-a.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/constraints-a.txt",
),
},
],
constraints: [
@ -54,8 +53,10 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/constraints-b.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/constraints-b.txt",
),
),
},
Requirement {
@ -76,8 +77,10 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/constraints-b.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/constraints-b.txt",
),
),
},
],

View file

@ -24,15 +24,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/constraints-b.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/constraints-b.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/constraints-b.txt",
),
},
RequirementEntry {
requirement: Named(
@ -54,15 +53,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/constraints-b.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/constraints-b.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/constraints-b.txt",
),
},
],
constraints: [],

View file

@ -24,15 +24,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
},
RequirementEntry {
requirement: Named(
@ -54,15 +53,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
},
RequirementEntry {
requirement: Named(
@ -73,15 +71,14 @@ RequirementsTxt {
extras: [],
version_or_url: None,
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
},
RequirementEntry {
requirement: Named(
@ -111,15 +108,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/for-poetry.txt",
),
},
],
constraints: [],

View file

@ -13,15 +13,14 @@ RequirementsTxt {
extras: [],
version_or_url: None,
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/include-b.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/include-b.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/include-b.txt",
),
},
RequirementEntry {
requirement: Named(
@ -43,15 +42,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/include-a.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/include-a.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/include-a.txt",
),
},
],
constraints: [],

View file

@ -13,15 +13,14 @@ RequirementsTxt {
extras: [],
version_or_url: None,
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/include-b.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/include-b.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/include-b.txt",
),
},
],
constraints: [],

View file

@ -51,17 +51,16 @@ RequirementsTxt {
],
),
),
source: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
),
},
),
hashes: [
"sha256:2e1ccc9417d4da358b9de6f174e3ac094391ea1d4fbef2d667865d819dfd0afe",
],
path: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
},
RequirementEntry {
requirement: Named(
@ -110,17 +109,16 @@ RequirementsTxt {
],
),
),
source: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
),
},
),
hashes: [
"sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305",
],
path: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
},
RequirementEntry {
requirement: Named(
@ -180,17 +178,16 @@ RequirementsTxt {
],
),
),
source: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
),
},
),
hashes: [
"sha256:e4d039def5768a47e4afec8e89e83ec3ae5a26bf00ad851f914d1240b444d2b1",
],
path: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
},
RequirementEntry {
requirement: Named(
@ -239,8 +236,10 @@ RequirementsTxt {
],
),
),
source: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
),
},
),
@ -248,9 +247,6 @@ RequirementsTxt {
"sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5",
"sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a",
],
path: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
},
RequirementEntry {
requirement: Named(
@ -299,8 +295,10 @@ RequirementsTxt {
],
),
),
source: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
),
},
),
@ -310,9 +308,6 @@ RequirementsTxt {
"sha256:1a5c7d7d577e0eabfcf15eb87d1e19314c8c4f0e722a301f98e0e3a65e238b4e",
"sha256:1e5a38aa85bd660c53947bd28aeaafb6a97d70423606f1ccb044a03a1203fe4a",
],
path: Some(
"<REQUIREMENTS_DIR>/poetry-with-hashes.txt",
),
},
],
constraints: [],

View file

@ -24,15 +24,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/small.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/small.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/small.txt",
),
},
RequirementEntry {
requirement: Named(
@ -54,15 +53,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/small.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/small.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/small.txt",
),
},
],
constraints: [],

View file

@ -25,15 +25,14 @@ RequirementsTxt {
},
extras: [],
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/bare-url.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/bare-url.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/bare-url.txt",
),
},
RequirementEntry {
requirement: Unnamed(
@ -60,15 +59,14 @@ RequirementsTxt {
),
],
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/bare-url.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/bare-url.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/bare-url.txt",
),
},
RequirementEntry {
requirement: Unnamed(
@ -91,15 +89,14 @@ RequirementsTxt {
},
extras: [],
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/bare-url.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/bare-url.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/bare-url.txt",
),
},
],
constraints: [],

View file

@ -13,15 +13,14 @@ RequirementsTxt {
extras: [],
version_or_url: None,
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/whitespace.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/whitespace.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/whitespace.txt",
),
},
RequirementEntry {
requirement: Named(
@ -59,15 +58,14 @@ RequirementsTxt {
),
),
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/whitespace.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/whitespace.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/whitespace.txt",
),
},
],
constraints: [],

View file

@ -25,15 +25,14 @@ RequirementsTxt {
},
extras: [],
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/bare-url.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/bare-url.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/bare-url.txt",
),
},
RequirementEntry {
requirement: Unnamed(
@ -60,15 +59,14 @@ RequirementsTxt {
),
],
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/bare-url.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/bare-url.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/bare-url.txt",
),
},
RequirementEntry {
requirement: Unnamed(
@ -91,15 +89,14 @@ RequirementsTxt {
},
extras: [],
marker: None,
source: Some(
"<REQUIREMENTS_DIR>/bare-url.txt",
origin: Some(
File(
"<REQUIREMENTS_DIR>/bare-url.txt",
),
),
},
),
hashes: [],
path: Some(
"<REQUIREMENTS_DIR>/bare-url.txt",
),
},
],
constraints: [],

View file

@ -132,7 +132,7 @@ pub(crate) async fn resolve_many(args: ResolveManyArgs) -> Result<()> {
extras: requirement.extras,
version_or_url: Some(equals_version),
marker: None,
source: requirement.source,
origin: requirement.origin,
}
} else {
requirement

View file

@ -342,7 +342,6 @@ impl<'a> SitePackages<'a> {
Requirement::from_pep508(dependency)?,
),
hashes: vec![],
path: None,
};
if seen.insert(dependency.clone()) {
stack.push(dependency);
@ -407,7 +406,6 @@ impl<'a> SitePackages<'a> {
Requirement::from_pep508(dependency)?,
),
hashes: vec![],
path: None,
};
if seen.insert(dependency.clone()) {
stack.push(dependency);

View file

@ -22,7 +22,7 @@ use url::Url;
use distribution_types::{ParsedUrlError, Requirement, RequirementSource, Requirements};
use pep440_rs::VersionSpecifiers;
use pep508_rs::{VerbatimUrl, VersionOrUrl};
use pep508_rs::{RequirementOrigin, VerbatimUrl, VersionOrUrl};
use uv_configuration::PreviewMode;
use uv_fs::Simplified;
use uv_git::GitReference;
@ -333,8 +333,9 @@ pub(crate) fn lower_requirements(
let dependencies = dependencies
.iter()
.map(|dependency| {
let requirement = pep508_rs::Requirement::from_str(dependency)?
.with_source(Some(pyproject_path.to_path_buf()));
let requirement = pep508_rs::Requirement::from_str(dependency)?.with_origin(Some(
RequirementOrigin::Project(pyproject_path.to_path_buf(), project_name.clone()),
));
let name = requirement.name.clone();
lower_requirement(
requirement,
@ -354,8 +355,12 @@ pub(crate) fn lower_requirements(
let dependencies: Vec<_> = dependencies
.iter()
.map(|dependency| {
let requirement = pep508_rs::Requirement::from_str(dependency)?
.with_source(Some(pyproject_path.to_path_buf()));
let requirement = pep508_rs::Requirement::from_str(dependency)?.with_origin(
Some(RequirementOrigin::Project(
pyproject_path.to_path_buf(),
project_name.clone(),
)),
);
let name = requirement.name.clone();
lower_requirement(
requirement,
@ -537,7 +542,7 @@ pub(crate) fn lower_requirement(
extras: requirement.extras,
marker: requirement.marker,
source,
path: Some(project_dir.join("pyproject.toml")),
origin: requirement.origin,
})
}

View file

@ -8,6 +8,7 @@ use url::Url;
use distribution_types::{
BuildableSource, HashPolicy, PathSourceUrl, Requirement, SourceUrl, VersionId,
};
use pep508_rs::RequirementOrigin;
use uv_client::RegistryClient;
use uv_distribution::{DistributionDatabase, Reporter};
@ -77,20 +78,27 @@ impl<'a, Context: BuildContext> SourceTreeResolver<'a, Context> {
}
/// Infer the package name for a given "unnamed" requirement.
async fn resolve_source_tree(&self, source_tree: &Path) -> Result<Vec<pep508_rs::Requirement>> {
async fn resolve_source_tree(&self, path: &Path) -> Result<Vec<pep508_rs::Requirement>> {
// Convert to a buildable source.
let path = fs_err::canonicalize(source_tree).with_context(|| {
let source_tree = fs_err::canonicalize(path).with_context(|| {
format!(
"Failed to canonicalize path to source tree: {}",
source_tree.user_display()
path.user_display()
)
})?;
let Ok(url) = Url::from_directory_path(&path) else {
let source_tree = source_tree.parent().ok_or_else(|| {
anyhow::anyhow!(
"The file `{}` appears to be a `setup.py` or `setup.cfg` file, which must be in a directory",
path.user_display()
)
})?;
let Ok(url) = Url::from_directory_path(source_tree) else {
return Err(anyhow::anyhow!("Failed to convert path to URL"));
};
let source = SourceUrl::Path(PathSourceUrl {
url: &url,
path: Cow::Owned(path),
path: Cow::Borrowed(source_tree),
});
// Determine the hash policy. Since we don't have a package name, we perform a
@ -101,7 +109,7 @@ impl<'a, Context: BuildContext> SourceTreeResolver<'a, Context> {
HashStrategy::Validate { .. } => {
return Err(anyhow::anyhow!(
"Hash-checking is not supported for local directories: {}",
source_tree.user_display()
path.user_display()
));
}
};
@ -136,15 +144,23 @@ impl<'a, Context: BuildContext> SourceTreeResolver<'a, Context> {
}
};
// Extract the origin.
let origin = RequirementOrigin::Project(path.to_path_buf(), metadata.name.clone());
// Determine the appropriate requirements to return based on the extras. This involves
// evaluating the `extras` expression in any markers, but preserving the remaining marker
// conditions.
match self.extras {
ExtrasSpecification::None => Ok(metadata.requires_dist),
ExtrasSpecification::None => Ok(metadata
.requires_dist
.into_iter()
.map(|requirement| requirement.with_origin(Some(origin.clone())))
.collect()),
ExtrasSpecification::All => Ok(metadata
.requires_dist
.into_iter()
.map(|requirement| pep508_rs::Requirement {
origin: Some(origin.clone()),
marker: requirement
.marker
.and_then(|marker| marker.simplify_extras(&metadata.provides_extras)),
@ -155,6 +171,7 @@ impl<'a, Context: BuildContext> SourceTreeResolver<'a, Context> {
.requires_dist
.into_iter()
.map(|requirement| pep508_rs::Requirement {
origin: Some(origin.clone()),
marker: requirement
.marker
.and_then(|marker| marker.simplify_extras(extras)),

View file

@ -71,7 +71,6 @@ impl RequirementsSpecification {
RequirementEntry {
requirement,
hashes: vec![],
path: None,
},
)?],
constraints: vec![],
@ -149,30 +148,21 @@ impl RequirementsSpecification {
Self::parse_direct_pyproject_toml(&contents, extras, path.as_ref(), preview)
.with_context(|| format!("Failed to parse `{}`", path.user_display()))?
}
RequirementsSource::SetupPy(path) | RequirementsSource::SetupCfg(path) => {
let path = fs_err::canonicalize(path)?;
let source_tree = path.parent().ok_or_else(|| {
anyhow::anyhow!(
"The file `{}` appears to be a `setup.py` or `setup.cfg` file, which must be in a directory",
path.user_display()
)
})?;
Self {
project: None,
requirements: vec![],
constraints: vec![],
overrides: vec![],
editables: vec![],
source_trees: vec![source_tree.to_path_buf()],
extras: FxHashSet::default(),
index_url: None,
extra_index_urls: vec![],
no_index: false,
find_links: vec![],
no_binary: NoBinary::default(),
no_build: NoBuild::default(),
}
}
RequirementsSource::SetupPy(path) | RequirementsSource::SetupCfg(path) => Self {
project: None,
requirements: vec![],
constraints: vec![],
overrides: vec![],
editables: vec![],
source_trees: vec![path.clone()],
extras: FxHashSet::default(),
index_url: None,
extra_index_urls: vec![],
no_index: false,
find_links: vec![],
no_binary: NoBinary::default(),
no_build: NoBuild::default(),
},
})
}
@ -224,13 +214,12 @@ impl RequirementsSpecification {
url,
path,
extras: requirement.extras,
source: Some(pyproject_path.to_path_buf()),
origin: requirement.origin,
})
} else {
Either::Right(UnresolvedRequirementSpecification {
requirement: UnresolvedRequirement::Named(requirement),
hashes: vec![],
path: Some(pyproject_path.to_string_lossy().to_string()),
})
}
});
@ -248,17 +237,10 @@ impl RequirementsSpecification {
"Dynamic pyproject.toml at: `{}`",
pyproject_path.user_display()
);
let path = fs_err::canonicalize(pyproject_path)?;
let source_tree = path.parent().ok_or_else(|| {
anyhow::anyhow!(
"The file `{}` appears to be a `pyproject.toml` file, which must be in a directory",
path.user_display()
)
})?;
Ok(Self {
project: None,
requirements: vec![],
source_trees: vec![source_tree.to_path_buf()],
source_trees: vec![pyproject_path.to_path_buf()],
..Self::default()
})
}

View file

@ -101,7 +101,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> {
extras: requirement.extras,
version_or_url: Some(VersionOrUrl::Url(requirement.url)),
marker: requirement.marker,
source: requirement.source,
origin: requirement.origin,
});
}
@ -120,7 +120,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> {
extras: requirement.extras,
version_or_url: Some(VersionOrUrl::Url(requirement.url)),
marker: requirement.marker,
source: requirement.source,
origin: requirement.origin,
});
}
@ -148,13 +148,13 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> {
extras: requirement.extras,
version_or_url: Some(VersionOrUrl::Url(requirement.url)),
marker: requirement.marker,
source: requirement.source,
origin: requirement.origin,
});
}
// Attempt to read a `pyproject.toml` file.
let project_path = path.join("pyproject.toml");
if let Some(pyproject) = fs_err::read_to_string(&project_path)
if let Some(pyproject) = fs_err::read_to_string(project_path)
.ok()
.and_then(|contents| toml::from_str::<PyProjectToml>(&contents).ok())
{
@ -170,7 +170,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> {
extras: requirement.extras,
version_or_url: Some(VersionOrUrl::Url(requirement.url)),
marker: requirement.marker,
source: Some(project_path.clone()),
origin: requirement.origin,
});
}
@ -188,7 +188,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> {
extras: requirement.extras,
version_or_url: Some(VersionOrUrl::Url(requirement.url)),
marker: requirement.marker,
source: Some(project_path.clone()),
origin: requirement.origin,
});
}
}
@ -217,7 +217,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> {
extras: requirement.extras,
version_or_url: Some(VersionOrUrl::Url(requirement.url)),
marker: requirement.marker,
source: requirement.source,
origin: requirement.origin,
});
}
}
@ -276,7 +276,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> {
extras: requirement.extras,
version_or_url: Some(VersionOrUrl::Url(requirement.url)),
marker: requirement.marker,
source: requirement.source,
origin: requirement.origin,
})
}
}

View file

@ -371,21 +371,11 @@ pub(crate) async fn pip_compile(
.iter()
.filter(|requirement| requirement.evaluate_markers(marker_filter, &[]))
{
if let Some(path) = &requirement.path {
if path.ends_with("pyproject.toml") {
sources.add(
&requirement.name,
SourceAnnotation::PyProject {
path: path.clone(),
project_name: project.as_ref().map(ToString::to_string),
},
);
} else {
sources.add(
&requirement.name,
SourceAnnotation::Requirement(path.clone()),
);
}
if let Some(origin) = &requirement.origin {
sources.add(
&requirement.name,
SourceAnnotation::Requirement(origin.clone()),
);
}
}
@ -393,10 +383,10 @@ pub(crate) async fn pip_compile(
.iter()
.filter(|requirement| requirement.evaluate_markers(marker_filter, &[]))
{
if let Some(path) = &requirement.path {
if let Some(origin) = &requirement.origin {
sources.add(
&requirement.name,
SourceAnnotation::Constraint(path.clone()),
SourceAnnotation::Constraint(origin.clone()),
);
}
}
@ -405,27 +395,20 @@ pub(crate) async fn pip_compile(
.iter()
.filter(|requirement| requirement.evaluate_markers(marker_filter, &[]))
{
if let Some(path) = &requirement.path {
sources.add(&requirement.name, SourceAnnotation::Override(path.clone()));
if let Some(origin) = &requirement.origin {
sources.add(
&requirement.name,
SourceAnnotation::Override(origin.clone()),
);
}
}
for editable in &editables {
if let Some(source) = &editable.source {
if source.ends_with("pyproject.toml") {
sources.add_editable(
editable.url(),
SourceAnnotation::PyProject {
path: source.clone(),
project_name: project.as_ref().map(ToString::to_string),
},
);
} else {
sources.add_editable(
editable.url(),
SourceAnnotation::Requirement(source.clone()),
);
}
if let Some(origin) = &editable.origin {
sources.add_editable(
editable.url(),
SourceAnnotation::Requirement(origin.clone()),
);
}
}
@ -444,7 +427,7 @@ pub(crate) async fn pip_compile(
url,
extras,
path,
source: _,
origin: _,
} = editable;
LocalEditable { url, path, extras }
}));

View file

@ -580,7 +580,7 @@ async fn build_editables(
url,
extras,
path,
source: _,
origin: _,
} = editable;
LocalEditable {
url: url.clone(),
@ -679,7 +679,7 @@ async fn resolve(
extras: vec![],
marker: None,
source,
path: None,
origin: None,
};
Ok(Preference::from_requirement(requirement))
})

View file

@ -691,7 +691,7 @@ async fn resolve_editables(
url,
path,
extras,
source: _,
origin: _,
} = editable;
LocalEditable {
url: url.clone(),

View file

@ -499,6 +499,7 @@ build-backend = "poetry.core.masonry.api"
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z pyproject.toml --extra test
anyio==3.7.1
# via poetry-editable (pyproject.toml)
idna==3.6
# via anyio
iniconfig==2.0.0
@ -508,6 +509,7 @@ build-backend = "poetry.core.masonry.api"
pluggy==1.4.0
# via pytest
pytest==8.1.1
# via poetry-editable (pyproject.toml)
sniffio==1.3.1
# via anyio
@ -568,9 +570,11 @@ setup(
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z pyproject.toml --extra dev
anyio==4.3.0
# via dummypkg (pyproject.toml)
idna==3.6
# via anyio
iniconfig==2.0.0
# via dummypkg (pyproject.toml)
sniffio==1.3.1
# via anyio
@ -624,9 +628,11 @@ setup(
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z setup.cfg --extra dev
anyio==4.3.0
# via dummypkg (setup.cfg)
idna==3.6
# via anyio
iniconfig==2.0.0
# via dummypkg (setup.cfg)
sniffio==1.3.1
# via anyio
@ -670,9 +676,11 @@ setup(
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z setup.py --extra dev
anyio==4.3.0
# via dummypkg (setup.py)
idna==3.6
# via anyio
iniconfig==2.0.0
# via dummypkg (setup.py)
sniffio==1.3.1
# via anyio
@ -3919,7 +3927,7 @@ fn generate_hashes_local_directory() -> Result<()> {
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
# via anyio
poetry-editable @ ../../scripts/packages/poetry_editable
# via [WORKSPACE]/scripts/packages/poetry_editable/pyproject.toml
# via -r [TEMP_DIR]/requirements.in
sniffio==1.3.1 \
--hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \
--hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc
@ -6755,10 +6763,10 @@ fn compile_root_uri_non_editable() -> Result<()> {
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z requirements.in
black @ ${BLACK_PATH}
# via
# [WORKSPACE]/scripts/packages/black_editable/pyproject.toml
# -r requirements.in
# root-editable
root-editable @ ${ROOT_PATH}
# via [WORKSPACE]/scripts/packages/root_editable/pyproject.toml
# via -r requirements.in
----- stderr -----
Resolved 2 packages in [TIME]
@ -7141,7 +7149,7 @@ fn unnamed_path_requirement() -> Result<()> {
# httpx
# poetry-editable
black @ ../../scripts/packages/black_editable
# via [WORKSPACE]/scripts/packages/black_editable/pyproject.toml
# via -r [TEMP_DIR]/requirements.in
certifi==2024.2.2
# via
# httpcore
@ -7161,7 +7169,7 @@ fn unnamed_path_requirement() -> Result<()> {
# httpx
# requests
poetry-editable @ ../../scripts/packages/poetry_editable
# via [WORKSPACE]/scripts/packages/poetry_editable/pyproject.toml
# via -r [TEMP_DIR]/requirements.in
requests==2.31.0
# via setup-cfg-editable
setup-cfg-editable @ ../../scripts/packages/setup_cfg_editable
@ -7653,7 +7661,7 @@ requires-python = ">3.8"
anyio @ file://[TEMP_DIR]/anyio/
# via lib
example @ ./app
# via app/pyproject.toml
# via -r requirements.in
idna==3.6
# via anyio
lib @ file://[TEMP_DIR]/lib/
@ -7741,7 +7749,7 @@ requires-python = ">3.8"
# --override overrides.txt
# lib
example @ ./app
# via app/pyproject.toml
# via -r requirements.in
idna==3.6
# via anyio
lib @ file://[TEMP_DIR]/lib/
@ -7856,7 +7864,7 @@ requires-python = ">3.8"
# --override overrides.txt
# lib
example @ ./app
# via app/pyproject.toml
# via -r requirements.in
idna==3.6
# via anyio
lib @ file://[TEMP_DIR]/lib
@ -7902,7 +7910,7 @@ requires-python = ">3.8"
click==8.1.7
# via flask
example @ .
# via pyproject.toml
# via -r requirements.in
flask==2.0.0rc1
# via example
itsdangerous==2.1.2