uv/crates/uv-pep508
Andrew Gallant 7b80b18166 uv-pep508: fix disjointness bug
This commit fixes a bug where disjointness checking didn't always
satisfy commutativity. And it *should*. The `is_disjoint_commutative`
test added here demonstrates a regression test. Before this commit,
its second assertion failed.

That is, given `m1 = extra == "A" and extra != "B"` and
`m2 = extra == "A"`, we were saying that m1 was disjoint with
m2 (wrong) but that m2 was not disjoint with m1 (right).

It turned out that this was a "simple" matter of not using the
correct parent node when calling negation. Likely just a
transcription snafu.

This bug does not seem restricted in scope to extras, which is
how I found it, so it's not clear why we haven't noticed it until
now. I noticed it because I was formulating markers in a similar
format for resolver forking based on conflicting extras, and this
resulted in incorrectly filtering out dependencies due to `is_disjoint`
returning a false positive.
2024-10-10 09:46:42 -04:00
..
src uv-pep508: fix disjointness bug 2024-10-10 09:46:42 -04:00
Cargo.toml Add `uv-` prefix to all internal crates (#7853) 2024-10-01 20:15:32 -04:00
Changelog.md Add `uv-` prefix to all internal crates (#7853) 2024-10-01 20:15:32 -04:00
License-Apache Add `uv-` prefix to all internal crates (#7853) 2024-10-01 20:15:32 -04:00
License-BSD Add `uv-` prefix to all internal crates (#7853) 2024-10-01 20:15:32 -04:00
Readme.md Add `uv-` prefix to all internal crates (#7853) 2024-10-01 20:15:32 -04:00

Readme.md

Dependency specifiers (PEP 508) in Rust

Crates.io PyPI

A library for python dependency specifiers, better known as PEP 508.

Usage

use std::str::FromStr;
use pep508_rs::Requirement;

let marker = r#"requests [security,tests] >= 2.8.1, == 2.8.* ; python_version > "3.8""#;
let dependency_specification = Requirement::from_str(marker).unwrap();
assert_eq!(dependency_specification.name, "requests");
assert_eq!(dependency_specification.extras, Some(vec!["security".to_string(), "tests".to_string()]));

Markers

Markers allow you to install dependencies only in specific environments (python version, operating system, architecture, etc.) or when a specific feature is activated. E.g. you can say importlib-metadata ; python_version < "3.8" or itsdangerous (>=1.1.0) ; extra == 'security'. Unfortunately, the marker grammar has some oversights (e.g. https://github.com/pypa/packaging.python.org/pull/1181) and the design of comparisons (PEP 440 comparisons with lexicographic fallback) leads to confusing outcomes. This implementation tries to carefully validate everything and emit warnings whenever bogus comparisons with unintended semantics are made.