Backport changes from publish crates (#1739)

Backport of changes for the published new versions of pep440_rs and
pep508_rs to make it easier to keep them in sync.
This commit is contained in:
konsti 2024-02-20 19:33:27 +01:00 committed by GitHub
parent 8480842d3e
commit 2928c6e574
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 121 additions and 120 deletions

64
Cargo.lock generated
View File

@ -876,7 +876,7 @@ name = "distribution-filename"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"insta", "insta",
"pep440_rs 0.4.0", "pep440_rs",
"platform-tags", "platform-tags",
"rkyv", "rkyv",
"serde", "serde",
@ -896,7 +896,7 @@ dependencies = [
"fs-err", "fs-err",
"itertools 0.12.1", "itertools 0.12.1",
"once_cell", "once_cell",
"pep440_rs 0.4.0", "pep440_rs",
"pep508_rs", "pep508_rs",
"platform-tags", "platform-tags",
"pypi-types", "pypi-types",
@ -1588,7 +1588,7 @@ dependencies = [
"indoc", "indoc",
"mailparse", "mailparse",
"once_cell", "once_cell",
"pep440_rs 0.4.0", "pep440_rs",
"platform-host", "platform-host",
"platform-info", "platform-info",
"plist", "plist",
@ -2156,16 +2156,6 @@ dependencies = [
"parking_lot_core 0.8.6", "parking_lot_core 0.8.6",
] ]
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core 0.9.9",
]
[[package]] [[package]]
name = "parking_lot_core" name = "parking_lot_core"
version = "0.8.6" version = "0.8.6"
@ -2201,19 +2191,7 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]] [[package]]
name = "pep440_rs" name = "pep440_rs"
version = "0.3.12" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "887f66cc62717ea72caac4f1eb4e6f392224da3ffff3f40ec13ab427802746d6"
dependencies = [
"lazy_static",
"regex",
"serde",
"unicode-width",
]
[[package]]
name = "pep440_rs"
version = "0.4.0"
dependencies = [ dependencies = [
"indoc", "indoc",
"once_cell", "once_cell",
@ -2228,13 +2206,13 @@ dependencies = [
[[package]] [[package]]
name = "pep508_rs" name = "pep508_rs"
version = "0.2.3" version = "0.4.2"
dependencies = [ dependencies = [
"derivative", "derivative",
"indoc", "indoc",
"log", "log",
"once_cell", "once_cell",
"pep440_rs 0.4.0", "pep440_rs",
"pyo3", "pyo3",
"pyo3-log", "pyo3-log",
"regex", "regex",
@ -2496,7 +2474,7 @@ dependencies = [
"indoc", "indoc",
"libc", "libc",
"memoffset", "memoffset",
"parking_lot 0.12.1", "parking_lot",
"pyo3-build-config", "pyo3-build-config",
"pyo3-ffi", "pyo3-ffi",
"pyo3-macros", "pyo3-macros",
@ -2567,7 +2545,7 @@ dependencies = [
"insta", "insta",
"mailparse", "mailparse",
"once_cell", "once_cell",
"pep440_rs 0.4.0", "pep440_rs",
"pep508_rs", "pep508_rs",
"regex", "regex",
"rkyv", "rkyv",
@ -2583,12 +2561,12 @@ dependencies = [
[[package]] [[package]]
name = "pyproject-toml" name = "pyproject-toml"
version = "0.8.1" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46d4a5e69187f23a29f8aa0ea57491d104ba541bc55f76552c2a74962aa20e04" checksum = "3b80f889b6d413c3f8963a2c7db03f95dd6e1d85e1074137cb2013ea2faa8898"
dependencies = [ dependencies = [
"indexmap 2.2.3", "indexmap 2.2.3",
"pep440_rs 0.3.12", "pep440_rs",
"pep508_rs", "pep508_rs",
"serde", "serde",
"toml", "toml",
@ -2793,7 +2771,7 @@ dependencies = [
"insta", "insta",
"itertools 0.10.5", "itertools 0.10.5",
"once_cell", "once_cell",
"pep440_rs 0.4.0", "pep440_rs",
"pep508_rs", "pep508_rs",
"regex", "regex",
"serde", "serde",
@ -2882,7 +2860,7 @@ dependencies = [
"getrandom", "getrandom",
"http", "http",
"hyper", "hyper",
"parking_lot 0.11.2", "parking_lot",
"reqwest", "reqwest",
"reqwest-middleware", "reqwest-middleware",
"retry-policies", "retry-policies",
@ -4185,7 +4163,7 @@ dependencies = [
"miette", "miette",
"mimalloc", "mimalloc",
"owo-colors 4.0.0", "owo-colors 4.0.0",
"pep440_rs 0.4.0", "pep440_rs",
"pep508_rs", "pep508_rs",
"platform-host", "platform-host",
"platform-tags", "platform-tags",
@ -4292,7 +4270,7 @@ dependencies = [
"http", "http",
"insta", "insta",
"install-wheel-rs", "install-wheel-rs",
"pep440_rs 0.4.0", "pep440_rs",
"pep508_rs", "pep508_rs",
"platform-tags", "platform-tags",
"pypi-types", "pypi-types",
@ -4338,7 +4316,7 @@ dependencies = [
"itertools 0.12.1", "itertools 0.12.1",
"mimalloc", "mimalloc",
"owo-colors 4.0.0", "owo-colors 4.0.0",
"pep440_rs 0.4.0", "pep440_rs",
"pep508_rs", "pep508_rs",
"petgraph", "petgraph",
"platform-host", "platform-host",
@ -4410,7 +4388,7 @@ dependencies = [
"futures", "futures",
"install-wheel-rs", "install-wheel-rs",
"nanoid", "nanoid",
"pep440_rs 0.4.0", "pep440_rs",
"pep508_rs", "pep508_rs",
"platform-tags", "platform-tags",
"pypi-types", "pypi-types",
@ -4502,7 +4480,7 @@ dependencies = [
"futures", "futures",
"install-wheel-rs", "install-wheel-rs",
"once-map", "once-map",
"pep440_rs 0.4.0", "pep440_rs",
"pep508_rs", "pep508_rs",
"platform-tags", "platform-tags",
"pypi-types", "pypi-types",
@ -4536,7 +4514,7 @@ dependencies = [
"insta", "insta",
"itertools 0.12.1", "itertools 0.12.1",
"once_cell", "once_cell",
"pep440_rs 0.4.0", "pep440_rs",
"pep508_rs", "pep508_rs",
"platform-host", "platform-host",
"platform-tags", "platform-tags",
@ -4586,7 +4564,7 @@ dependencies = [
"once-map", "once-map",
"once_cell", "once_cell",
"owo-colors 4.0.0", "owo-colors 4.0.0",
"pep440_rs 0.4.0", "pep440_rs",
"pep508_rs", "pep508_rs",
"petgraph", "petgraph",
"platform-host", "platform-host",
@ -4812,7 +4790,7 @@ checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f"
dependencies = [ dependencies = [
"futures", "futures",
"js-sys", "js-sys",
"parking_lot 0.11.2", "parking_lot",
"pin-utils", "pin-utils",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",

View File

@ -69,7 +69,7 @@ plist = { version = "1.6.0" }
pubgrub = { git = "https://github.com/zanieb/pubgrub", rev = "9b6d89cb8a0c7902815c8b2ae99106ba322ffb14" } pubgrub = { git = "https://github.com/zanieb/pubgrub", rev = "9b6d89cb8a0c7902815c8b2ae99106ba322ffb14" }
pyo3 = { version = "0.20.2" } pyo3 = { version = "0.20.2" }
pyo3-log = { version = "0.9.0"} pyo3-log = { version = "0.9.0"}
pyproject-toml = { version = "0.8.1" } pyproject-toml = { version = "0.10.0" }
rand = { version = "0.8.5" } rand = { version = "0.8.5" }
rayon = { version = "1.8.0" } rayon = { version = "1.8.0" }
reflink-copy = { version = "0.1.14" } reflink-copy = { version = "0.1.14" }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "pep440_rs" name = "pep440_rs"
version = "0.4.0" version = "0.5.0"
description = "A library for python version numbers and specifiers, implementing PEP 440" description = "A library for python version numbers and specifiers, implementing PEP 440"
license = "Apache-2.0 OR BSD-2-Clause" license = "Apache-2.0 OR BSD-2-Clause"
include = ["/src", "Changelog.md", "License-Apache", "License-BSD", "Readme.md", "pyproject.toml"] include = ["/src", "Changelog.md", "License-Apache", "License-BSD", "Readme.md", "pyproject.toml"]

View File

@ -16,7 +16,7 @@ let version = Version::from_str("1.19").unwrap();
let version_specifier = VersionSpecifier::from_str("==1.*").unwrap(); let version_specifier = VersionSpecifier::from_str("==1.*").unwrap();
assert!(version_specifier.contains(&version)); assert!(version_specifier.contains(&version));
let version_specifiers = parse_version_specifiers(">=1.16, <2.0").unwrap(); let version_specifiers = parse_version_specifiers(">=1.16, <2.0").unwrap();
assert!(version_specifiers.iter().all(|specifier| specifier.contains(&version))); assert!(version_specifiers.contains(&version));
``` ```
In python (`pip install pep440_rs`): In python (`pip install pep440_rs`):

View File

@ -9,7 +9,7 @@
//! let version_specifier = VersionSpecifier::from_str("== 1.*").unwrap(); //! let version_specifier = VersionSpecifier::from_str("== 1.*").unwrap();
//! assert!(version_specifier.contains(&version)); //! assert!(version_specifier.contains(&version));
//! let version_specifiers = VersionSpecifiers::from_str(">=1.16, <2.0").unwrap(); //! let version_specifiers = VersionSpecifiers::from_str(">=1.16, <2.0").unwrap();
//! assert!(version_specifiers.iter().all(|specifier| specifier.contains(&version))); //! assert!(version_specifiers.contains(&version));
//! ``` //! ```
//! //!
//! PEP 440 has a lot of unintuitive features, including: //! PEP 440 has a lot of unintuitive features, including:
@ -41,9 +41,7 @@ pub use {
LocalSegment, Operator, OperatorParseError, PreRelease, PreReleaseKind, Version, LocalSegment, Operator, OperatorParseError, PreRelease, PreReleaseKind, Version,
VersionParseError, VersionPattern, VersionPatternParseError, MIN_VERSION, VersionParseError, VersionPattern, VersionPatternParseError, MIN_VERSION,
}, },
version_specifier::{ version_specifier::{VersionSpecifier, VersionSpecifiers, VersionSpecifiersParseError},
parse_version_specifiers, VersionSpecifier, VersionSpecifiers, VersionSpecifiersParseError,
},
}; };
mod version; mod version;

View File

@ -2291,7 +2291,7 @@ fn parse_u64(bytes: &[u8]) -> Result<u64, VersionParseError> {
Ok(n) Ok(n)
} }
/// The minimum version that can be represented by a [`Version`]. /// The minimum version that can be represented by a [`Version`]: `0a0.dev0`.
pub static MIN_VERSION: once_cell::sync::Lazy<Version> = pub static MIN_VERSION: once_cell::sync::Lazy<Version> =
once_cell::sync::Lazy::new(|| Version::from_str("0a0.dev0").unwrap()); once_cell::sync::Lazy::new(|| Version::from_str("0a0.dev0").unwrap());

View File

@ -697,19 +697,8 @@ impl From<ParseErrorKind> for VersionSpecifierParseError {
} }
} }
/// Parses a list of specifiers such as `>= 1.0, != 1.3.*, < 2.0`. /// Parse a list of specifiers such as `>= 1.0, != 1.3.*, < 2.0`.
/// pub(crate) fn parse_version_specifiers(
/// I recommend using [`VersionSpecifiers::from_str`] instead.
///
/// ```rust
/// use std::str::FromStr;
/// use pep440_rs::{parse_version_specifiers, Version};
///
/// let version = Version::from_str("1.19").unwrap();
/// let version_specifiers = parse_version_specifiers(">=1.16, <2.0").unwrap();
/// assert!(version_specifiers.iter().all(|specifier| specifier.contains(&version)));
/// ```
pub fn parse_version_specifiers(
spec: &str, spec: &str,
) -> Result<Vec<VersionSpecifier>, VersionSpecifiersParseError> { ) -> Result<Vec<VersionSpecifier>, VersionSpecifiersParseError> {
let mut version_ranges = Vec::new(); let mut version_ranges = Vec::new();

View File

@ -1,6 +1,6 @@
[package] [package]
name = "pep508_rs" name = "pep508_rs"
version = "0.2.3" version = "0.4.2"
description = "A library for python dependency specifiers, better known as PEP 508" description = "A library for python dependency specifiers, better known as PEP 508"
include = ["/src", "Changelog.md", "License-Apache", "License-BSD", "Readme.md", "pyproject.toml"] include = ["/src", "Changelog.md", "License-Apache", "License-BSD", "Readme.md", "pyproject.toml"]
license = "Apache-2.0 OR BSD-2-Clause" license = "Apache-2.0 OR BSD-2-Clause"
@ -30,9 +30,9 @@ rkyv = { workspace = true, features = ["strict"], optional = true }
serde = { workspace = true, features = ["derive"], optional = true } serde = { workspace = true, features = ["derive"], optional = true }
serde_json = { workspace = true, optional = true } serde_json = { workspace = true, optional = true }
thiserror = { workspace = true } thiserror = { workspace = true }
tracing = { workspace = true, features = ["log"] } tracing = { workspace = true, optional = true }
unicode-width = { workspace = true } unicode-width = { workspace = true }
url = { workspace = true, features = ["serde"] } url = { workspace = true }
[dev-dependencies] [dev-dependencies]
indoc = { version = "2.0.4" } indoc = { version = "2.0.4" }
@ -41,7 +41,15 @@ serde_json = { version = "1.0.111" }
testing_logger = { version = "0.1.1" } testing_logger = { version = "0.1.1" }
[features] [features]
pyo3 = ["dep:pyo3", "pep440_rs/pyo3", "pyo3-log"] pyo3 = ["dep:pyo3", "pep440_rs/pyo3", "pyo3-log", "tracing", "tracing/log"]
rkyv = ["dep:rkyv", "pep440_rs/rkyv"] rkyv = ["dep:rkyv", "pep440_rs/rkyv", "uv-normalize/rkyv"]
serde = ["dep:serde", "pep440_rs/serde"] serde = ["dep:serde", "pep440_rs/serde", "uv-normalize/serde", "url/serde"]
tracing = ["dep:tracing", "pep440_rs/tracing"]
# PEP 508 allows only URLs such as `foo @ https://example.org/foo` or `foo @ file:///home/ferris/foo`, and
# arguably does not allow relative paths in file URLs (`foo @ file://./foo`,
# `foo @ file:foo-3.0.0-py3-none-any.whl`, `foo @ file://foo-3.0.0-py3-none-any.whl`), as they are not part of the
# relevant RFCs, even though widely supported. Pip accepts relative file URLs and paths instead of urls
# (`foo @ ./foo-3.0.0-py3-none-any.whl`). The `non-pep508-features` controls whether these non-spec features will
# be supported.
non-pep508-extensions = []
default = [] default = []

View File

@ -14,7 +14,7 @@
//! assert_eq!(dependency_specification.extras, vec![ExtraName::from_str("security").unwrap(), ExtraName::from_str("tests").unwrap()]); //! assert_eq!(dependency_specification.extras, vec![ExtraName::from_str("security").unwrap(), ExtraName::from_str("tests").unwrap()]);
//! ``` //! ```
#![deny(missing_docs)] #![warn(missing_docs)]
#[cfg(feature = "pyo3")] #[cfg(feature = "pyo3")]
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
@ -738,7 +738,7 @@ fn parse_url(cursor: &mut Cursor, working_dir: Option<&Path>) -> Result<Verbatim
/// Create a `VerbatimUrl` to represent the requirement. /// Create a `VerbatimUrl` to represent the requirement.
fn preprocess_url( fn preprocess_url(
url: &str, url: &str,
working_dir: Option<&Path>, #[cfg_attr(not(feature = "non-pep508-extensions"), allow(unused))] working_dir: Option<&Path>,
cursor: &Cursor, cursor: &Cursor,
start: usize, start: usize,
len: usize, len: usize,
@ -752,9 +752,13 @@ fn preprocess_url(
// Transform, e.g., `/C:/Users/ferris/wheel-0.42.0.tar.gz` to `C:\Users\ferris\wheel-0.42.0.tar.gz`. // Transform, e.g., `/C:/Users/ferris/wheel-0.42.0.tar.gz` to `C:\Users\ferris\wheel-0.42.0.tar.gz`.
let path = normalize_url_path(path); let path = normalize_url_path(path);
#[cfg(feature = "non-pep508-extensions")]
if let Some(working_dir) = working_dir { if let Some(working_dir) = working_dir {
return Ok(
VerbatimUrl::from_path(path, working_dir).with_given(url.to_string()) VerbatimUrl::from_path(path, working_dir).with_given(url.to_string())
} else { );
}
VerbatimUrl::from_absolute_path(path) VerbatimUrl::from_absolute_path(path)
.map_err(|err| Pep508Error { .map_err(|err| Pep508Error {
message: Pep508ErrorSource::UrlError(err), message: Pep508ErrorSource::UrlError(err),
@ -764,8 +768,6 @@ fn preprocess_url(
})? })?
.with_given(url.to_string()) .with_given(url.to_string())
} }
}
// Ex) `https://download.pytorch.org/whl/torch_stable.html` // Ex) `https://download.pytorch.org/whl/torch_stable.html`
Some(_) => { Some(_) => {
// Ex) `https://download.pytorch.org/whl/torch_stable.html` // Ex) `https://download.pytorch.org/whl/torch_stable.html`
@ -795,9 +797,11 @@ fn preprocess_url(
} }
} else { } else {
// Ex) `../editable/` // Ex) `../editable/`
#[cfg(feature = "non-pep508-extensions")]
if let Some(working_dir) = working_dir { if let Some(working_dir) = working_dir {
VerbatimUrl::from_path(url, working_dir).with_given(url.to_string()) return Ok(VerbatimUrl::from_path(url, working_dir).with_given(url.to_string()));
} else { }
VerbatimUrl::from_absolute_path(url) VerbatimUrl::from_absolute_path(url)
.map_err(|err| Pep508Error { .map_err(|err| Pep508Error {
message: Pep508ErrorSource::UrlError(err), message: Pep508ErrorSource::UrlError(err),
@ -806,7 +810,6 @@ fn preprocess_url(
input: cursor.to_string(), input: cursor.to_string(),
})? })?
.with_given(url.to_string()) .with_given(url.to_string())
}
}; };
Ok(url) Ok(url)
} }
@ -1045,6 +1048,7 @@ pub fn python_module(py: Python<'_>, m: &PyModule) -> PyResult<()> {
/// Half of these tests are copied from <https://github.com/pypa/packaging/pull/624> /// Half of these tests are copied from <https://github.com/pypa/packaging/pull/624>
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::env;
use std::str::FromStr; use std::str::FromStr;
use indoc::indoc; use indoc::indoc;
@ -1629,4 +1633,26 @@ mod tests {
}, },
); );
} }
/// Check that the relative path support feature toggle works.
#[test]
fn non_pep508_paths() {
let requirements = &[
"foo @ file://./foo",
"foo @ file://foo-3.0.0-py3-none-any.whl",
"foo @ file:foo-3.0.0-py3-none-any.whl",
"foo @ ./foo-3.0.0-py3-none-any.whl",
];
let cwd = env::current_dir().unwrap();
for requirement in requirements {
assert_eq!(
Requirement::parse(requirement, &cwd).is_ok(),
cfg!(feature = "non-pep508-extensions"),
"{}: {:?}",
requirement,
Requirement::parse(requirement, &cwd)
);
}
}
} }

View File

@ -21,7 +21,6 @@ use std::collections::HashSet;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::ops::Deref; use std::ops::Deref;
use std::str::FromStr; use std::str::FromStr;
use tracing::warn;
use uv_normalize::ExtraName; use uv_normalize::ExtraName;
/// Ways in which marker evaluation can fail /// Ways in which marker evaluation can fail
@ -944,8 +943,11 @@ impl FromStr for MarkerTree {
impl MarkerTree { impl MarkerTree {
/// Does this marker apply in the given environment? /// Does this marker apply in the given environment?
pub fn evaluate(&self, env: &MarkerEnvironment, extras: &[ExtraName]) -> bool { pub fn evaluate(&self, env: &MarkerEnvironment, extras: &[ExtraName]) -> bool {
let mut reporter = |_kind, message, _marker_expression: &MarkerExpression| { let mut reporter = |_kind, _message, _marker_expression: &MarkerExpression| {
warn!("{}", message); #[cfg(feature = "tracing")]
{
tracing::warn!("{}", _message);
}
}; };
self.report_deprecated_options(&mut reporter); self.report_deprecated_options(&mut reporter);
match self { match self {
@ -1347,7 +1349,6 @@ mod test {
use crate::marker::{MarkerEnvironment, StringVersion}; use crate::marker::{MarkerEnvironment, StringVersion};
use crate::{MarkerExpression, MarkerOperator, MarkerTree, MarkerValue, MarkerValueString}; use crate::{MarkerExpression, MarkerOperator, MarkerTree, MarkerValue, MarkerValueString};
use indoc::indoc; use indoc::indoc;
use log::Level;
use std::str::FromStr; use std::str::FromStr;
fn assert_err(input: &str, error: &str) { fn assert_err(input: &str, error: &str) {
@ -1443,6 +1444,7 @@ mod test {
} }
#[test] #[test]
#[cfg(feature = "tracing")]
fn warnings() { fn warnings() {
let env37 = env37(); let env37 = env37();
testing_logger::setup(); testing_logger::setup();
@ -1453,7 +1455,7 @@ mod test {
captured_logs[0].body, captured_logs[0].body,
"Comparing two markers with each other doesn't make any sense, evaluating to false" "Comparing two markers with each other doesn't make any sense, evaluating to false"
); );
assert_eq!(captured_logs[0].level, Level::Warn); assert_eq!(captured_logs[0].level, log::Level::Warn);
assert_eq!(captured_logs.len(), 1); assert_eq!(captured_logs.len(), 1);
}); });
let non_pep440 = MarkerTree::from_str("python_version >= '3.9.'").unwrap(); let non_pep440 = MarkerTree::from_str("python_version >= '3.9.'").unwrap();
@ -1465,7 +1467,7 @@ mod test {
evaluating to false: after parsing 3.9, found \".\" after it, \ evaluating to false: after parsing 3.9, found \".\" after it, \
which is not part of a valid version" which is not part of a valid version"
); );
assert_eq!(captured_logs[0].level, Level::Warn); assert_eq!(captured_logs[0].level, log::Level::Warn);
assert_eq!(captured_logs.len(), 1); assert_eq!(captured_logs.len(), 1);
}); });
let string_string = MarkerTree::from_str("'b' >= 'a'").unwrap(); let string_string = MarkerTree::from_str("'b' >= 'a'").unwrap();
@ -1475,7 +1477,7 @@ mod test {
captured_logs[0].body, captured_logs[0].body,
"Comparing two quoted strings with each other doesn't make sense: 'b' >= 'a', evaluating to false" "Comparing two quoted strings with each other doesn't make sense: 'b' >= 'a', evaluating to false"
); );
assert_eq!(captured_logs[0].level, Level::Warn); assert_eq!(captured_logs[0].level, log::Level::Warn);
assert_eq!(captured_logs.len(), 1); assert_eq!(captured_logs.len(), 1);
}); });
let string_string = MarkerTree::from_str(r#"os.name == 'posix' and platform.machine == 'x86_64' and platform.python_implementation == 'CPython' and 'Ubuntu' in platform.version and sys.platform == 'linux'"#).unwrap(); let string_string = MarkerTree::from_str(r#"os.name == 'posix' and platform.machine == 'x86_64' and platform.python_implementation == 'CPython' and 'Ubuntu' in platform.version and sys.platform == 'linux'"#).unwrap();
@ -1484,7 +1486,7 @@ mod test {
let messages: Vec<_> = captured_logs let messages: Vec<_> = captured_logs
.iter() .iter()
.map(|message| { .map(|message| {
assert_eq!(message.level, Level::Warn); assert_eq!(message.level, log::Level::Warn);
&message.body &message.body
}) })
.collect(); .collect();

View File

@ -35,7 +35,8 @@ impl VerbatimUrl {
Ok(Self { url, given: None }) Ok(Self { url, given: None })
} }
/// Parse a URL from am absolute or relative path. /// Parse a URL from an absolute or relative path.
#[cfg(feature = "non-pep508-extensions")] // PEP 508 arguably only allows absolute file URLs.
pub fn from_path(path: impl AsRef<str>, working_dir: impl AsRef<Path>) -> Self { pub fn from_path(path: impl AsRef<str>, working_dir: impl AsRef<Path>) -> Self {
// Expand any environment variables. // Expand any environment variables.
let path = PathBuf::from(expand_env_vars(path.as_ref(), false).as_ref()); let path = PathBuf::from(expand_env_vars(path.as_ref(), false).as_ref());

View File

@ -14,7 +14,7 @@ workspace = true
[dependencies] [dependencies]
pep440_rs = { path = "../pep440-rs", features = ["rkyv", "serde"] } pep440_rs = { path = "../pep440-rs", features = ["rkyv", "serde"] }
pep508_rs = { path = "../pep508-rs", features = ["rkyv", "serde"] } pep508_rs = { path = "../pep508-rs", features = ["rkyv", "serde", "non-pep508-extensions"] }
uv-fs = { path = "../uv-fs" } uv-fs = { path = "../uv-fs" }
uv-normalize = { path = "../uv-normalize" } uv-normalize = { path = "../uv-normalize" }
uv-warnings = { path = "../uv-warnings" } uv-warnings = { path = "../uv-warnings" }

View File

@ -5,5 +5,5 @@ edition = "2021"
description = "Normalization for distribution, package and extra anmes" description = "Normalization for distribution, package and extra anmes"
[dependencies] [dependencies]
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"], optional = true }
rkyv = { workspace = true, features = ["strict", "validation"] } rkyv = { workspace = true, features = ["strict", "validation"], optional = true }

View File

@ -1,3 +1,4 @@
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize}; use serde::{Deserialize, Deserializer, Serialize};
use std::fmt; use std::fmt;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
@ -13,7 +14,8 @@ use crate::{validate_and_normalize_owned, validate_and_normalize_ref, InvalidNam
/// See: /// See:
/// - <https://peps.python.org/pep-0685/#specification/> /// - <https://peps.python.org/pep-0685/#specification/>
/// - <https://packaging.python.org/en/latest/specifications/name-normalization/> /// - <https://packaging.python.org/en/latest/specifications/name-normalization/>
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize)] #[cfg_attr(feature = "serde", derive(Serialize))]
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ExtraName(String); pub struct ExtraName(String);
impl ExtraName { impl ExtraName {
@ -31,6 +33,7 @@ impl FromStr for ExtraName {
} }
} }
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for ExtraName { impl<'de> Deserialize<'de> for ExtraName {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where

View File

@ -90,6 +90,7 @@ fn is_normalized(name: impl AsRef<str>) -> Result<bool, InvalidNameError> {
Ok(true) Ok(true)
} }
/// Invalid [`crate::PackageName`] or [`crate::ExtraName`].
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub struct InvalidNameError(String); pub struct InvalidNameError(String);

View File

@ -1,6 +1,7 @@
use std::borrow::Cow; use std::borrow::Cow;
use std::str::FromStr; use std::str::FromStr;
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize}; use serde::{Deserialize, Deserializer, Serialize};
use crate::{validate_and_normalize_owned, validate_and_normalize_ref, InvalidNameError}; use crate::{validate_and_normalize_owned, validate_and_normalize_ref, InvalidNameError};
@ -11,21 +12,14 @@ use crate::{validate_and_normalize_owned, validate_and_normalize_ref, InvalidNam
/// down to a single `-`, e.g., `---`, `.`, and `__` all get converted to just `-`. /// down to a single `-`, e.g., `---`, `.`, and `__` all get converted to just `-`.
/// ///
/// See: <https://packaging.python.org/en/latest/specifications/name-normalization/> /// See: <https://packaging.python.org/en/latest/specifications/name-normalization/>
#[derive( #[cfg_attr(feature = "serde", derive(Serialize))]
Debug, #[cfg_attr(
Clone, feature = "rkyv",
PartialEq, derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize),
Eq, archive(check_bytes),
Hash, archive_attr(derive(Debug))
PartialOrd,
Ord,
Serialize,
rkyv::Archive,
rkyv::Deserialize,
rkyv::Serialize,
)] )]
#[archive(check_bytes)] #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[archive_attr(derive(Debug))]
pub struct PackageName(String); pub struct PackageName(String);
impl PackageName { impl PackageName {
@ -75,6 +69,7 @@ impl FromStr for PackageName {
} }
} }
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for PackageName { impl<'de> Deserialize<'de> for PackageName {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where