mirror of https://github.com/astral-sh/uv
## Summary This is an alternative to #9344. If accepted, I need to audit the codebase and call sites to apply it everywhere, but the basic idea is: rather than encoding mutually-incompatible pairs of markers in the representation itself, we have an additional method on `MarkerTree` that expands the false-y definition to take into account assumptions about which markers can be true alongside others. We then check if the the current marker implies that at least one of them is true. So, for example, we know that `sys_platform == 'win32'` and `platform_system == 'Darwin'` are mutually exclusive. When given a marker expression like `python_version >= '3.7'`, we test if `python_version >= '3.7'` and `sys_platform != 'win32' or platform_system != 'Darwin'` are disjoint, i.e., if the following can't be satisfied: ``` python_version >= '3.7' and (sys_platform != 'win32' or platform_system != 'Darwin') ``` Since, if this can't be satisfied, it implies that the left-hand expression requires `sys_platform == 'win32'` and `platform_system == 'Darwin'` to be true at the same time. I think the main downsides here are: 1. We can't _simplify_ markers based on these implications. So we'd still write markers like `sys_platform == 'win32' and platform_system != 'Darwin'`, even though we know the latter expression is redundant. 2. It might be expensive? I'm not sure. I don't think we test for falseness _that_ often though. Closes #7760. Closes #9275. |
||
|---|---|---|
| .. | ||
| src | ||
| Cargo.toml | ||
| Changelog.md | ||
| License-Apache | ||
| License-BSD | ||
| Readme.md | ||
Readme.md
Dependency specifiers (PEP 508) in Rust
A library for dependency specifiers, previously 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.