mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 19:08:04 +00:00
Avoid deserialization error for paths above the root (#10789)
## Summary Closes https://github.com/astral-sh/uv/issues/10777 ## Test Plan Copied over this lockfile: ```toml version = 1 requires-python = ">=3.12" resolution-markers = [ "sys_platform == 'win32'", "sys_platform != 'win32'", ] [[package]] name = "pyasn1" version = "0.6.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "01f1a64245/pyasn1-0.6.1.tar.gz
", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322 } wheels = [ { url = "d6a797abb1/pyasn1-0.6.1-py3-none-any.whl
", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135 }, ] [[package]] name = "pyasn1-modules" version = "0.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyasn1" }, ] sdist = { url = "6afbf0d507/pyasn1_modules-0.4.1.tar.gz
", hash = "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c", size = 310028 } wheels = [ { url = "bc88a67119/pyasn1_modules-0.4.1-py3-none-any.whl
", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd", size = 181537 }, ] [[package]] name = "python-ldap" version = "3.4.4" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "sys_platform != 'win32'", ] dependencies = [ { name = "pyasn1", marker = "sys_platform != 'win32'" }, { name = "pyasn1-modules", marker = "sys_platform != 'win32'" }, ] sdist = { url = "1eeb4025dc/python-ldap-3.4.4.tar.gz
", hash = "sha256:7edb0accec4e037797705f3a05cbf36a9fde50d08c8f67f2aef99a2628fab828", size = 377889 } [[package]] name = "python-ldap" version = "3.4.4" source = { path = "../../../uti/Python/python_ldap-3.4.4-cp312-cp312-win_amd64.whl" } resolution-markers = [ "sys_platform == 'win32'", ] dependencies = [ { name = "pyasn1", marker = "sys_platform == 'win32'" }, { name = "pyasn1-modules", marker = "sys_platform == 'win32'" }, ] wheels = [ { filename = "python_ldap-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:94d2ca2b3ced81c9d89aa5c79d4965d03053e1ffdcfae73e9fac85d25b692e85" }, ] [package.metadata] requires-dist = [ { name = "pyasn1", specifier = ">=0.3.7" }, { name = "pyasn1-modules", specifier = ">=0.1.5" }, ] [[package]] name = "uv-test" version = "1.0" source = { virtual = "." } dependencies = [ { name = "python-ldap", version = "3.4.4", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'win32'" }, { name = "python-ldap", version = "3.4.4", source = { path = "../../../uti/Python/python_ldap-3.4.4-cp312-cp312-win_amd64.whl" }, marker = "sys_platform == 'win32'" }, ] [package.metadata] requires-dist = [ { name = "python-ldap", marker = "sys_platform != 'win32'" }, { name = "python-ldap", marker = "sys_platform == 'win32'", path = "../../../../../../../../../../../../uti/Python/python_ldap-3.4.4-cp312-cp312-win_amd64.whl" }, ] ``` Verified that `cargo run sync --frozen` installs `python-ldap` from PyPI, without erroring.
This commit is contained in:
parent
6b4c8a906c
commit
07e1e85c5d
3 changed files with 49 additions and 12 deletions
|
@ -112,6 +112,34 @@ impl VerbatimUrl {
|
|||
Ok(Self { url, given: None })
|
||||
}
|
||||
|
||||
/// Parse a URL from a normalized path.
|
||||
///
|
||||
/// Like [`VerbatimUrl::from_absolute_path`], but skips the normalization step.
|
||||
pub fn from_normalized_path(path: impl AsRef<Path>) -> Result<Self, VerbatimUrlError> {
|
||||
let path = path.as_ref();
|
||||
|
||||
// Error if the path is relative.
|
||||
let path = if path.is_absolute() {
|
||||
path
|
||||
} else {
|
||||
return Err(VerbatimUrlError::WorkingDirectory(path.to_path_buf()));
|
||||
};
|
||||
|
||||
// Extract the fragment, if it exists.
|
||||
let (path, fragment) = split_fragment(path);
|
||||
|
||||
// Convert to a URL.
|
||||
let mut url = Url::from_file_path(path.clone())
|
||||
.unwrap_or_else(|()| panic!("path is absolute: {}", path.display()));
|
||||
|
||||
// Set the fragment, if it exists.
|
||||
if let Some(fragment) = fragment {
|
||||
url.set_fragment(Some(fragment));
|
||||
}
|
||||
|
||||
Ok(Self { url, given: None })
|
||||
}
|
||||
|
||||
/// Set the verbatim representation of the URL.
|
||||
#[must_use]
|
||||
pub fn with_given(self, given: impl AsRef<str>) -> Self {
|
||||
|
|
|
@ -870,10 +870,12 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
|
|||
}
|
||||
// TODO(charlie): The use of `CWD` here is incorrect. These should be resolved relative
|
||||
// to the workspace root, but we don't have access to it here. When comparing these
|
||||
// sources in the lockfile, we replace the URL anyway.
|
||||
// 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 url = VerbatimUrl::from_path(&path, &*CWD)?;
|
||||
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))?,
|
||||
|
@ -883,7 +885,9 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
|
|||
}
|
||||
RequirementSourceWire::Directory { directory } => {
|
||||
let directory = PathBuf::from(directory);
|
||||
let url = VerbatimUrl::from_path(&directory, &*CWD)?;
|
||||
let url = VerbatimUrl::from_normalized_path(uv_fs::normalize_path_buf(
|
||||
CWD.join(&directory),
|
||||
))?;
|
||||
Ok(Self::Directory {
|
||||
install_path: directory,
|
||||
editable: false,
|
||||
|
@ -893,7 +897,9 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
|
|||
}
|
||||
RequirementSourceWire::Editable { editable } => {
|
||||
let editable = PathBuf::from(editable);
|
||||
let url = VerbatimUrl::from_path(&editable, &*CWD)?;
|
||||
let url = VerbatimUrl::from_normalized_path(uv_fs::normalize_path_buf(
|
||||
CWD.join(&editable),
|
||||
))?;
|
||||
Ok(Self::Directory {
|
||||
install_path: editable,
|
||||
editable: true,
|
||||
|
@ -903,7 +909,9 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
|
|||
}
|
||||
RequirementSourceWire::Virtual { r#virtual } => {
|
||||
let r#virtual = PathBuf::from(r#virtual);
|
||||
let url = VerbatimUrl::from_path(&r#virtual, &*CWD)?;
|
||||
let url = VerbatimUrl::from_normalized_path(uv_fs::normalize_path_buf(
|
||||
CWD.join(&r#virtual),
|
||||
))?;
|
||||
Ok(Self::Directory {
|
||||
install_path: r#virtual,
|
||||
editable: false,
|
||||
|
|
|
@ -2489,12 +2489,13 @@ impl Package {
|
|||
}
|
||||
}
|
||||
|
||||
/// Attempts to construct a `VerbatimUrl` from the given `Path`.
|
||||
/// Attempts to construct a `VerbatimUrl` from the given normalized `Path`.
|
||||
fn verbatim_url(path: &Path, id: &PackageId) -> Result<VerbatimUrl, LockError> {
|
||||
let url = VerbatimUrl::from_absolute_path(path).map_err(|err| LockErrorKind::VerbatimUrl {
|
||||
id: id.clone(),
|
||||
err,
|
||||
})?;
|
||||
let url =
|
||||
VerbatimUrl::from_normalized_path(path).map_err(|err| LockErrorKind::VerbatimUrl {
|
||||
id: id.clone(),
|
||||
err,
|
||||
})?;
|
||||
Ok(url)
|
||||
}
|
||||
|
||||
|
@ -4146,7 +4147,7 @@ fn normalize_requirement(requirement: Requirement, root: &Path) -> Result<Requir
|
|||
url: _,
|
||||
} => {
|
||||
let install_path = uv_fs::normalize_path_buf(root.join(&install_path));
|
||||
let url = VerbatimUrl::from_absolute_path(&install_path)
|
||||
let url = VerbatimUrl::from_normalized_path(&install_path)
|
||||
.map_err(LockErrorKind::RequirementVerbatimUrl)?;
|
||||
|
||||
Ok(Requirement {
|
||||
|
@ -4169,7 +4170,7 @@ fn normalize_requirement(requirement: Requirement, root: &Path) -> Result<Requir
|
|||
url: _,
|
||||
} => {
|
||||
let install_path = uv_fs::normalize_path_buf(root.join(&install_path));
|
||||
let url = VerbatimUrl::from_absolute_path(&install_path)
|
||||
let url = VerbatimUrl::from_normalized_path(&install_path)
|
||||
.map_err(LockErrorKind::RequirementVerbatimUrl)?;
|
||||
|
||||
Ok(Requirement {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue