Remove some dependencies on EditableRequirement (#3727)

## Summary

Use `LocalEditable` instead throughout the `ResolvedEditable` pipeline.
This commit is contained in:
Charlie Marsh
2024-05-21 19:36:53 -04:00
committed by GitHub
parent 1379fb7dcd
commit 285adaed64
7 changed files with 35 additions and 36 deletions
+4 -4
View File
@@ -1,10 +1,10 @@
use serde::Deserialize;
use std::path::Path;
use distribution_types::{
CachedDist, InstalledDist, InstalledMetadata, InstalledVersion, LocalEditable, Name,
};
use pypi_types::Metadata23;
use requirements_txt::EditableRequirement;
use uv_normalize::PackageName;
@@ -112,10 +112,10 @@ impl std::fmt::Display for ResolvedEditable {
}
}
/// Returns `true` if the [`EditableRequirement`] contains dynamic metadata.
pub fn is_dynamic(editable: &EditableRequirement) -> bool {
/// Returns `true` if the source tree at the given path contains dynamic metadata.
pub fn is_dynamic(path: &Path) -> bool {
// If there's no `pyproject.toml`, we assume it's dynamic.
let Ok(contents) = fs_err::read_to_string(editable.path.join("pyproject.toml")) else {
let Ok(contents) = fs_err::read_to_string(path.join("pyproject.toml")) else {
return true;
};
let Ok(pyproject_toml) = toml::from_str::<PyProjectToml>(&contents) else {
+1 -1
View File
@@ -322,7 +322,7 @@ impl SitePackages {
}
// Does the editable have dynamic metadata?
if is_dynamic(requirement) {
if is_dynamic(&requirement.path) {
return Ok(SatisfiesResult::Unsatisfied(requirement.to_string()));
}
+3 -1
View File
@@ -342,7 +342,9 @@ pub(crate) async fn pip_install(
// Build all editable distributions. The editables are shared between resolution and
// installation, and should live for the duration of the command.
let editables = ResolvedEditables::resolve(
editables,
editables
.into_iter()
.map(ResolvedEditables::from_requirement),
&site_packages,
&reinstall,
&hasher,
+3 -1
View File
@@ -297,7 +297,9 @@ pub(crate) async fn pip_sync(
// Resolve any editables.
let editables = ResolvedEditables::resolve(
editables,
editables
.into_iter()
.map(ResolvedEditables::from_requirement),
&site_packages,
reinstall,
&hasher,
+4 -1
View File
@@ -108,7 +108,10 @@ pub(crate) async fn lock(
// Build all editable distributions. The editables are shared between resolution and
// installation, and should live for the duration of the command.
let editables = ResolvedEditables::resolve(
spec.editables.clone(),
spec.editables
.iter()
.cloned()
.map(ResolvedEditables::from_requirement),
&EmptyInstalledPackages,
&reinstall,
&hasher,
+4 -1
View File
@@ -574,7 +574,10 @@ pub(crate) async fn update_environment(
// Build all editable distributions. The editables are shared between resolution and
// installation, and should live for the duration of the command.
let editables = ResolvedEditables::resolve(
spec.editables.clone(),
spec.editables
.iter()
.cloned()
.map(ResolvedEditables::from_requirement),
&site_packages,
&reinstall,
&hasher,
+16 -27
View File
@@ -46,7 +46,7 @@ impl ResolvedEditables {
/// Resolve the set of editables that need to be installed.
#[allow(clippy::too_many_arguments)]
pub(crate) async fn resolve(
editables: Vec<EditableRequirement>,
editables: impl IntoIterator<Item = LocalEditable>,
installed_packages: &impl InstalledPackagesProvider,
reinstall: &Reinstall,
hasher: &HashStrategy,
@@ -59,8 +59,8 @@ impl ResolvedEditables {
printer: Printer,
) -> Result<Self> {
// Partition the editables into those that are already installed, and those that must be built.
let mut installed = Vec::with_capacity(editables.len());
let mut builds = Vec::with_capacity(editables.len());
let mut installed = Vec::new();
let mut builds = Vec::new();
for editable in editables {
match reinstall {
Reinstall::None => {
@@ -107,20 +107,7 @@ impl ResolvedEditables {
)
.with_reporter(DownloadReporter::from(printer).with_length(builds.len() as u64));
let editables = LocalEditables::from_editables(builds.iter().map(|editable| {
let EditableRequirement {
url,
path,
extras,
marker: _,
origin: _,
} = editable;
LocalEditable {
url: url.clone(),
path: path.clone(),
extras: extras.clone(),
}
}));
let editables = LocalEditables::from_editables(builds.into_iter());
let temp_dir = tempfile::tempdir_in(cache.root())?;
@@ -193,21 +180,27 @@ impl ResolvedEditables {
})
.collect()
}
/// Convert an [`EditableRequirement`] into a [`LocalEditable`].
pub(crate) fn from_requirement(editable: EditableRequirement) -> LocalEditable {
LocalEditable {
url: editable.url,
path: editable.path,
extras: editable.extras,
}
}
}
/// Returns the [`InstalledEditable`] if the installed distribution is up-to-date for the given
/// requirement.
fn up_to_date(
editable: &EditableRequirement,
dist: &InstalledDist,
) -> Result<Option<InstalledEditable>> {
fn up_to_date(editable: &LocalEditable, dist: &InstalledDist) -> Result<Option<InstalledEditable>> {
// If the editable isn't up-to-date, don't reuse it.
if !ArchiveTimestamp::up_to_date_with(&editable.path, ArchiveTarget::Install(dist))? {
return Ok(None);
};
// If the editable is dynamic, don't reuse it.
if is_dynamic(editable) {
if is_dynamic(&editable.path) {
return Ok(None);
};
@@ -217,11 +210,7 @@ fn up_to_date(
};
Ok(Some(InstalledEditable {
editable: LocalEditable {
url: editable.url.clone(),
path: editable.path.clone(),
extras: editable.extras.clone(),
},
editable: editable.clone(),
wheel: (*dist).clone(),
metadata,
}))