mirror of https://github.com/astral-sh/uv
Migrate from `urlencoding` to `percent-encoding` (#11144)
## Summary This lets us drop a dependency entirely. `percent-encoding` is used by `url` and so is already in the graph, whereas `urlencoding` isn't used by anything else.
This commit is contained in:
parent
027db656aa
commit
8adf4a8977
|
|
@ -4440,12 +4440,6 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "urlencoding"
|
|
||||||
version = "2.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "usvg"
|
name = "usvg"
|
||||||
version = "0.29.0"
|
version = "0.29.0"
|
||||||
|
|
@ -4619,6 +4613,7 @@ dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"http",
|
"http",
|
||||||
"insta",
|
"insta",
|
||||||
|
"percent-encoding",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"reqwest-middleware",
|
"reqwest-middleware",
|
||||||
"rust-netrc",
|
"rust-netrc",
|
||||||
|
|
@ -4628,7 +4623,6 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
"urlencoding",
|
|
||||||
"uv-once-map",
|
"uv-once-map",
|
||||||
"uv-static",
|
"uv-static",
|
||||||
"wiremock",
|
"wiremock",
|
||||||
|
|
@ -4771,9 +4765,9 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
"percent-encoding",
|
||||||
"seahash",
|
"seahash",
|
||||||
"url",
|
"url",
|
||||||
"urlencoding",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -4822,6 +4816,7 @@ dependencies = [
|
||||||
"insta",
|
"insta",
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
"jiff",
|
"jiff",
|
||||||
|
"percent-encoding",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"reqwest-middleware",
|
"reqwest-middleware",
|
||||||
"reqwest-retry",
|
"reqwest-retry",
|
||||||
|
|
@ -4836,7 +4831,6 @@ dependencies = [
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
"urlencoding",
|
|
||||||
"uv-auth",
|
"uv-auth",
|
||||||
"uv-cache",
|
"uv-cache",
|
||||||
"uv-cache-key",
|
"uv-cache-key",
|
||||||
|
|
@ -5048,6 +5042,7 @@ dependencies = [
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
"jiff",
|
"jiff",
|
||||||
"owo-colors",
|
"owo-colors",
|
||||||
|
"percent-encoding",
|
||||||
"petgraph",
|
"petgraph",
|
||||||
"rkyv",
|
"rkyv",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
|
|
@ -5057,7 +5052,6 @@ dependencies = [
|
||||||
"thiserror 2.0.11",
|
"thiserror 2.0.11",
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
"urlencoding",
|
|
||||||
"uv-auth",
|
"uv-auth",
|
||||||
"uv-cache-info",
|
"uv-cache-info",
|
||||||
"uv-cache-key",
|
"uv-cache-key",
|
||||||
|
|
@ -5110,13 +5104,13 @@ dependencies = [
|
||||||
"fs2",
|
"fs2",
|
||||||
"junction",
|
"junction",
|
||||||
"path-slash",
|
"path-slash",
|
||||||
|
"percent-encoding",
|
||||||
"rustix",
|
"rustix",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"urlencoding",
|
|
||||||
"winsafe 0.0.22",
|
"winsafe 0.0.22",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ nix = { version = "0.29.0" }
|
||||||
owo-colors = { version = "4.1.0" }
|
owo-colors = { version = "4.1.0" }
|
||||||
path-slash = { version = "0.2.1" }
|
path-slash = { version = "0.2.1" }
|
||||||
pathdiff = { version = "0.2.1" }
|
pathdiff = { version = "0.2.1" }
|
||||||
|
percent-encoding = { version = "2.3.1" }
|
||||||
petgraph = { version = "0.7.1" }
|
petgraph = { version = "0.7.1" }
|
||||||
platform-info = { version = "2.0.3" }
|
platform-info = { version = "2.0.3" }
|
||||||
proc-macro2 = { version = "1.0.86" }
|
proc-macro2 = { version = "1.0.86" }
|
||||||
|
|
@ -176,7 +177,6 @@ tracing-tree = { version = "0.4.0" }
|
||||||
unicode-width = { version = "0.1.13" }
|
unicode-width = { version = "0.1.13" }
|
||||||
unscanny = { version = "0.1.0" }
|
unscanny = { version = "0.1.0" }
|
||||||
url = { version = "2.5.2", features = ["serde"] }
|
url = { version = "2.5.2", features = ["serde"] }
|
||||||
urlencoding = { version = "2.1.3" }
|
|
||||||
version-ranges = { git = "https://github.com/astral-sh/pubgrub", rev = "648aa343486e5529953153781fc86025c73c4a61" }
|
version-ranges = { git = "https://github.com/astral-sh/pubgrub", rev = "648aa343486e5529953153781fc86025c73c4a61" }
|
||||||
walkdir = { version = "2.5.0" }
|
walkdir = { version = "2.5.0" }
|
||||||
which = { version = "7.0.0", features = ["regex"] }
|
which = { version = "7.0.0", features = ["regex"] }
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,14 @@ workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uv-once-map = { workspace = true }
|
uv-once-map = { workspace = true }
|
||||||
|
uv-static = { workspace = true }
|
||||||
|
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
async-trait = { workspace = true }
|
async-trait = { workspace = true }
|
||||||
base64 = { workspace = true }
|
base64 = { workspace = true }
|
||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
http = { workspace = true }
|
http = { workspace = true }
|
||||||
|
percent-encoding = { workspace = true }
|
||||||
reqwest = { workspace = true }
|
reqwest = { workspace = true }
|
||||||
reqwest-middleware = { workspace = true }
|
reqwest-middleware = { workspace = true }
|
||||||
rust-netrc = { workspace = true }
|
rust-netrc = { workspace = true }
|
||||||
|
|
@ -24,13 +26,10 @@ rustc-hash = { workspace = true }
|
||||||
tokio = { workspace = true }
|
tokio = { workspace = true }
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
url = { workspace = true }
|
url = { workspace = true }
|
||||||
urlencoding = { workspace = true }
|
|
||||||
|
|
||||||
uv-static = { workspace = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
insta = { version = "1.40.0" }
|
||||||
tempfile = { workspace = true }
|
tempfile = { workspace = true }
|
||||||
|
test-log = { version = "0.2.16", features = ["trace"], default-features = false }
|
||||||
tokio = { workspace = true }
|
tokio = { workspace = true }
|
||||||
wiremock = { workspace = true }
|
wiremock = { workspace = true }
|
||||||
insta = { version = "1.40.0" }
|
|
||||||
test-log = { version = "0.2.16", features = ["trace"], default-features = false }
|
|
||||||
|
|
|
||||||
|
|
@ -127,14 +127,16 @@ impl Credentials {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(
|
Some(
|
||||||
urlencoding::decode(url.username())
|
percent_encoding::percent_decode_str(url.username())
|
||||||
|
.decode_utf8()
|
||||||
.expect("An encoded username should always decode")
|
.expect("An encoded username should always decode")
|
||||||
.into_owned(),
|
.into_owned(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
password: url.password().map(|password| {
|
password: url.password().map(|password| {
|
||||||
urlencoding::decode(password)
|
percent_encoding::percent_decode_str(password)
|
||||||
|
.decode_utf8()
|
||||||
.expect("An encoded password should always decode")
|
.expect("An encoded password should always decode")
|
||||||
.into_owned()
|
.into_owned()
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,6 @@ workspace = true
|
||||||
[dependencies]
|
[dependencies]
|
||||||
hex = { workspace = true }
|
hex = { workspace = true }
|
||||||
memchr = { workspace = true }
|
memchr = { workspace = true }
|
||||||
|
percent-encoding = { workspace = true }
|
||||||
seahash = { workspace = true }
|
seahash = { workspace = true }
|
||||||
url = { workspace = true }
|
url = { workspace = true }
|
||||||
urlencoding = { workspace = true }
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,8 @@ impl CanonicalUrl {
|
||||||
.path_segments()
|
.path_segments()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|segment| {
|
.map(|segment| {
|
||||||
urlencoding::decode(segment)
|
percent_encoding::percent_decode_str(segment)
|
||||||
|
.decode_utf8()
|
||||||
.unwrap_or(Cow::Borrowed(segment))
|
.unwrap_or(Cow::Borrowed(segment))
|
||||||
.into_owned()
|
.into_owned()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ html-escape = { workspace = true }
|
||||||
http = { workspace = true }
|
http = { workspace = true }
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
jiff = { workspace = true }
|
jiff = { workspace = true }
|
||||||
|
percent-encoding = { workspace = true }
|
||||||
reqwest = { workspace = true }
|
reqwest = { workspace = true }
|
||||||
reqwest-middleware = { workspace = true }
|
reqwest-middleware = { workspace = true }
|
||||||
reqwest-retry = { workspace = true }
|
reqwest-retry = { workspace = true }
|
||||||
|
|
@ -52,7 +53,6 @@ tokio = { workspace = true }
|
||||||
tokio-util = { workspace = true }
|
tokio-util = { workspace = true }
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
url = { workspace = true }
|
url = { workspace = true }
|
||||||
urlencoding = { workspace = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ impl SimpleHtml {
|
||||||
// Extract the hash, which should be in the fragment.
|
// Extract the hash, which should be in the fragment.
|
||||||
let decoded = html_escape::decode_html_entities(href);
|
let decoded = html_escape::decode_html_entities(href);
|
||||||
let (path, hashes) = if let Some((path, fragment)) = decoded.split_once('#') {
|
let (path, hashes) = if let Some((path, fragment)) = decoded.split_once('#') {
|
||||||
let fragment = urlencoding::decode(fragment)?;
|
let fragment = percent_encoding::percent_decode_str(fragment).decode_utf8()?;
|
||||||
(
|
(
|
||||||
path,
|
path,
|
||||||
if fragment.trim().is_empty() {
|
if fragment.trim().is_empty() {
|
||||||
|
|
@ -131,7 +131,8 @@ impl SimpleHtml {
|
||||||
let filename = filename.split('?').next().unwrap_or(filename);
|
let filename = filename.split('?').next().unwrap_or(filename);
|
||||||
|
|
||||||
// Unquote the filename.
|
// Unquote the filename.
|
||||||
let filename = urlencoding::decode(filename)
|
let filename = percent_encoding::percent_decode_str(filename)
|
||||||
|
.decode_utf8()
|
||||||
.map_err(|_| Error::UnsupportedFilename(filename.to_string()))?;
|
.map_err(|_| Error::UnsupportedFilename(filename.to_string()))?;
|
||||||
|
|
||||||
// Extract the `requires-python` value, which should be set on the
|
// Extract the `requires-python` value, which should be set on the
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ fs-err = { workspace = true }
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
jiff = { workspace = true }
|
jiff = { workspace = true }
|
||||||
owo-colors = { workspace = true }
|
owo-colors = { workspace = true }
|
||||||
|
percent-encoding = { workspace = true }
|
||||||
petgraph = { workspace = true }
|
petgraph = { workspace = true }
|
||||||
rkyv = { workspace = true }
|
rkyv = { workspace = true }
|
||||||
rustc-hash = { workspace = true }
|
rustc-hash = { workspace = true }
|
||||||
|
|
@ -43,5 +44,4 @@ serde_json = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
url = { workspace = true }
|
url = { workspace = true }
|
||||||
urlencoding = { workspace = true }
|
|
||||||
version-ranges = { workspace = true }
|
version-ranges = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ pub enum Error {
|
||||||
Io(#[from] std::io::Error),
|
Io(#[from] std::io::Error),
|
||||||
|
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Utf8(#[from] std::string::FromUtf8Error),
|
Utf8(#[from] std::str::Utf8Error),
|
||||||
|
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
WheelFilename(#[from] uv_distribution_filename::WheelFilenameError),
|
WheelFilename(#[from] uv_distribution_filename::WheelFilenameError),
|
||||||
|
|
|
||||||
|
|
@ -923,7 +923,7 @@ impl RemoteSource for Url {
|
||||||
let last = path_segments.last().expect("path segments is non-empty");
|
let last = path_segments.last().expect("path segments is non-empty");
|
||||||
|
|
||||||
// Decode the filename, which may be percent-encoded.
|
// Decode the filename, which may be percent-encoded.
|
||||||
let filename = urlencoding::decode(last)?;
|
let filename = percent_encoding::percent_decode_str(last).decode_utf8()?;
|
||||||
|
|
||||||
Ok(filename)
|
Ok(filename)
|
||||||
}
|
}
|
||||||
|
|
@ -943,7 +943,7 @@ impl RemoteSource for UrlString {
|
||||||
.ok_or_else(|| Error::MissingPathSegments(self.to_string()))?;
|
.ok_or_else(|| Error::MissingPathSegments(self.to_string()))?;
|
||||||
|
|
||||||
// Decode the filename, which may be percent-encoded.
|
// Decode the filename, which may be percent-encoded.
|
||||||
let filename = urlencoding::decode(last)?;
|
let filename = percent_encoding::percent_decode_str(last).decode_utf8()?;
|
||||||
|
|
||||||
Ok(filename)
|
Ok(filename)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ doctest = false
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
cachedir = { workspace = true }
|
cachedir = { workspace = true }
|
||||||
dunce = { workspace = true }
|
dunce = { workspace = true }
|
||||||
either = { workspace = true }
|
either = { workspace = true }
|
||||||
|
|
@ -24,12 +23,12 @@ encoding_rs_io = { workspace = true }
|
||||||
fs-err = { workspace = true }
|
fs-err = { workspace = true }
|
||||||
fs2 = { workspace = true }
|
fs2 = { workspace = true }
|
||||||
path-slash = { workspace = true }
|
path-slash = { workspace = true }
|
||||||
|
percent-encoding = { workspace = true }
|
||||||
schemars = { workspace = true, optional = true }
|
schemars = { workspace = true, optional = true }
|
||||||
serde = { workspace = true, optional = true }
|
serde = { workspace = true, optional = true }
|
||||||
tokio = { workspace = true, optional = true}
|
|
||||||
tempfile = { workspace = true }
|
tempfile = { workspace = true }
|
||||||
|
tokio = { workspace = true, optional = true}
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
urlencoding = { workspace = true }
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
winsafe = { workspace = true }
|
winsafe = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,9 @@ impl<T: AsRef<Path>> PythonExt for T {
|
||||||
/// On other platforms, this is a no-op.
|
/// On other platforms, this is a no-op.
|
||||||
pub fn normalize_url_path(path: &str) -> Cow<'_, str> {
|
pub fn normalize_url_path(path: &str) -> Cow<'_, str> {
|
||||||
// Apply percent-decoding to the URL.
|
// Apply percent-decoding to the URL.
|
||||||
let path = urlencoding::decode(path).unwrap_or(Cow::Borrowed(path));
|
let path = percent_encoding::percent_decode_str(path)
|
||||||
|
.decode_utf8()
|
||||||
|
.unwrap_or(Cow::Borrowed(path));
|
||||||
|
|
||||||
// Return the path.
|
// Return the path.
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue