mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Merge 6d32ab671f
into e104eea34a
This commit is contained in:
commit
2ef76548b0
23 changed files with 538 additions and 216 deletions
|
@ -124,7 +124,10 @@ impl SourceUrl<'_> {
|
|||
pub fn is_editable(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
Self::Directory(DirectorySourceUrl { editable: true, .. })
|
||||
Self::Directory(DirectorySourceUrl {
|
||||
editable: Some(true),
|
||||
..
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -210,7 +213,7 @@ impl<'a> From<&'a PathSourceDist> for PathSourceUrl<'a> {
|
|||
pub struct DirectorySourceUrl<'a> {
|
||||
pub url: &'a DisplaySafeUrl,
|
||||
pub install_path: Cow<'a, Path>,
|
||||
pub editable: bool,
|
||||
pub editable: Option<bool>,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for DirectorySourceUrl<'_> {
|
||||
|
|
|
@ -343,9 +343,9 @@ pub struct DirectorySourceDist {
|
|||
/// The absolute path to the distribution which we use for installing.
|
||||
pub install_path: Box<Path>,
|
||||
/// Whether the package should be installed in editable mode.
|
||||
pub editable: bool,
|
||||
pub editable: Option<bool>,
|
||||
/// Whether the package should be built and installed.
|
||||
pub r#virtual: bool,
|
||||
pub r#virtual: Option<bool>,
|
||||
/// The URL as it was provided by the user.
|
||||
pub url: VerbatimUrl,
|
||||
}
|
||||
|
@ -452,8 +452,8 @@ impl Dist {
|
|||
name: PackageName,
|
||||
url: VerbatimUrl,
|
||||
install_path: &Path,
|
||||
editable: bool,
|
||||
r#virtual: bool,
|
||||
editable: Option<bool>,
|
||||
r#virtual: Option<bool>,
|
||||
) -> Result<Dist, Error> {
|
||||
// Convert to an absolute path.
|
||||
let install_path = path::absolute(install_path)?;
|
||||
|
@ -655,7 +655,7 @@ impl SourceDist {
|
|||
/// Returns `true` if the distribution is editable.
|
||||
pub fn is_editable(&self) -> bool {
|
||||
match self {
|
||||
Self::Directory(DirectorySourceDist { editable, .. }) => *editable,
|
||||
Self::Directory(DirectorySourceDist { editable, .. }) => editable.unwrap_or(false),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -663,7 +663,7 @@ impl SourceDist {
|
|||
/// Returns `true` if the distribution is virtual.
|
||||
pub fn is_virtual(&self) -> bool {
|
||||
match self {
|
||||
Self::Directory(DirectorySourceDist { r#virtual, .. }) => *r#virtual,
|
||||
Self::Directory(DirectorySourceDist { r#virtual, .. }) => r#virtual.unwrap_or(false),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -429,9 +429,9 @@ pub enum RequirementSource {
|
|||
/// The absolute path to the distribution which we use for installing.
|
||||
install_path: Box<Path>,
|
||||
/// For a source tree (a directory), whether to install as an editable.
|
||||
editable: bool,
|
||||
editable: Option<bool>,
|
||||
/// For a source tree (a directory), whether the project should be built and installed.
|
||||
r#virtual: bool,
|
||||
r#virtual: Option<bool>,
|
||||
/// The PEP 508 style URL in the format
|
||||
/// `file:///<path>#subdirectory=<subdirectory>`.
|
||||
url: VerbatimUrl,
|
||||
|
@ -545,7 +545,13 @@ impl RequirementSource {
|
|||
|
||||
/// Returns `true` if the source is editable.
|
||||
pub fn is_editable(&self) -> bool {
|
||||
matches!(self, Self::Directory { editable: true, .. })
|
||||
matches!(
|
||||
self,
|
||||
Self::Directory {
|
||||
editable: Some(true),
|
||||
..
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns `true` if the source is empty.
|
||||
|
@ -792,11 +798,11 @@ impl From<RequirementSource> for RequirementSourceWire {
|
|||
r#virtual,
|
||||
url: _,
|
||||
} => {
|
||||
if editable {
|
||||
if editable.unwrap_or(false) {
|
||||
Self::Editable {
|
||||
editable: PortablePathBuf::from(install_path),
|
||||
}
|
||||
} else if r#virtual {
|
||||
} else if r#virtual.unwrap_or(false) {
|
||||
Self::Virtual {
|
||||
r#virtual: PortablePathBuf::from(install_path),
|
||||
}
|
||||
|
@ -908,8 +914,8 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
|
|||
))?;
|
||||
Ok(Self::Directory {
|
||||
install_path: directory,
|
||||
editable: false,
|
||||
r#virtual: false,
|
||||
editable: Some(false),
|
||||
r#virtual: Some(false),
|
||||
url,
|
||||
})
|
||||
}
|
||||
|
@ -920,8 +926,8 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
|
|||
))?;
|
||||
Ok(Self::Directory {
|
||||
install_path: editable,
|
||||
editable: true,
|
||||
r#virtual: false,
|
||||
editable: Some(true),
|
||||
r#virtual: Some(false),
|
||||
url,
|
||||
})
|
||||
}
|
||||
|
@ -932,8 +938,8 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
|
|||
))?;
|
||||
Ok(Self::Directory {
|
||||
install_path: r#virtual,
|
||||
editable: false,
|
||||
r#virtual: true,
|
||||
editable: Some(false),
|
||||
r#virtual: Some(true),
|
||||
url,
|
||||
})
|
||||
}
|
||||
|
@ -980,8 +986,8 @@ mod tests {
|
|||
marker: MarkerTree::TRUE,
|
||||
source: RequirementSource::Directory {
|
||||
install_path: PathBuf::from(path).into_boxed_path(),
|
||||
editable: false,
|
||||
r#virtual: false,
|
||||
editable: Some(false),
|
||||
r#virtual: Some(false),
|
||||
url: VerbatimUrl::from_absolute_path(path).unwrap(),
|
||||
},
|
||||
origin: None,
|
||||
|
|
|
@ -119,7 +119,7 @@ impl<'a> BuiltWheelIndex<'a> {
|
|||
) -> Result<Option<CachedWheel>, Error> {
|
||||
let cache_shard = self.cache.shard(
|
||||
CacheBucket::SourceDistributions,
|
||||
if source_dist.editable {
|
||||
if source_dist.editable.unwrap_or(false) {
|
||||
WheelCache::Editable(&source_dist.url).root()
|
||||
} else {
|
||||
WheelCache::Path(&source_dist.url).root()
|
||||
|
|
|
@ -310,15 +310,15 @@ impl LoweredRequirement {
|
|||
RequirementSource::Directory {
|
||||
install_path: install_path.into_boxed_path(),
|
||||
url,
|
||||
editable: true,
|
||||
r#virtual: false,
|
||||
editable: Some(true),
|
||||
r#virtual: Some(false),
|
||||
}
|
||||
} else {
|
||||
RequirementSource::Directory {
|
||||
install_path: install_path.into_boxed_path(),
|
||||
url,
|
||||
editable: false,
|
||||
r#virtual: true,
|
||||
editable: Some(false),
|
||||
r#virtual: Some(true),
|
||||
}
|
||||
};
|
||||
(source, marker)
|
||||
|
@ -724,8 +724,8 @@ fn path_source(
|
|||
Ok(RequirementSource::Directory {
|
||||
install_path: install_path.into_boxed_path(),
|
||||
url,
|
||||
editable: true,
|
||||
r#virtual: false,
|
||||
editable,
|
||||
r#virtual: Some(false),
|
||||
})
|
||||
} else {
|
||||
// Determine whether the project is a package or virtual.
|
||||
|
@ -738,12 +738,14 @@ fn path_source(
|
|||
.unwrap_or(true)
|
||||
});
|
||||
|
||||
// If the project is not a package, treat it as a virtual dependency.
|
||||
let r#virtual = !is_package;
|
||||
|
||||
Ok(RequirementSource::Directory {
|
||||
install_path: install_path.into_boxed_path(),
|
||||
url,
|
||||
editable: false,
|
||||
// If a project is not a package, treat it as a virtual dependency.
|
||||
r#virtual: !is_package,
|
||||
editable: Some(false),
|
||||
r#virtual: Some(r#virtual),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1070,7 +1070,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
|
|||
|
||||
let cache_shard = self.build_context.cache().shard(
|
||||
CacheBucket::SourceDistributions,
|
||||
if resource.editable {
|
||||
if resource.editable.unwrap_or(false) {
|
||||
WheelCache::Editable(resource.url).root()
|
||||
} else {
|
||||
WheelCache::Path(resource.url).root()
|
||||
|
@ -1183,7 +1183,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
|
|||
|
||||
let cache_shard = self.build_context.cache().shard(
|
||||
CacheBucket::SourceDistributions,
|
||||
if resource.editable {
|
||||
if resource.editable.unwrap_or(false) {
|
||||
WheelCache::Editable(resource.url).root()
|
||||
} else {
|
||||
WheelCache::Path(resource.url).root()
|
||||
|
|
|
@ -241,7 +241,7 @@ impl RequirementSatisfaction {
|
|||
return Self::Mismatch;
|
||||
};
|
||||
|
||||
if *requested_editable != installed_editable.unwrap_or_default() {
|
||||
if requested_editable != installed_editable {
|
||||
trace!(
|
||||
"Editable mismatch: {:?} vs. {:?}",
|
||||
*requested_editable,
|
||||
|
|
|
@ -86,8 +86,8 @@ impl UnnamedRequirementUrl for VerbatimParsedUrl {
|
|||
ParsedUrl::Directory(ParsedDirectoryUrl {
|
||||
url,
|
||||
install_path,
|
||||
editable: false,
|
||||
r#virtual: false,
|
||||
editable: None,
|
||||
r#virtual: None,
|
||||
})
|
||||
} else {
|
||||
ParsedUrl::Path(ParsedPathUrl {
|
||||
|
@ -118,8 +118,8 @@ impl UnnamedRequirementUrl for VerbatimParsedUrl {
|
|||
ParsedUrl::Directory(ParsedDirectoryUrl {
|
||||
url,
|
||||
install_path,
|
||||
editable: false,
|
||||
r#virtual: false,
|
||||
editable: None,
|
||||
r#virtual: None,
|
||||
})
|
||||
} else {
|
||||
ParsedUrl::Path(ParsedPathUrl {
|
||||
|
@ -187,7 +187,10 @@ impl ParsedUrl {
|
|||
pub fn is_editable(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
Self::Directory(ParsedDirectoryUrl { editable: true, .. })
|
||||
Self::Directory(ParsedDirectoryUrl {
|
||||
editable: Some(true),
|
||||
..
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -226,16 +229,18 @@ pub struct ParsedDirectoryUrl {
|
|||
pub url: DisplaySafeUrl,
|
||||
/// The absolute path to the distribution which we use for installing.
|
||||
pub install_path: Box<Path>,
|
||||
pub editable: bool,
|
||||
pub r#virtual: bool,
|
||||
/// Whether the project at the given URL should be installed in editable mode.
|
||||
pub editable: Option<bool>,
|
||||
/// Whether the project at the given URL should be treated as a virtual package.
|
||||
pub r#virtual: Option<bool>,
|
||||
}
|
||||
|
||||
impl ParsedDirectoryUrl {
|
||||
/// Construct a [`ParsedDirectoryUrl`] from a path requirement source.
|
||||
pub fn from_source(
|
||||
install_path: Box<Path>,
|
||||
editable: bool,
|
||||
r#virtual: bool,
|
||||
editable: Option<bool>,
|
||||
r#virtual: Option<bool>,
|
||||
url: DisplaySafeUrl,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
@ -399,8 +404,8 @@ impl TryFrom<DisplaySafeUrl> for ParsedUrl {
|
|||
Ok(Self::Directory(ParsedDirectoryUrl {
|
||||
url,
|
||||
install_path: path.into_boxed_path(),
|
||||
editable: false,
|
||||
r#virtual: false,
|
||||
editable: None,
|
||||
r#virtual: None,
|
||||
}))
|
||||
} else {
|
||||
Ok(Self::Path(ParsedPathUrl {
|
||||
|
@ -445,7 +450,7 @@ impl From<&ParsedDirectoryUrl> for DirectUrl {
|
|||
Self::LocalDirectory {
|
||||
url: value.url.to_string(),
|
||||
dir_info: DirInfo {
|
||||
editable: value.editable.then_some(true),
|
||||
editable: value.editable,
|
||||
},
|
||||
subdirectory: None,
|
||||
}
|
||||
|
|
|
@ -2064,8 +2064,10 @@ mod test {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "/foo/bar",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
|
|
@ -90,7 +90,7 @@ impl RequirementsTxtRequirement {
|
|||
version_or_url: Some(uv_pep508::VersionOrUrl::Url(VerbatimParsedUrl {
|
||||
verbatim: url.verbatim,
|
||||
parsed_url: ParsedUrl::Directory(ParsedDirectoryUrl {
|
||||
editable: true,
|
||||
editable: Some(true),
|
||||
..parsed_url
|
||||
}),
|
||||
})),
|
||||
|
@ -115,7 +115,7 @@ impl RequirementsTxtRequirement {
|
|||
url: VerbatimParsedUrl {
|
||||
verbatim: requirement.url.verbatim,
|
||||
parsed_url: ParsedUrl::Directory(ParsedDirectoryUrl {
|
||||
editable: true,
|
||||
editable: Some(true),
|
||||
..parsed_url
|
||||
}),
|
||||
},
|
||||
|
|
|
@ -22,8 +22,8 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/scripts/packages/black_editable",
|
||||
editable: false,
|
||||
virtual: false,
|
||||
editable: None,
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -72,8 +72,8 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/scripts/packages/black_editable",
|
||||
editable: false,
|
||||
virtual: false,
|
||||
editable: None,
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -126,8 +126,8 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "/scripts/packages/black_editable",
|
||||
editable: false,
|
||||
virtual: false,
|
||||
editable: None,
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -176,8 +176,8 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/scripts/packages/black editable",
|
||||
editable: false,
|
||||
virtual: false,
|
||||
editable: None,
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -226,8 +226,8 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/scripts/packages/black editable",
|
||||
editable: false,
|
||||
virtual: false,
|
||||
editable: None,
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -276,8 +276,8 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/scripts/packages/black editable",
|
||||
editable: false,
|
||||
virtual: false,
|
||||
editable: None,
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
|
|
@ -24,8 +24,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -81,8 +83,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -138,8 +142,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -195,8 +201,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -252,8 +260,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -302,8 +312,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable[d",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -352,8 +364,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -402,8 +416,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
|
|
@ -22,8 +22,8 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/scripts/packages/black_editable",
|
||||
editable: false,
|
||||
virtual: false,
|
||||
editable: None,
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -72,8 +72,8 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/scripts/packages/black_editable",
|
||||
editable: false,
|
||||
virtual: false,
|
||||
editable: None,
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -126,8 +126,8 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/scripts/packages/black_editable",
|
||||
editable: false,
|
||||
virtual: false,
|
||||
editable: None,
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -176,8 +176,8 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/scripts/packages/black editable",
|
||||
editable: false,
|
||||
virtual: false,
|
||||
editable: None,
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -226,8 +226,8 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/scripts/packages/black editable",
|
||||
editable: false,
|
||||
virtual: false,
|
||||
editable: None,
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -276,8 +276,8 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/scripts/packages/black editable",
|
||||
editable: false,
|
||||
virtual: false,
|
||||
editable: None,
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
|
|
@ -24,8 +24,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -81,8 +83,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -138,8 +142,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -195,8 +201,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -252,8 +260,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -302,8 +312,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable[d",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -352,8 +364,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
@ -402,8 +416,10 @@ RequirementsTxt {
|
|||
fragment: None,
|
||||
},
|
||||
install_path: "<REQUIREMENTS_DIR>/editable",
|
||||
editable: true,
|
||||
virtual: false,
|
||||
editable: Some(
|
||||
true,
|
||||
),
|
||||
virtual: None,
|
||||
},
|
||||
),
|
||||
verbatim: VerbatimUrl {
|
||||
|
|
|
@ -154,7 +154,7 @@ impl<'a, Context: BuildContext> SourceTreeResolver<'a, Context> {
|
|||
let source = SourceUrl::Directory(DirectorySourceUrl {
|
||||
url: &url,
|
||||
install_path: Cow::Borrowed(source_tree),
|
||||
editable: false,
|
||||
editable: None,
|
||||
});
|
||||
|
||||
// Determine the hash policy. Since we don't have a package name, we perform a
|
||||
|
|
|
@ -500,7 +500,7 @@ impl<'lock> PylockToml {
|
|||
.unwrap_or_else(|_| dist.install_path.clone());
|
||||
package.directory = Some(PylockTomlDirectory {
|
||||
path: PortablePathBuf::from(path),
|
||||
editable: if dist.editable { Some(true) } else { None },
|
||||
editable: dist.editable,
|
||||
subdirectory: None,
|
||||
});
|
||||
}
|
||||
|
@ -737,7 +737,7 @@ impl<'lock> PylockToml {
|
|||
),
|
||||
editable: match editable {
|
||||
EditableMode::NonEditable => None,
|
||||
EditableMode::Editable => Some(sdist.editable),
|
||||
EditableMode::Editable => sdist.editable,
|
||||
},
|
||||
subdirectory: None,
|
||||
}),
|
||||
|
@ -1394,8 +1394,8 @@ impl PylockTomlDirectory {
|
|||
Ok(DirectorySourceDist {
|
||||
name: name.clone(),
|
||||
install_path: path.into_boxed_path(),
|
||||
editable: self.editable.unwrap_or(false),
|
||||
r#virtual: false,
|
||||
editable: self.editable,
|
||||
r#virtual: Some(false),
|
||||
url,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2402,8 +2402,8 @@ impl Package {
|
|||
name: self.id.name.clone(),
|
||||
url: verbatim_url(&install_path, &self.id)?,
|
||||
install_path: install_path.into_boxed_path(),
|
||||
editable: false,
|
||||
r#virtual: false,
|
||||
editable: Some(false),
|
||||
r#virtual: Some(false),
|
||||
};
|
||||
uv_distribution_types::SourceDist::Directory(dir_dist)
|
||||
}
|
||||
|
@ -2413,8 +2413,8 @@ impl Package {
|
|||
name: self.id.name.clone(),
|
||||
url: verbatim_url(&install_path, &self.id)?,
|
||||
install_path: install_path.into_boxed_path(),
|
||||
editable: true,
|
||||
r#virtual: false,
|
||||
editable: Some(true),
|
||||
r#virtual: Some(false),
|
||||
};
|
||||
uv_distribution_types::SourceDist::Directory(dir_dist)
|
||||
}
|
||||
|
@ -2424,8 +2424,8 @@ impl Package {
|
|||
name: self.id.name.clone(),
|
||||
url: verbatim_url(&install_path, &self.id)?,
|
||||
install_path: install_path.into_boxed_path(),
|
||||
editable: false,
|
||||
r#virtual: true,
|
||||
editable: Some(false),
|
||||
r#virtual: Some(true),
|
||||
};
|
||||
uv_distribution_types::SourceDist::Directory(dir_dist)
|
||||
}
|
||||
|
@ -3256,9 +3256,9 @@ impl Source {
|
|||
let path = relative_to(&directory_dist.install_path, root)
|
||||
.or_else(|_| std::path::absolute(&directory_dist.install_path))
|
||||
.map_err(LockErrorKind::DistributionRelativePath)?;
|
||||
if directory_dist.editable {
|
||||
if directory_dist.editable.unwrap_or(false) {
|
||||
Ok(Source::Editable(path.into_boxed_path()))
|
||||
} else if directory_dist.r#virtual {
|
||||
} else if directory_dist.r#virtual.unwrap_or(false) {
|
||||
Ok(Source::Virtual(path.into_boxed_path()))
|
||||
} else {
|
||||
Ok(Source::Directory(path.into_boxed_path()))
|
||||
|
@ -4806,8 +4806,8 @@ fn normalize_requirement(
|
|||
marker: requires_python.simplify_markers(requirement.marker),
|
||||
source: RequirementSource::Directory {
|
||||
install_path,
|
||||
editable,
|
||||
r#virtual,
|
||||
editable: Some(editable.unwrap_or(false)),
|
||||
r#virtual: Some(r#virtual.unwrap_or(false)),
|
||||
url,
|
||||
},
|
||||
origin: None,
|
||||
|
|
|
@ -619,6 +619,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
|||
&state.python_requirement,
|
||||
&state.pubgrub,
|
||||
)?;
|
||||
|
||||
match forked_deps {
|
||||
ForkedDependencies::Unavailable(reason) => {
|
||||
// Then here, if we get a reason that we consider unrecoverable, we should
|
||||
|
|
|
@ -63,9 +63,9 @@ impl Urls {
|
|||
verbatim: _,
|
||||
} = package_url
|
||||
{
|
||||
if !*editable {
|
||||
if editable.is_none() {
|
||||
debug!("Allowing an editable variant of {}", &package_url.verbatim);
|
||||
*editable = true;
|
||||
*editable = Some(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,8 +201,9 @@ fn same_resource(a: &ParsedUrl, b: &ParsedUrl, git: &GitResolver) -> bool {
|
|||
|| is_same_file(&a.install_path, &b.install_path).unwrap_or(false)
|
||||
}
|
||||
(ParsedUrl::Directory(a), ParsedUrl::Directory(b)) => {
|
||||
a.install_path == b.install_path
|
||||
|| is_same_file(&a.install_path, &b.install_path).unwrap_or(false)
|
||||
(a.install_path == b.install_path
|
||||
|| is_same_file(&a.install_path, &b.install_path).unwrap_or(false))
|
||||
&& a.editable.is_none_or(|a| b.editable.is_none_or(|b| a == b))
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
|
|
|
@ -315,15 +315,15 @@ impl Workspace {
|
|||
source: if member.pyproject_toml.is_package() {
|
||||
RequirementSource::Directory {
|
||||
install_path: member.root.clone().into_boxed_path(),
|
||||
editable: true,
|
||||
r#virtual: false,
|
||||
editable: Some(true),
|
||||
r#virtual: Some(false),
|
||||
url,
|
||||
}
|
||||
} else {
|
||||
RequirementSource::Directory {
|
||||
install_path: member.root.clone().into_boxed_path(),
|
||||
editable: false,
|
||||
r#virtual: true,
|
||||
editable: Some(false),
|
||||
r#virtual: Some(true),
|
||||
url,
|
||||
}
|
||||
},
|
||||
|
@ -371,15 +371,15 @@ impl Workspace {
|
|||
source: if member.pyproject_toml.is_package() {
|
||||
RequirementSource::Directory {
|
||||
install_path: member.root.clone().into_boxed_path(),
|
||||
editable: true,
|
||||
r#virtual: false,
|
||||
editable: Some(true),
|
||||
r#virtual: Some(false),
|
||||
url,
|
||||
}
|
||||
} else {
|
||||
RequirementSource::Directory {
|
||||
install_path: member.root.clone().into_boxed_path(),
|
||||
editable: false,
|
||||
r#virtual: true,
|
||||
editable: Some(false),
|
||||
r#virtual: Some(true),
|
||||
url,
|
||||
}
|
||||
},
|
||||
|
|
|
@ -802,7 +802,7 @@ fn apply_no_virtual_project(resolution: Resolution) -> Resolution {
|
|||
return true;
|
||||
};
|
||||
|
||||
!dist.r#virtual
|
||||
!dist.r#virtual.unwrap_or(false)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -820,8 +820,8 @@ fn apply_editable_mode(resolution: Resolution, editable: EditableMode) -> Resolu
|
|||
let Dist::Source(SourceDist::Directory(DirectorySourceDist {
|
||||
name,
|
||||
install_path,
|
||||
editable: true,
|
||||
r#virtual: false,
|
||||
editable: Some(true),
|
||||
r#virtual,
|
||||
url,
|
||||
})) = dist.as_ref()
|
||||
else {
|
||||
|
@ -832,8 +832,8 @@ fn apply_editable_mode(resolution: Resolution, editable: EditableMode) -> Resolu
|
|||
dist: Arc::new(Dist::Source(SourceDist::Directory(DirectorySourceDist {
|
||||
name: name.clone(),
|
||||
install_path: install_path.clone(),
|
||||
editable: false,
|
||||
r#virtual: false,
|
||||
editable: Some(false),
|
||||
r#virtual: *r#virtual,
|
||||
url: url.clone(),
|
||||
}))),
|
||||
version: version.clone(),
|
||||
|
|
|
@ -10944,7 +10944,7 @@ fn lock_sources_source_tree() -> Result<()> {
|
|||
}
|
||||
|
||||
/// Lock a project in which a given dependency is requested from two different members, once as
|
||||
/// editable, and once as non-editable.
|
||||
/// editable, and once as non-editable. This should trigger a conflicting URL error.
|
||||
#[test]
|
||||
fn lock_editable() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
@ -11084,86 +11084,16 @@ fn lock_editable() -> Result<()> {
|
|||
library = { path = "../../library", editable = true }
|
||||
"#})?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.lock(), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
uv_snapshot!(context.filters(), context.lock(), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
"###);
|
||||
|
||||
let lock = context.read("uv.lock");
|
||||
|
||||
insta::with_settings!({
|
||||
filters => context.filters(),
|
||||
}, {
|
||||
assert_snapshot!(
|
||||
lock, @r#"
|
||||
version = 1
|
||||
revision = 2
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[options]
|
||||
exclude-newer = "2024-03-25T00:00:00Z"
|
||||
|
||||
[manifest]
|
||||
members = [
|
||||
"leaf",
|
||||
"workspace",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leaf"
|
||||
version = "0.1.0"
|
||||
source = { editable = "packages/leaf" }
|
||||
dependencies = [
|
||||
{ name = "library" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "library", editable = "library" }]
|
||||
|
||||
[[package]]
|
||||
name = "library"
|
||||
version = "0.1.0"
|
||||
source = { editable = "library" }
|
||||
|
||||
[[package]]
|
||||
name = "workspace"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "library" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "library", directory = "library" }]
|
||||
"#
|
||||
);
|
||||
});
|
||||
|
||||
// Re-run with `--locked`.
|
||||
uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
"###);
|
||||
|
||||
// Install from the lockfile.
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--frozen"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Prepared 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ library==0.1.0 (from file://[TEMP_DIR]/library)
|
||||
"###);
|
||||
error: Requirements contain conflicting URLs for package `library` in all marker environments:
|
||||
- file://[TEMP_DIR]/library
|
||||
- file://[TEMP_DIR]/library (editable)
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -9989,3 +9989,343 @@ fn sync_url_with_query_parameters() -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// See: <https://github.com/astral-sh/uv/issues/11648>
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn conflicting_editable() -> 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 = []
|
||||
|
||||
[dependency-groups]
|
||||
foo = [
|
||||
"child",
|
||||
]
|
||||
bar = [
|
||||
"child",
|
||||
]
|
||||
|
||||
[tool.uv]
|
||||
conflicts = [
|
||||
[
|
||||
{ group = "foo" },
|
||||
{ group = "bar" },
|
||||
],
|
||||
]
|
||||
|
||||
[tool.uv.sources]
|
||||
child = [
|
||||
{ path = "./child", editable = true, group = "foo" },
|
||||
{ path = "./child", editable = false, group = "bar" },
|
||||
]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
context
|
||||
.temp_dir
|
||||
.child("child")
|
||||
.child("pyproject.toml")
|
||||
.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "child"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = []
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
"#,
|
||||
)?;
|
||||
context
|
||||
.temp_dir
|
||||
.child("child")
|
||||
.child("src")
|
||||
.child("child")
|
||||
.child("__init__.py")
|
||||
.touch()?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.sync(), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
Audited in [TIME]
|
||||
");
|
||||
|
||||
let lock = context.read("uv.lock");
|
||||
|
||||
insta::with_settings!({
|
||||
filters => context.filters(),
|
||||
}, {
|
||||
assert_snapshot!(
|
||||
lock, @r#"
|
||||
version = 1
|
||||
revision = 2
|
||||
requires-python = ">=3.12"
|
||||
conflicts = [[
|
||||
{ package = "project", group = "bar" },
|
||||
{ package = "project", group = "foo" },
|
||||
]]
|
||||
|
||||
[options]
|
||||
exclude-newer = "2024-03-25T00:00:00Z"
|
||||
|
||||
[[package]]
|
||||
name = "child"
|
||||
version = "0.1.0"
|
||||
source = { directory = "child" }
|
||||
|
||||
[[package]]
|
||||
name = "child"
|
||||
version = "0.1.0"
|
||||
source = { editable = "child" }
|
||||
|
||||
[[package]]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
|
||||
[package.dev-dependencies]
|
||||
bar = [
|
||||
{ name = "child", version = "0.1.0", source = { directory = "child" } },
|
||||
]
|
||||
foo = [
|
||||
{ name = "child", version = "0.1.0", source = { editable = "child" } },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
bar = [{ name = "child", directory = "child" }]
|
||||
foo = [{ name = "child", editable = "child" }]
|
||||
"#
|
||||
);
|
||||
});
|
||||
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--group").arg("foo"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
Prepared 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ child==0.1.0 (from file://[TEMP_DIR]/child)
|
||||
");
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_list().arg("--format").arg("json"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
[{"name":"child","version":"0.1.0","editable_project_location":"[TEMP_DIR]/child"}]
|
||||
|
||||
----- stderr -----
|
||||
"#);
|
||||
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--group").arg("bar"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
Prepared 1 package in [TIME]
|
||||
Uninstalled 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
~ child==0.1.0 (from file://[TEMP_DIR]/child)
|
||||
");
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_list().arg("--format").arg("json"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
[{"name":"child","version":"0.1.0"}]
|
||||
|
||||
----- stderr -----
|
||||
"#);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// See: <https://github.com/astral-sh/uv/issues/11648>
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn undeclared_editable() -> 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 = []
|
||||
|
||||
[dependency-groups]
|
||||
foo = [
|
||||
"child",
|
||||
]
|
||||
bar = [
|
||||
"child",
|
||||
]
|
||||
|
||||
[tool.uv]
|
||||
conflicts = [
|
||||
[
|
||||
{ group = "foo" },
|
||||
{ group = "bar" },
|
||||
],
|
||||
]
|
||||
|
||||
[tool.uv.sources]
|
||||
child = [
|
||||
{ path = "./child", editable = true, group = "foo" },
|
||||
{ path = "./child", group = "bar" },
|
||||
]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
context
|
||||
.temp_dir
|
||||
.child("child")
|
||||
.child("pyproject.toml")
|
||||
.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "child"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = []
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
"#,
|
||||
)?;
|
||||
context
|
||||
.temp_dir
|
||||
.child("child")
|
||||
.child("src")
|
||||
.child("child")
|
||||
.child("__init__.py")
|
||||
.touch()?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.sync(), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
Audited in [TIME]
|
||||
");
|
||||
|
||||
let lock = context.read("uv.lock");
|
||||
|
||||
insta::with_settings!({
|
||||
filters => context.filters(),
|
||||
}, {
|
||||
assert_snapshot!(
|
||||
lock, @r#"
|
||||
version = 1
|
||||
revision = 2
|
||||
requires-python = ">=3.12"
|
||||
conflicts = [[
|
||||
{ package = "project", group = "bar" },
|
||||
{ package = "project", group = "foo" },
|
||||
]]
|
||||
|
||||
[options]
|
||||
exclude-newer = "2024-03-25T00:00:00Z"
|
||||
|
||||
[[package]]
|
||||
name = "child"
|
||||
version = "0.1.0"
|
||||
source = { directory = "child" }
|
||||
|
||||
[[package]]
|
||||
name = "child"
|
||||
version = "0.1.0"
|
||||
source = { editable = "child" }
|
||||
|
||||
[[package]]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
|
||||
[package.dev-dependencies]
|
||||
bar = [
|
||||
{ name = "child", version = "0.1.0", source = { directory = "child" } },
|
||||
]
|
||||
foo = [
|
||||
{ name = "child", version = "0.1.0", source = { editable = "child" } },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
bar = [{ name = "child", directory = "child" }]
|
||||
foo = [{ name = "child", editable = "child" }]
|
||||
"#
|
||||
);
|
||||
});
|
||||
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--group").arg("foo"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
Prepared 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ child==0.1.0 (from file://[TEMP_DIR]/child)
|
||||
");
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_list().arg("--format").arg("json"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
[{"name":"child","version":"0.1.0","editable_project_location":"[TEMP_DIR]/child"}]
|
||||
|
||||
----- stderr -----
|
||||
"#);
|
||||
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--group").arg("bar"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
Prepared 1 package in [TIME]
|
||||
Uninstalled 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
~ child==0.1.0 (from file://[TEMP_DIR]/child)
|
||||
");
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_list().arg("--format").arg("json"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
[{"name":"child","version":"0.1.0"}]
|
||||
|
||||
----- stderr -----
|
||||
"#);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue