Use Box<Path> in lieu of PathBuf for immutable structs (#12346)

## Summary

I don't know if I actually want to commit this, but I did it on the
plane last time and just polished it off (got it to compile) while
waiting to board.
This commit is contained in:
Charlie Marsh 2025-03-25 17:56:06 -04:00 committed by GitHub
parent 9745b76357
commit e4c98e976f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 225 additions and 180 deletions

View file

@ -1185,7 +1185,7 @@ pub enum Refresh {
/// Don't refresh any entries.
None(Timestamp),
/// Refresh entries linked to the given packages, if created before the given timestamp.
Packages(Vec<PackageName>, Vec<PathBuf>, Timestamp),
Packages(Vec<PackageName>, Vec<Box<Path>>, Timestamp),
/// Refresh all entries created before the given timestamp.
All(Timestamp),
}

View file

@ -623,7 +623,7 @@ impl RegistryClient {
.await?
}
BuiltDist::Path(wheel) => {
let file = fs_err::tokio::File::open(&wheel.install_path)
let file = fs_err::tokio::File::open(wheel.install_path.as_ref())
.await
.map_err(ErrorKind::Io)?;
let reader = tokio::io::BufReader::new(file);

View file

@ -1,4 +1,4 @@
use std::path::{Path, PathBuf};
use std::path::Path;
use either::Either;
use rustc_hash::FxHashMap;
@ -20,7 +20,7 @@ pub enum Reinstall {
All,
/// Reinstall only the specified packages.
Packages(Vec<PackageName>, Vec<PathBuf>),
Packages(Vec<PackageName>, Vec<Box<Path>>),
}
impl Reinstall {
@ -89,9 +89,9 @@ impl Reinstall {
}
}
/// Add a [`PathBuf`] to the [`Reinstall`] policy.
/// Add a [`Box<Path>`] to the [`Reinstall`] policy.
#[must_use]
pub fn with_path(self, path: PathBuf) -> Self {
pub fn with_path(self, path: Box<Path>) -> Self {
match self {
Self::None => Self::Packages(vec![], vec![path]),
Self::All => Self::All,

View file

@ -1,4 +1,4 @@
use std::path::{Path, PathBuf};
use std::path::Path;
use uv_cache_info::CacheInfo;
use uv_distribution_filename::WheelFilename;
@ -22,7 +22,7 @@ pub enum CachedDist {
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct CachedRegistryDist {
pub filename: WheelFilename,
pub path: PathBuf,
pub path: Box<Path>,
pub hashes: HashDigests,
pub cache_info: CacheInfo,
}
@ -31,7 +31,7 @@ pub struct CachedRegistryDist {
pub struct CachedDirectUrlDist {
pub filename: WheelFilename,
pub url: VerbatimParsedUrl,
pub path: PathBuf,
pub path: Box<Path>,
pub hashes: HashDigests,
pub cache_info: CacheInfo,
}
@ -43,7 +43,7 @@ impl CachedDist {
filename: WheelFilename,
hashes: HashDigests,
cache_info: CacheInfo,
path: PathBuf,
path: Box<Path>,
) -> Self {
match remote {
Dist::Built(BuiltDist::Registry(_dist)) => Self::Registry(CachedRegistryDist {

View file

@ -77,7 +77,7 @@ pub enum InstalledDist {
pub struct InstalledRegistryDist {
pub name: PackageName,
pub version: Version,
pub path: PathBuf,
pub path: Box<Path>,
pub cache_info: Option<CacheInfo>,
}
@ -88,7 +88,7 @@ pub struct InstalledDirectUrlDist {
pub direct_url: Box<DirectUrl>,
pub url: Url,
pub editable: bool,
pub path: PathBuf,
pub path: Box<Path>,
pub cache_info: Option<CacheInfo>,
}
@ -96,24 +96,24 @@ pub struct InstalledDirectUrlDist {
pub struct InstalledEggInfoFile {
pub name: PackageName,
pub version: Version,
pub path: PathBuf,
pub path: Box<Path>,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct InstalledEggInfoDirectory {
pub name: PackageName,
pub version: Version,
pub path: PathBuf,
pub path: Box<Path>,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct InstalledLegacyEditable {
pub name: PackageName,
pub version: Version,
pub egg_link: PathBuf,
pub target: PathBuf,
pub egg_link: Box<Path>,
pub target: Box<Path>,
pub target_url: Url,
pub egg_info: PathBuf,
pub egg_info: Box<Path>,
}
impl InstalledDist {
@ -145,7 +145,7 @@ impl InstalledDist {
editable: matches!(&direct_url, DirectUrl::LocalDirectory { dir_info, .. } if dir_info.editable == Some(true)),
direct_url: Box::new(direct_url),
url,
path: path.to_path_buf(),
path: path.to_path_buf().into_boxed_path(),
cache_info,
}))),
Err(err) => {
@ -153,7 +153,7 @@ impl InstalledDist {
Ok(Some(Self::Registry(InstalledRegistryDist {
name,
version,
path: path.to_path_buf(),
path: path.to_path_buf().into_boxed_path(),
cache_info,
})))
}
@ -162,7 +162,7 @@ impl InstalledDist {
Ok(Some(Self::Registry(InstalledRegistryDist {
name,
version,
path: path.to_path_buf(),
path: path.to_path_buf().into_boxed_path(),
cache_info,
})))
};
@ -191,7 +191,7 @@ impl InstalledDist {
return Ok(Some(Self::EggInfoDirectory(InstalledEggInfoDirectory {
name: file_name.name,
version,
path: path.to_path_buf(),
path: path.to_path_buf().into_boxed_path(),
})));
}
@ -199,7 +199,7 @@ impl InstalledDist {
return Ok(Some(Self::EggInfoFile(InstalledEggInfoFile {
name: file_name.name,
version,
path: path.to_path_buf(),
path: path.to_path_buf().into_boxed_path(),
})));
}
};
@ -211,7 +211,7 @@ impl InstalledDist {
return Ok(Some(Self::EggInfoDirectory(InstalledEggInfoDirectory {
name: file_name.name,
version: Version::from_str(&egg_metadata.version)?,
path: path.to_path_buf(),
path: path.to_path_buf().into_boxed_path(),
})));
}
@ -222,7 +222,7 @@ impl InstalledDist {
return Ok(Some(Self::EggInfoDirectory(InstalledEggInfoDirectory {
name: file_name.name,
version: Version::from_str(&egg_metadata.version)?,
path: path.to_path_buf(),
path: path.to_path_buf().into_boxed_path(),
})));
}
}
@ -270,10 +270,10 @@ impl InstalledDist {
return Ok(Some(Self::LegacyEditable(InstalledLegacyEditable {
name: egg_metadata.name,
version: Version::from_str(&egg_metadata.version)?,
egg_link: path.to_path_buf(),
target,
egg_link: path.to_path_buf().into_boxed_path(),
target: target.into_boxed_path(),
target_url: url,
egg_info,
egg_info: egg_info.into_boxed_path(),
})));
}
@ -344,7 +344,7 @@ impl InstalledDist {
}
Self::EggInfoFile(_) | Self::EggInfoDirectory(_) | Self::LegacyEditable(_) => {
let path = match self {
Self::EggInfoFile(dist) => Cow::Borrowed(&dist.path),
Self::EggInfoFile(dist) => Cow::Borrowed(&*dist.path),
Self::EggInfoDirectory(dist) => Cow::Owned(dist.path.join("PKG-INFO")),
Self::LegacyEditable(dist) => Cow::Owned(dist.egg_info.join("PKG-INFO")),
_ => unreachable!(),

View file

@ -34,7 +34,7 @@
//! Since we read this information from [`direct_url.json`](https://packaging.python.org/en/latest/specifications/direct-url-data-structure/), it doesn't match the information [`Dist`] exactly.
use std::borrow::Cow;
use std::path;
use std::path::{Path, PathBuf};
use std::path::Path;
use std::str::FromStr;
use url::Url;
@ -266,7 +266,7 @@ pub struct DirectUrlBuiltDist {
pub struct PathBuiltDist {
pub filename: WheelFilename,
/// The absolute path to the wheel which we use for installing.
pub install_path: PathBuf,
pub install_path: Box<Path>,
/// The URL as it was provided by the user.
pub url: VerbatimUrl,
}
@ -299,7 +299,7 @@ pub struct DirectUrlSourceDist {
/// The URL without the subdirectory fragment.
pub location: Box<Url>,
/// The subdirectory within the archive in which the source distribution is located.
pub subdirectory: Option<PathBuf>,
pub subdirectory: Option<Box<Path>>,
/// The file extension, e.g. `tar.gz`, `zip`, etc.
pub ext: SourceDistExtension,
/// The URL as it was provided by the user, including the subdirectory fragment.
@ -313,7 +313,7 @@ pub struct GitSourceDist {
/// The URL without the revision and subdirectory fragment.
pub git: Box<GitUrl>,
/// The subdirectory within the Git repository in which the source distribution is located.
pub subdirectory: Option<PathBuf>,
pub subdirectory: Option<Box<Path>>,
/// The URL as it was provided by the user, including the revision and subdirectory fragment.
pub url: VerbatimUrl,
}
@ -324,7 +324,7 @@ pub struct PathSourceDist {
pub name: PackageName,
pub version: Option<Version>,
/// The absolute path to the distribution which we use for installing.
pub install_path: PathBuf,
pub install_path: Box<Path>,
/// The file extension, e.g. `tar.gz`, `zip`, etc.
pub ext: SourceDistExtension,
/// The URL as it was provided by the user.
@ -336,7 +336,7 @@ pub struct PathSourceDist {
pub struct DirectorySourceDist {
pub name: PackageName,
/// The absolute path to the distribution which we use for installing.
pub install_path: PathBuf,
pub install_path: Box<Path>,
/// Whether the package should be installed in editable mode.
pub editable: bool,
/// Whether the package should be built and installed.
@ -352,7 +352,7 @@ impl Dist {
name: PackageName,
url: VerbatimUrl,
location: Url,
subdirectory: Option<PathBuf>,
subdirectory: Option<Box<Path>>,
ext: DistExtension,
) -> Result<Dist, Error> {
match ext {
@ -417,7 +417,7 @@ impl Dist {
}
Ok(Self::Built(BuiltDist::Path(PathBuiltDist {
filename,
install_path,
install_path: install_path.into_boxed_path(),
url,
})))
}
@ -434,7 +434,7 @@ impl Dist {
Ok(Self::Source(SourceDist::Path(PathSourceDist {
name,
version,
install_path,
install_path: install_path.into_boxed_path(),
ext,
url,
})))
@ -464,7 +464,7 @@ impl Dist {
// Determine whether the path represents an archive or a directory.
Ok(Self::Source(SourceDist::Directory(DirectorySourceDist {
name,
install_path,
install_path: install_path.into_boxed_path(),
editable,
r#virtual,
url,
@ -476,7 +476,7 @@ impl Dist {
name: PackageName,
url: VerbatimUrl,
git: GitUrl,
subdirectory: Option<PathBuf>,
subdirectory: Option<Box<Path>>,
) -> Result<Dist, Error> {
Ok(Self::Source(SourceDist::Git(GitSourceDist {
name,

View file

@ -1,6 +1,6 @@
use std::fmt::{Display, Formatter};
use std::io;
use std::path::{Path, PathBuf};
use std::path::Path;
use std::str::FromStr;
use thiserror::Error;
@ -385,7 +385,7 @@ pub enum RequirementSource {
location: Url,
/// For source distributions, the path to the distribution if it is not in the archive
/// root.
subdirectory: Option<PathBuf>,
subdirectory: Option<Box<Path>>,
/// The file extension, e.g. `tar.gz`, `zip`, etc.
ext: DistExtension,
/// The PEP 508 style URL in the format
@ -397,7 +397,7 @@ pub enum RequirementSource {
/// The repository URL and reference to the commit to use.
git: GitUrl,
/// The path to the source distribution if it is not in the repository root.
subdirectory: Option<PathBuf>,
subdirectory: Option<Box<Path>>,
/// The PEP 508 style url in the format
/// `git+<scheme>://<domain>/<path>@<rev>#subdirectory=<subdirectory>`.
url: VerbatimUrl,
@ -407,7 +407,7 @@ pub enum RequirementSource {
/// `.tar.gz` file).
Path {
/// The absolute path to the distribution which we use for installing.
install_path: PathBuf,
install_path: Box<Path>,
/// The file extension, e.g. `tar.gz`, `zip`, etc.
ext: DistExtension,
/// The PEP 508 style URL in the format
@ -418,7 +418,7 @@ pub enum RequirementSource {
/// source distribution with only a setup.py but non pyproject.toml in it).
Directory {
/// The absolute path to the distribution which we use for installing.
install_path: PathBuf,
install_path: Box<Path>,
/// For a source tree (a directory), whether to install as an editable.
editable: bool,
/// For a source tree (a directory), whether the project should be built and installed.
@ -572,7 +572,8 @@ impl RequirementSource {
url,
} => Ok(Self::Path {
install_path: relative_to(&install_path, path)
.or_else(|_| std::path::absolute(install_path))?,
.or_else(|_| std::path::absolute(install_path))?
.into_boxed_path(),
ext,
url,
}),
@ -584,7 +585,8 @@ impl RequirementSource {
..
} => Ok(Self::Directory {
install_path: relative_to(&install_path, path)
.or_else(|_| std::path::absolute(install_path))?,
.or_else(|_| std::path::absolute(install_path))?
.into_boxed_path(),
editable,
r#virtual,
url,
@ -821,7 +823,7 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
Ok(Self::Git {
git: GitUrl::from_fields(repository, reference, precise)?,
subdirectory: subdirectory.map(PathBuf::from),
subdirectory: subdirectory.map(Box::<Path>::from),
url,
})
}
@ -836,7 +838,7 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
Ok(Self::Url {
location,
subdirectory: subdirectory.map(PathBuf::from),
subdirectory: subdirectory.map(Box::<Path>::from),
ext: DistExtension::from_path(url.path())
.map_err(|err| ParsedUrlError::MissingExtensionUrl(url.to_string(), err))?,
url: VerbatimUrl::from_url(url.clone()),
@ -847,18 +849,19 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
// sources in the lockfile, we replace the URL anyway. Ideally, we'd either remove the
// URL field or make it optional.
RequirementSourceWire::Path { path } => {
let path = PathBuf::from(path);
let path = Box::<Path>::from(path);
let url =
VerbatimUrl::from_normalized_path(uv_fs::normalize_path_buf(CWD.join(&path)))?;
Ok(Self::Path {
ext: DistExtension::from_path(path.as_path())
.map_err(|err| ParsedUrlError::MissingExtensionPath(path.clone(), err))?,
ext: DistExtension::from_path(&path).map_err(|err| {
ParsedUrlError::MissingExtensionPath(path.to_path_buf(), err)
})?,
install_path: path,
url,
})
}
RequirementSourceWire::Directory { directory } => {
let directory = PathBuf::from(directory);
let directory = Box::<Path>::from(directory);
let url = VerbatimUrl::from_normalized_path(uv_fs::normalize_path_buf(
CWD.join(&directory),
))?;
@ -870,7 +873,7 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
})
}
RequirementSourceWire::Editable { editable } => {
let editable = PathBuf::from(editable);
let editable = Box::<Path>::from(editable);
let url = VerbatimUrl::from_normalized_path(uv_fs::normalize_path_buf(
CWD.join(&editable),
))?;
@ -882,7 +885,7 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
})
}
RequirementSourceWire::Virtual { r#virtual } => {
let r#virtual = PathBuf::from(r#virtual);
let r#virtual = Box::<Path>::from(r#virtual);
let url = VerbatimUrl::from_normalized_path(uv_fs::normalize_path_buf(
CWD.join(&r#virtual),
))?;
@ -947,7 +950,7 @@ mod tests {
groups: Box::new([]),
marker: MarkerTree::TRUE,
source: RequirementSource::Directory {
install_path: PathBuf::from(path),
install_path: PathBuf::from(path).into_boxed_path(),
editable: false,
r#virtual: false,
url: VerbatimUrl::from_absolute_path(path).unwrap(),

View file

@ -216,7 +216,11 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
{
Ok(archive) => Ok(LocalWheel {
dist: Dist::Built(dist.clone()),
archive: self.build_context.cache().archive(&archive.id),
archive: self
.build_context
.cache()
.archive(&archive.id)
.into_boxed_path(),
hashes: archive.hashes,
filename: wheel.filename.clone(),
cache: CacheInfo::default(),
@ -247,7 +251,11 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
Ok(LocalWheel {
dist: Dist::Built(dist.clone()),
archive: self.build_context.cache().archive(&archive.id),
archive: self
.build_context
.cache()
.archive(&archive.id)
.into_boxed_path(),
hashes: archive.hashes,
filename: wheel.filename.clone(),
cache: CacheInfo::default(),
@ -279,7 +287,11 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
{
Ok(archive) => Ok(LocalWheel {
dist: Dist::Built(dist.clone()),
archive: self.build_context.cache().archive(&archive.id),
archive: self
.build_context
.cache()
.archive(&archive.id)
.into_boxed_path(),
hashes: archive.hashes,
filename: wheel.filename.clone(),
cache: CacheInfo::default(),
@ -303,7 +315,11 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
.await?;
Ok(LocalWheel {
dist: Dist::Built(dist.clone()),
archive: self.build_context.cache().archive(&archive.id),
archive: self
.build_context
.cache()
.archive(&archive.id)
.into_boxed_path(),
hashes: archive.hashes,
filename: wheel.filename.clone(),
cache: CacheInfo::default(),
@ -368,7 +384,7 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
Ok(archive) => {
return Ok(LocalWheel {
dist: Dist::Source(dist.clone()),
archive,
archive: archive.into_boxed_path(),
filename: built_wheel.filename,
hashes: built_wheel.hashes,
cache: built_wheel.cache_info,
@ -385,7 +401,7 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
Ok(LocalWheel {
dist: Dist::Source(dist.clone()),
archive: self.build_context.cache().archive(&id),
archive: self.build_context.cache().archive(&id).into_boxed_path(),
hashes: built_wheel.hashes,
filename: built_wheel.filename,
cache: built_wheel.cache_info,
@ -837,7 +853,11 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
if let Some(archive) = archive {
Ok(LocalWheel {
dist: Dist::Built(dist.clone()),
archive: self.build_context.cache().archive(&archive.id),
archive: self
.build_context
.cache()
.archive(&archive.id)
.into_boxed_path(),
hashes: archive.hashes,
filename: filename.clone(),
cache: CacheInfo::from_timestamp(modified),
@ -859,7 +879,11 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
Ok(LocalWheel {
dist: Dist::Built(dist.clone()),
archive: self.build_context.cache().archive(&archive.id),
archive: self
.build_context
.cache()
.archive(&archive.id)
.into_boxed_path(),
hashes: archive.hashes,
filename: filename.clone(),
cache: CacheInfo::from_timestamp(modified),
@ -905,7 +929,11 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
Ok(LocalWheel {
dist: Dist::Built(dist.clone()),
archive: self.build_context.cache().archive(&archive.id),
archive: self
.build_context
.cache()
.archive(&archive.id)
.into_boxed_path(),
hashes: archive.hashes,
filename: filename.clone(),
cache: CacheInfo::from_timestamp(modified),

View file

@ -1,12 +1,12 @@
use std::path::{Path, PathBuf};
use std::path::Path;
use crate::Error;
use uv_cache_info::CacheInfo;
use uv_distribution_filename::WheelFilename;
use uv_distribution_types::{CachedDist, Dist, Hashed};
use uv_metadata::read_flat_wheel_metadata;
use uv_pypi_types::{HashDigest, HashDigests, ResolutionMetadata};
use uv_cache_info::CacheInfo;
use crate::Error;
/// A locally available wheel.
#[derive(Debug, Clone)]
@ -17,7 +17,7 @@ pub struct LocalWheel {
pub(crate) filename: WheelFilename,
/// The canonicalized path in the cache directory to which the wheel was downloaded.
/// Typically, a directory within the archive bucket.
pub(crate) archive: PathBuf,
pub(crate) archive: Box<Path>,
/// The cache index of the wheel.
pub(crate) cache: CacheInfo,
/// The computed hashes of the wheel.
@ -43,7 +43,7 @@ impl LocalWheel {
/// Read the [`ResolutionMetadata`] from a wheel.
pub fn metadata(&self) -> Result<ResolutionMetadata, Error> {
read_flat_wheel_metadata(&self.filename, &self.archive)
.map_err(|err| Error::WheelMetadata(self.archive.clone(), Box::new(err)))
.map_err(|err| Error::WheelMetadata(self.archive.to_path_buf(), Box::new(err)))
}
}

View file

@ -50,7 +50,7 @@ impl CachedWheel {
pub fn into_registry_dist(self) -> CachedRegistryDist {
CachedRegistryDist {
filename: self.filename,
path: self.entry.into_path_buf(),
path: self.entry.into_path_buf().into_boxed_path(),
hashes: self.hashes,
cache_info: self.cache_info,
}
@ -65,7 +65,7 @@ impl CachedWheel {
parsed_url: dist.parsed_url(),
verbatim: dist.url.clone(),
},
path: self.entry.into_path_buf(),
path: self.entry.into_path_buf().into_boxed_path(),
hashes: self.hashes,
cache_info: self.cache_info,
}
@ -80,7 +80,7 @@ impl CachedWheel {
parsed_url: dist.parsed_url(),
verbatim: dist.url.clone(),
},
path: self.entry.into_path_buf(),
path: self.entry.into_path_buf().into_boxed_path(),
hashes: self.hashes,
cache_info: self.cache_info,
}
@ -95,7 +95,7 @@ impl CachedWheel {
parsed_url: dist.parsed_url(),
verbatim: dist.url.clone(),
},
path: self.entry.into_path_buf(),
path: self.entry.into_path_buf().into_boxed_path(),
hashes: self.hashes,
cache_info: self.cache_info,
}
@ -110,7 +110,7 @@ impl CachedWheel {
parsed_url: dist.parsed_url(),
verbatim: dist.url.clone(),
},
path: self.entry.into_path_buf(),
path: self.entry.into_path_buf().into_boxed_path(),
hashes: self.hashes,
cache_info: self.cache_info,
}

View file

@ -171,7 +171,7 @@ impl LoweredRequirement {
} => {
let source = git_source(
&git,
subdirectory.map(PathBuf::from),
subdirectory.map(Box::<Path>::from),
rev,
tag,
branch,
@ -185,7 +185,7 @@ impl LoweredRequirement {
..
} => {
let source =
url_source(&requirement, url, subdirectory.map(PathBuf::from))?;
url_source(&requirement, url, subdirectory.map(Box::<Path>::from))?;
(source, marker)
}
Source::Path {
@ -196,7 +196,7 @@ impl LoweredRequirement {
..
} => {
let source = path_source(
PathBuf::from(path),
path,
git_member,
origin,
project_dir,
@ -298,20 +298,20 @@ impl LoweredRequirement {
subdirectory: if subdirectory == PathBuf::new() {
None
} else {
Some(subdirectory)
Some(subdirectory.into_boxed_path())
},
url,
}
} else if member.pyproject_toml().is_package() {
RequirementSource::Directory {
install_path,
install_path: install_path.into_boxed_path(),
url,
editable: true,
r#virtual: false,
}
} else {
RequirementSource::Directory {
install_path,
install_path: install_path.into_boxed_path(),
url,
editable: false,
r#virtual: true,
@ -404,7 +404,7 @@ impl LoweredRequirement {
} => {
let source = git_source(
&git,
subdirectory.map(PathBuf::from),
subdirectory.map(Box::<Path>::from),
rev,
tag,
branch,
@ -418,7 +418,7 @@ impl LoweredRequirement {
..
} => {
let source =
url_source(&requirement, url, subdirectory.map(PathBuf::from))?;
url_source(&requirement, url, subdirectory.map(Box::<Path>::from))?;
(source, marker)
}
Source::Path {
@ -429,7 +429,7 @@ impl LoweredRequirement {
..
} => {
let source = path_source(
PathBuf::from(path),
path,
None,
RequirementOrigin::Project,
dir,
@ -554,7 +554,7 @@ impl std::fmt::Display for SourceKind {
/// Convert a Git source into a [`RequirementSource`].
fn git_source(
git: &Url,
subdirectory: Option<PathBuf>,
subdirectory: Option<Box<Path>>,
rev: Option<String>,
tag: Option<String>,
branch: Option<String>,
@ -575,7 +575,7 @@ fn git_source(
if let Some(subdirectory) = subdirectory.as_ref() {
let subdirectory = subdirectory
.to_str()
.ok_or_else(|| LoweringError::NonUtf8Path(subdirectory.clone()))?;
.ok_or_else(|| LoweringError::NonUtf8Path(subdirectory.to_path_buf()))?;
url.set_fragment(Some(&format!("subdirectory={subdirectory}")));
}
let url = VerbatimUrl::from_url(url);
@ -593,7 +593,7 @@ fn git_source(
fn url_source(
requirement: &uv_pep508::Requirement<VerbatimParsedUrl>,
url: Url,
subdirectory: Option<PathBuf>,
subdirectory: Option<Box<Path>>,
) -> Result<RequirementSource, LoweringError> {
let mut verbatim_url = url.clone();
if verbatim_url.fragment().is_some() {
@ -602,7 +602,7 @@ fn url_source(
if let Some(subdirectory) = subdirectory.as_ref() {
let subdirectory = subdirectory
.to_str()
.ok_or_else(|| LoweringError::NonUtf8Path(subdirectory.clone()))?;
.ok_or_else(|| LoweringError::NonUtf8Path(subdirectory.to_path_buf()))?;
verbatim_url.set_fragment(Some(&format!("subdirectory={subdirectory}")));
}
@ -691,7 +691,7 @@ fn path_source(
subdirectory: if subdirectory == PathBuf::new() {
None
} else {
Some(subdirectory)
Some(subdirectory.into_boxed_path())
},
url,
});
@ -699,7 +699,7 @@ fn path_source(
if editable == Some(true) {
Ok(RequirementSource::Directory {
install_path,
install_path: install_path.into_boxed_path(),
url,
editable: true,
r#virtual: false,
@ -716,7 +716,7 @@ fn path_source(
});
Ok(RequirementSource::Directory {
install_path,
install_path: install_path.into_boxed_path(),
url,
editable: false,
// If a project is not a package, treat it as a virtual dependency.
@ -737,7 +737,7 @@ fn path_source(
Ok(RequirementSource::Path {
ext: DistExtension::from_path(&install_path)
.map_err(|err| ParsedUrlError::MissingExtensionPath(path.to_path_buf(), err))?,
install_path,
install_path: install_path.into_boxed_path(),
url,
})
}

View file

@ -1,4 +1,4 @@
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use uv_cache::CacheShard;
@ -15,9 +15,9 @@ use uv_pypi_types::{HashDigest, HashDigests};
#[derive(Debug, Clone)]
pub(crate) struct BuiltWheelMetadata {
/// The path to the built wheel.
pub(crate) path: PathBuf,
pub(crate) path: Box<Path>,
/// The expected path to the downloaded wheel's entry in the cache.
pub(crate) target: PathBuf,
pub(crate) target: Box<Path>,
/// The parsed filename.
pub(crate) filename: WheelFilename,
/// The computed hashes of the source distribution from which the wheel was built.
@ -48,8 +48,8 @@ impl BuiltWheelMetadata {
let filename = path.file_name()?.to_str()?;
let filename = WheelFilename::from_str(filename).ok()?;
Some(Self {
target: cache_shard.join(filename.stem()),
path,
target: cache_shard.join(filename.stem()).into_boxed_path(),
path: path.into_boxed_path(),
filename,
cache_info: CacheInfo::default(),
hashes: HashDigests::empty(),

View file

@ -487,8 +487,8 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
.map_err(Error::CacheWrite)?;
Ok(BuiltWheelMetadata {
path: cache_shard.join(&disk_filename),
target: cache_shard.join(wheel_filename.stem()),
path: cache_shard.join(&disk_filename).into_boxed_path(),
target: cache_shard.join(wheel_filename.stem()).into_boxed_path(),
filename: wheel_filename,
hashes: revision.into_hashes(),
cache_info: CacheInfo::default(),
@ -840,8 +840,8 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
.map_err(Error::CacheWrite)?;
Ok(BuiltWheelMetadata {
path: cache_shard.join(&disk_filename),
target: cache_shard.join(filename.stem()),
path: cache_shard.join(&disk_filename).into_boxed_path(),
target: cache_shard.join(filename.stem()).into_boxed_path(),
filename,
hashes: revision.into_hashes(),
cache_info,
@ -1137,8 +1137,8 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
.map_err(Error::CacheWrite)?;
Ok(BuiltWheelMetadata {
path: cache_shard.join(&disk_filename),
target: cache_shard.join(filename.stem()),
path: cache_shard.join(&disk_filename).into_boxed_path(),
target: cache_shard.join(filename.stem()).into_boxed_path(),
filename,
hashes: revision.into_hashes(),
cache_info,
@ -1527,8 +1527,8 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
.map_err(Error::CacheWrite)?;
Ok(BuiltWheelMetadata {
path: cache_shard.join(&disk_filename),
target: cache_shard.join(filename.stem()),
path: cache_shard.join(&disk_filename).into_boxed_path(),
target: cache_shard.join(filename.stem()).into_boxed_path(),
filename,
hashes: HashDigests::empty(),
cache_info: CacheInfo::default(),

View file

@ -344,7 +344,7 @@ pub fn relative_to(
pub struct PortablePath<'a>(&'a Path);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PortablePathBuf(PathBuf);
pub struct PortablePathBuf(Box<Path>);
#[cfg(feature = "schemars")]
impl schemars::JsonSchema for PortablePathBuf {
@ -397,21 +397,21 @@ impl std::fmt::Display for PortablePathBuf {
impl From<&str> for PortablePathBuf {
fn from(path: &str) -> Self {
if path == "." {
Self(PathBuf::new())
Self(PathBuf::new().into_boxed_path())
} else {
Self(PathBuf::from(path))
Self(PathBuf::from(path).into_boxed_path())
}
}
}
impl From<PortablePathBuf> for PathBuf {
impl From<PortablePathBuf> for Box<Path> {
fn from(portable: PortablePathBuf) -> Self {
portable.0
}
}
impl From<PathBuf> for PortablePathBuf {
fn from(path: PathBuf) -> Self {
impl From<Box<Path>> for PortablePathBuf {
fn from(path: Box<Path>) -> Self {
Self(path)
}
}
@ -444,13 +444,19 @@ impl<'de> serde::de::Deserialize<'de> for PortablePathBuf {
{
let s = String::deserialize(deserializer)?;
if s == "." {
Ok(Self(PathBuf::new()))
Ok(Self(PathBuf::new().into_boxed_path()))
} else {
Ok(Self(PathBuf::from(s)))
Ok(Self(PathBuf::from(s).into_boxed_path()))
}
}
}
impl AsRef<Path> for PortablePathBuf {
fn as_ref(&self) -> &Path {
&self.0
}
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -33,9 +33,9 @@ pub enum GitError {
/// A global cache of the result of `which git`.
pub static GIT: LazyLock<Result<PathBuf, GitError>> = LazyLock::new(|| {
which::which("git").map_err(|e| match e {
which::which("git").map_err(|err| match err {
which::Error::CannotFindBinaryPath => GitError::GitNotFound,
e => GitError::Other(e),
err => GitError::Other(err),
})
});

View file

@ -196,7 +196,7 @@ impl<'a> Planner<'a> {
},
hashes: archive.hashes,
cache_info,
path: cache.archive(&archive.id),
path: cache.archive(&archive.id).into_boxed_path(),
};
debug!("URL wheel requirement already cached: {cached_dist}");
@ -256,7 +256,7 @@ impl<'a> Planner<'a> {
},
hashes: archive.hashes,
cache_info,
path: cache.archive(&archive.id),
path: cache.archive(&archive.id).into_boxed_path(),
};
debug!("Path wheel requirement already cached: {cached_dist}");

View file

@ -189,7 +189,7 @@ impl RequirementSatisfaction {
return Self::Mismatch;
};
if !(*requested_path == installed_path
if !(**requested_path == installed_path
|| is_same_file(requested_path, &installed_path).unwrap_or(false))
{
trace!(
@ -258,7 +258,7 @@ impl RequirementSatisfaction {
return Self::Mismatch;
};
if !(*requested_path == installed_path
if !(**requested_path == installed_path
|| is_same_file(requested_path, &installed_path).unwrap_or(false))
{
trace!(

View file

@ -1,5 +1,5 @@
use std::collections::BTreeMap;
use std::path::PathBuf;
use std::path::Path;
use serde::{Deserialize, Serialize};
use url::Url;
@ -27,7 +27,7 @@ pub enum DirectUrl {
url: String,
archive_info: ArchiveInfo,
#[serde(skip_serializing_if = "Option::is_none")]
subdirectory: Option<PathBuf>,
subdirectory: Option<Box<Path>>,
},
/// The direct URL is path to a VCS repository. For example:
/// ```json
@ -37,7 +37,7 @@ pub enum DirectUrl {
url: String,
vcs_info: VcsInfo,
#[serde(skip_serializing_if = "Option::is_none")]
subdirectory: Option<PathBuf>,
subdirectory: Option<Box<Path>>,
},
}

View file

@ -73,17 +73,19 @@ impl UnnamedRequirementUrl for VerbatimParsedUrl {
} else {
verbatim_path.extension().is_none()
};
let url = verbatim.to_url();
let install_path = verbatim.as_path()?.into_boxed_path();
let parsed_url = if is_dir {
ParsedUrl::Directory(ParsedDirectoryUrl {
url: verbatim.to_url(),
install_path: verbatim.as_path()?,
url,
install_path,
editable: false,
r#virtual: false,
})
} else {
ParsedUrl::Path(ParsedPathUrl {
url: verbatim.to_url(),
install_path: verbatim.as_path()?,
url,
install_path,
ext: DistExtension::from_path(&path).map_err(|err| {
ParsedUrlError::MissingExtensionPath(path.as_ref().to_path_buf(), err)
})?,
@ -103,17 +105,19 @@ impl UnnamedRequirementUrl for VerbatimParsedUrl {
} else {
verbatim_path.extension().is_none()
};
let url = verbatim.to_url();
let install_path = verbatim.as_path()?.into_boxed_path();
let parsed_url = if is_dir {
ParsedUrl::Directory(ParsedDirectoryUrl {
url: verbatim.to_url(),
install_path: verbatim.as_path()?,
url,
install_path,
editable: false,
r#virtual: false,
})
} else {
ParsedUrl::Path(ParsedPathUrl {
url: verbatim.to_url(),
install_path: verbatim.as_path()?,
url,
install_path,
ext: DistExtension::from_path(&path).map_err(|err| {
ParsedUrlError::MissingExtensionPath(path.as_ref().to_path_buf(), err)
})?,
@ -190,14 +194,14 @@ impl ParsedUrl {
pub struct ParsedPathUrl {
pub url: Url,
/// The absolute path to the distribution which we use for installing.
pub install_path: PathBuf,
pub install_path: Box<Path>,
/// The file extension, e.g. `tar.gz`, `zip`, etc.
pub ext: DistExtension,
}
impl ParsedPathUrl {
/// Construct a [`ParsedPathUrl`] from a path requirement source.
pub fn from_source(install_path: PathBuf, ext: DistExtension, url: Url) -> Self {
pub fn from_source(install_path: Box<Path>, ext: DistExtension, url: Url) -> Self {
Self {
url,
install_path,
@ -214,14 +218,14 @@ impl ParsedPathUrl {
pub struct ParsedDirectoryUrl {
pub url: Url,
/// The absolute path to the distribution which we use for installing.
pub install_path: PathBuf,
pub install_path: Box<Path>,
pub editable: bool,
pub r#virtual: bool,
}
impl ParsedDirectoryUrl {
/// Construct a [`ParsedDirectoryUrl`] from a path requirement source.
pub fn from_source(install_path: PathBuf, editable: bool, r#virtual: bool, url: Url) -> Self {
pub fn from_source(install_path: Box<Path>, editable: bool, r#virtual: bool, url: Url) -> Self {
Self {
url,
install_path,
@ -239,12 +243,12 @@ impl ParsedDirectoryUrl {
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Hash, Ord)]
pub struct ParsedGitUrl {
pub url: GitUrl,
pub subdirectory: Option<PathBuf>,
pub subdirectory: Option<Box<Path>>,
}
impl ParsedGitUrl {
/// Construct a [`ParsedGitUrl`] from a Git requirement source.
pub fn from_source(url: GitUrl, subdirectory: Option<PathBuf>) -> Self {
pub fn from_source(url: GitUrl, subdirectory: Option<Box<Path>>) -> Self {
Self { url, subdirectory }
}
}
@ -257,7 +261,7 @@ impl TryFrom<Url> for ParsedGitUrl {
/// When the URL includes a prefix, it's presumed to come from a PEP 508 requirement; when it's
/// excluded, it's presumed to come from `tool.uv.sources`.
fn try_from(url_in: Url) -> Result<Self, Self::Error> {
let subdirectory = get_subdirectory(&url_in);
let subdirectory = get_subdirectory(&url_in).map(PathBuf::into_boxed_path);
let url = url_in
.as_str()
@ -278,13 +282,13 @@ impl TryFrom<Url> for ParsedGitUrl {
#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
pub struct ParsedArchiveUrl {
pub url: Url,
pub subdirectory: Option<PathBuf>,
pub subdirectory: Option<Box<Path>>,
pub ext: DistExtension,
}
impl ParsedArchiveUrl {
/// Construct a [`ParsedArchiveUrl`] from a URL requirement source.
pub fn from_source(location: Url, subdirectory: Option<PathBuf>, ext: DistExtension) -> Self {
pub fn from_source(location: Url, subdirectory: Option<Box<Path>>, ext: DistExtension) -> Self {
Self {
url: location,
subdirectory,
@ -298,7 +302,7 @@ impl TryFrom<Url> for ParsedArchiveUrl {
fn try_from(mut url: Url) -> Result<Self, Self::Error> {
// Extract the `#subdirectory` fragment, if present.
let subdirectory = get_subdirectory(&url);
let subdirectory = get_subdirectory(&url).map(PathBuf::into_boxed_path);
url.set_fragment(None);
// Infer the extension from the path.
@ -377,7 +381,7 @@ impl TryFrom<Url> for ParsedUrl {
if is_dir {
Ok(Self::Directory(ParsedDirectoryUrl {
url,
install_path: path.clone(),
install_path: path.into_boxed_path(),
editable: false,
r#virtual: false,
}))
@ -386,7 +390,7 @@ impl TryFrom<Url> for ParsedUrl {
url,
ext: DistExtension::from_path(&path)
.map_err(|err| ParsedUrlError::MissingExtensionPath(path.clone(), err))?,
install_path: path.clone(),
install_path: path.into_boxed_path(),
}))
}
} else {

View file

@ -680,7 +680,7 @@ impl Lock {
let (Source::Editable(path) | Source::Virtual(path)) = &package.id.source else {
return false;
};
path == Path::new("")
path.as_ref() == Path::new("")
})
}
@ -1356,7 +1356,8 @@ impl Lock {
let path = url.to_file_path().ok()?;
let path = relative_to(&path, root)
.or_else(|_| std::path::absolute(path))
.ok()?;
.ok()?
.into_boxed_path();
Some(path)
}
})
@ -1698,7 +1699,7 @@ pub enum SatisfiesResult<'lock> {
/// The lockfile referenced a remote index that was not provided
MissingRemoteIndex(&'lock PackageName, &'lock Version, &'lock UrlString),
/// The lockfile referenced a local index that was not provided
MissingLocalIndex(&'lock PackageName, &'lock Version, &'lock PathBuf),
MissingLocalIndex(&'lock PackageName, &'lock Version, &'lock Path),
/// A package in the lockfile contains different `requires-dist` metadata than expected.
MismatchedPackageRequirements(
&'lock PackageName,
@ -2151,7 +2152,7 @@ impl Package {
let path_dist = PathBuiltDist {
filename,
url: verbatim_url(&install_path, &self.id)?,
install_path: absolute_path(workspace_root, path)?,
install_path: absolute_path(workspace_root, path)?.into_boxed_path(),
};
let built_dist = BuiltDist::Path(path_dist);
Ok(Dist::Built(built_dist))
@ -2330,7 +2331,7 @@ impl Package {
name: self.id.name.clone(),
version: self.id.version.clone(),
url: verbatim_url(&install_path, &self.id)?,
install_path,
install_path: install_path.into_boxed_path(),
ext,
};
uv_distribution_types::SourceDist::Path(path_dist)
@ -2340,7 +2341,7 @@ impl Package {
let dir_dist = DirectorySourceDist {
name: self.id.name.clone(),
url: verbatim_url(&install_path, &self.id)?,
install_path,
install_path: install_path.into_boxed_path(),
editable: false,
r#virtual: false,
};
@ -2351,7 +2352,7 @@ impl Package {
let dir_dist = DirectorySourceDist {
name: self.id.name.clone(),
url: verbatim_url(&install_path, &self.id)?,
install_path,
install_path: install_path.into_boxed_path(),
editable: true,
r#virtual: false,
};
@ -2362,7 +2363,7 @@ impl Package {
let dir_dist = DirectorySourceDist {
name: self.id.name.clone(),
url: verbatim_url(&install_path, &self.id)?,
install_path,
install_path: install_path.into_boxed_path(),
editable: false,
r#virtual: true,
};
@ -2402,16 +2403,15 @@ impl Package {
return Ok(None);
};
let location = url.to_url().map_err(LockErrorKind::InvalidUrl)?;
let subdirectory = direct.subdirectory.as_ref().map(PathBuf::from);
let url = Url::from(ParsedArchiveUrl {
url: location.clone(),
subdirectory: subdirectory.clone(),
subdirectory: direct.subdirectory.clone(),
ext: DistExtension::Source(ext),
});
let direct_dist = DirectUrlSourceDist {
name: self.id.name.clone(),
location: Box::new(location),
subdirectory: subdirectory.clone(),
subdirectory: direct.subdirectory.clone(),
ext,
url: VerbatimUrl::from_url(url),
};
@ -3060,13 +3060,13 @@ enum Source {
/// A direct HTTP(S) URL.
Direct(UrlString, DirectSource),
/// A path to a local source or built archive.
Path(PathBuf),
Path(Box<Path>),
/// A path to a local directory.
Directory(PathBuf),
Directory(Box<Path>),
/// A path to a local directory that should be installed as editable.
Editable(PathBuf),
Editable(Box<Path>),
/// A path to a local directory that should not be built or installed.
Virtual(PathBuf),
Virtual(Box<Path>),
}
impl Source {
@ -3152,14 +3152,14 @@ impl Source {
let path = relative_to(&path_dist.install_path, root)
.or_else(|_| std::path::absolute(&path_dist.install_path))
.map_err(LockErrorKind::DistributionRelativePath)?;
Ok(Source::Path(path))
Ok(Source::Path(path.into_boxed_path()))
}
fn from_path_source_dist(path_dist: &PathSourceDist, root: &Path) -> Result<Source, LockError> {
let path = relative_to(&path_dist.install_path, root)
.or_else(|_| std::path::absolute(&path_dist.install_path))
.map_err(LockErrorKind::DistributionRelativePath)?;
Ok(Source::Path(path))
Ok(Source::Path(path.into_boxed_path()))
}
fn from_directory_source_dist(
@ -3170,11 +3170,11 @@ impl Source {
.or_else(|_| std::path::absolute(&directory_dist.install_path))
.map_err(LockErrorKind::DistributionRelativePath)?;
if directory_dist.editable {
Ok(Source::Editable(path))
Ok(Source::Editable(path.into_boxed_path()))
} else if directory_dist.r#virtual {
Ok(Source::Virtual(path))
Ok(Source::Virtual(path.into_boxed_path()))
} else {
Ok(Source::Directory(path))
Ok(Source::Directory(path.into_boxed_path()))
}
}
@ -3191,7 +3191,7 @@ impl Source {
let path = relative_to(&path, root)
.or_else(|_| std::path::absolute(&path))
.map_err(LockErrorKind::IndexRelativePath)?;
let source = RegistrySource::Path(path);
let source = RegistrySource::Path(path.into_boxed_path());
Ok(Source::Registry(source))
}
}
@ -3418,7 +3418,7 @@ impl TryFrom<SourceWire> for Source {
Direct { url, subdirectory } => Ok(Source::Direct(
url,
DirectSource {
subdirectory: subdirectory.map(PathBuf::from),
subdirectory: subdirectory.map(Box::<std::path::Path>::from),
},
)),
Path { path } => Ok(Source::Path(path.into())),
@ -3435,7 +3435,7 @@ enum RegistrySource {
/// Ex) `https://pypi.org/simple`
Url(UrlString),
/// Ex) `../path/to/local/index`
Path(PathBuf),
Path(Box<Path>),
}
impl Display for RegistrySource {
@ -3506,7 +3506,7 @@ impl From<RegistrySourceWire> for RegistrySource {
#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, serde::Deserialize)]
struct DirectSource {
subdirectory: Option<PathBuf>,
subdirectory: Option<Box<Path>>,
}
/// NOTE: Care should be taken when adding variants to this enum. Namely, new
@ -3516,7 +3516,7 @@ struct DirectSource {
#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
struct GitSource {
precise: GitOid,
subdirectory: Option<PathBuf>,
subdirectory: Option<Box<Path>>,
kind: GitSourceKind,
}
@ -3585,7 +3585,7 @@ enum SourceDist {
metadata: SourceDistMetadata,
},
Path {
path: PathBuf,
path: Box<Path>,
#[serde(flatten)]
metadata: SourceDistMetadata,
},
@ -3733,7 +3733,8 @@ impl SourceDist {
.map_err(|()| LockErrorKind::UrlToPath)?;
let path = relative_to(&reg_dist_path, index_path)
.or_else(|_| std::path::absolute(&reg_dist_path))
.map_err(LockErrorKind::DistributionRelativePath)?;
.map_err(LockErrorKind::DistributionRelativePath)?
.into_boxed_path();
let hash = reg_dist.file.hashes.iter().max().cloned().map(Hash::from);
let size = reg_dist.file.size;
Ok(Some(SourceDist::Path {
@ -4036,7 +4037,8 @@ impl Wheel {
.map_err(|()| LockErrorKind::UrlToPath)?;
let path = relative_to(&wheel_path, index_path)
.or_else(|_| std::path::absolute(&wheel_path))
.map_err(LockErrorKind::DistributionRelativePath)?;
.map_err(LockErrorKind::DistributionRelativePath)?
.into_boxed_path();
Ok(Wheel {
url: WheelWireSource::Path { path },
hash: None,
@ -4174,7 +4176,7 @@ enum WheelWireSource {
/// Used for wheels that come from local registries (like `--find-links`).
Path {
/// The path to the wheel, relative to the index.
path: PathBuf,
path: Box<Path>,
},
/// Used for path wheels.
///
@ -4520,7 +4522,8 @@ fn normalize_requirement(
ext,
url: _,
} => {
let install_path = uv_fs::normalize_path_buf(root.join(&install_path));
let install_path =
uv_fs::normalize_path_buf(root.join(&install_path)).into_boxed_path();
let url = VerbatimUrl::from_normalized_path(&install_path)
.map_err(LockErrorKind::RequirementVerbatimUrl)?;
@ -4543,7 +4546,8 @@ fn normalize_requirement(
r#virtual,
url: _,
} => {
let install_path = uv_fs::normalize_path_buf(root.join(&install_path));
let install_path =
uv_fs::normalize_path_buf(root.join(&install_path)).into_boxed_path();
let url = VerbatimUrl::from_normalized_path(&install_path)
.map_err(LockErrorKind::RequirementVerbatimUrl)?;

View file

@ -524,16 +524,15 @@ impl std::fmt::Display for RequirementsTxtExport<'_> {
// Reconstruct the PEP 508-compatible URL from the `GitSource`.
let url = Url::from(ParsedGitUrl {
url: git_url.clone(),
subdirectory: git.subdirectory.as_ref().map(PathBuf::from),
subdirectory: git.subdirectory.clone(),
});
write!(f, "{} @ {}", package.id.name, url)?;
}
Source::Direct(url, direct) => {
let subdirectory = direct.subdirectory.as_ref().map(PathBuf::from);
let url = Url::from(ParsedArchiveUrl {
url: url.to_url().map_err(|_| std::fmt::Error)?,
subdirectory: subdirectory.clone(),
subdirectory: direct.subdirectory.clone(),
ext: DistExtension::Source(SourceDistExtension::TarGz),
});
write!(f, "{} @ {}", package.id.name, url)?;

View file

@ -1452,7 +1452,8 @@ impl Source {
path: PortablePathBuf::from(
relative_to(&install_path, root)
.or_else(|_| std::path::absolute(&install_path))
.map_err(SourceError::Absolute)?,
.map_err(SourceError::Absolute)?
.into_boxed_path(),
),
marker: MarkerTree::TRUE,
extra: None,

View file

@ -311,14 +311,14 @@ impl Workspace {
marker: MarkerTree::TRUE,
source: if member.pyproject_toml.is_package() {
RequirementSource::Directory {
install_path: member.root.clone(),
install_path: member.root.clone().into_boxed_path(),
editable: true,
r#virtual: false,
url,
}
} else {
RequirementSource::Directory {
install_path: member.root.clone(),
install_path: member.root.clone().into_boxed_path(),
editable: false,
r#virtual: true,
url,
@ -367,14 +367,14 @@ impl Workspace {
marker: MarkerTree::TRUE,
source: if member.pyproject_toml.is_package() {
RequirementSource::Directory {
install_path: member.root.clone(),
install_path: member.root.clone().into_boxed_path(),
editable: true,
r#virtual: false,
url,
}
} else {
RequirementSource::Directory {
install_path: member.root.clone(),
install_path: member.root.clone().into_boxed_path(),
editable: false,
r#virtual: true,
url,