Strip query parameters when parsing source URL (#14224)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / lint (push) Waiting to run
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / cargo shear (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | macos (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / build binary | windows aarch64 (push) Blocked by required conditions
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / build binary | linux libc (push) Blocked by required conditions
CI / build binary | linux musl (push) Blocked by required conditions
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / build binary | windows x86_64 (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / ecosystem test | pydantic/pydantic-core (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / smoke test | linux (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
CI / smoke test | macos (push) Blocked by required conditions
CI / smoke test | windows x86_64 (push) Blocked by required conditions
CI / smoke test | windows aarch64 (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | deadsnakes python3.9 on ubuntu (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | pyodide on ubuntu (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / integration test | free-threaded python on github actions (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / integration test | registries (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / integration test | uv_build (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / check system | python on debian (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / check system | graalpy on ubuntu (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python on macos x86-64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86-64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows x86-64 (push) Blocked by required conditions
CI / check system | x86-64 python3.13 on windows aarch64 (push) Blocked by required conditions
CI / check system | windows registry (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.8 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.11 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.11 on windows x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on windows x86-64 (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows x86-64 (push) Blocked by required conditions
CI / benchmarks | walltime aarch64 linux (push) Blocked by required conditions
CI / benchmarks | instrumented (push) Blocked by required conditions

## Summary

Closes https://github.com/astral-sh/uv/issues/14217.
This commit is contained in:
Charlie Marsh 2025-06-23 14:52:07 -04:00 committed by GitHub
parent d9351d52fc
commit aa2448ef83
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 63 additions and 6 deletions

View file

@ -2371,7 +2371,13 @@ impl Package {
let sdist = match &self.id.source {
Source::Path(path) => {
// A direct path source can also be a wheel, so validate the extension.
let DistExtension::Source(ext) = DistExtension::from_path(path)? else {
let DistExtension::Source(ext) = DistExtension::from_path(path).map_err(|err| {
LockErrorKind::MissingExtension {
id: self.id.clone(),
err,
}
})?
else {
return Ok(None);
};
let install_path = absolute_path(workspace_root, path)?;
@ -2444,7 +2450,14 @@ impl Package {
}
Source::Direct(url, direct) => {
// A direct URL source can also be a wheel, so validate the extension.
let DistExtension::Source(ext) = DistExtension::from_path(url.as_ref())? else {
let DistExtension::Source(ext) =
DistExtension::from_path(url.base_str()).map_err(|err| {
LockErrorKind::MissingExtension {
id: self.id.clone(),
err,
}
})?
else {
return Ok(None);
};
let location = url.to_url().map_err(LockErrorKind::InvalidUrl)?;
@ -2483,7 +2496,12 @@ impl Package {
.ok_or_else(|| LockErrorKind::MissingFilename {
id: self.id.clone(),
})?;
let ext = SourceDistExtension::from_path(filename.as_ref())?;
let ext = SourceDistExtension::from_path(filename.as_ref()).map_err(|err| {
LockErrorKind::MissingExtension {
id: self.id.clone(),
err,
}
})?;
let file = Box::new(uv_distribution_types::File {
dist_info_metadata: false,
filename: SmallString::from(filename),
@ -2535,7 +2553,12 @@ impl Package {
.ok_or_else(|| LockErrorKind::MissingFilename {
id: self.id.clone(),
})?;
let ext = SourceDistExtension::from_path(filename.as_ref())?;
let ext = SourceDistExtension::from_path(filename.as_ref()).map_err(|err| {
LockErrorKind::MissingExtension {
id: self.id.clone(),
err,
}
})?;
let file = Box::new(uv_distribution_types::File {
dist_info_metadata: false,
filename: SmallString::from(filename),
@ -5222,8 +5245,13 @@ enum LockErrorKind {
),
/// An error that occurs when the extension can't be determined
/// for a given wheel or source distribution.
#[error("Failed to parse file extension; expected one of: {0}")]
MissingExtension(#[from] ExtensionError),
#[error("Failed to parse file extension for `{id}`; expected one of: {err}", id = id.cyan())]
MissingExtension {
/// The filename that was expected to have an extension.
id: PackageId,
/// The list of valid extensions that were expected.
err: ExtensionError,
},
/// Failed to parse a Git source URL.
#[error("Failed to parse Git URL")]
InvalidGitSourceUrl(

View file

@ -9943,3 +9943,32 @@ fn sync_required_environment_hint() -> Result<()> {
Ok(())
}
#[test]
fn sync_url_with_query_parameters() -> Result<()> {
let context = TestContext::new("3.13").with_exclude_newer("2025-03-24T19:00:00Z");
let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(r#"
[project]
name = "example"
version = "0.1.0"
requires-python = ">=3.13.2"
dependencies = ["source-distribution @ https://files.pythonhosted.org/packages/1f/e5/5b016c945d745f8b108e759d428341488a6aee8f51f07c6c4e33498bb91f/source_distribution-0.0.3.tar.gz?foo=bar"]
"#
)?;
uv_snapshot!(context.filters(), context.sync(), @r"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 2 packages in [TIME]
Prepared 1 package in [TIME]
Installed 1 package in [TIME]
+ source-distribution==0.0.3 (from https://files.pythonhosted.org/packages/1f/e5/5b016c945d745f8b108e759d428341488a6aee8f51f07c6c4e33498bb91f/source_distribution-0.0.3.tar.gz?foo=bar)
");
Ok(())
}