nab-markersets 0.0.16__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nab_markersets-0.0.16/.gitignore +22 -0
- nab_markersets-0.0.16/LICENSE +21 -0
- nab_markersets-0.0.16/PKG-INFO +101 -0
- nab_markersets-0.0.16/README.md +74 -0
- nab_markersets-0.0.16/pyproject.toml +43 -0
- nab_markersets-0.0.16/src/nab_markersets/__init__.py +11 -0
- nab_markersets-0.0.16/src/nab_markersets/_compat.py +18 -0
- nab_markersets-0.0.16/src/nab_markersets/_markersets.py +1972 -0
- nab_markersets-0.0.16/src/nab_markersets/_packaging.py +156 -0
- nab_markersets-0.0.16/src/nab_markersets/errors.py +35 -0
- nab_markersets-0.0.16/src/nab_markersets/markersets.py +507 -0
- nab_markersets-0.0.16/src/nab_markersets/py.typed +0 -0
- nab_markersets-0.0.16/tests/__init__.py +1 -0
- nab_markersets-0.0.16/tests/ruff.toml +30 -0
- nab_markersets-0.0.16/tests/simplify_corpus_fixtures.py +752 -0
- nab_markersets-0.0.16/tests/test_docs.py +23 -0
- nab_markersets-0.0.16/tests/test_marker_algebra.py +1779 -0
- nab_markersets-0.0.16/tests/test_marker_algebra_differential.py +394 -0
- nab_markersets-0.0.16/tests/test_markersets.py +865 -0
- nab_markersets-0.0.16/tests/test_packaging_backend.py +227 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
*.egg-info/
|
|
4
|
+
dist/
|
|
5
|
+
build/
|
|
6
|
+
.pytest_cache/
|
|
7
|
+
.hypothesis/
|
|
8
|
+
.coverage*
|
|
9
|
+
.ruff_cache/
|
|
10
|
+
.venv/
|
|
11
|
+
.hatch/
|
|
12
|
+
.nox/
|
|
13
|
+
docs/_build/
|
|
14
|
+
|
|
15
|
+
*token*.txt
|
|
16
|
+
*.pypirc
|
|
17
|
+
.pypirc
|
|
18
|
+
|
|
19
|
+
# Profiling artefacts. By convention these live in `profiling/` at
|
|
20
|
+
# the workspace root and never inside `docs/`, so the Sphinx build
|
|
21
|
+
# never has to scan them.
|
|
22
|
+
profiling/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Damian Shaw
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nab-markersets
|
|
3
|
+
Version: 0.0.16
|
|
4
|
+
Summary: PEP 508 marker algebra: markers as sets of environments
|
|
5
|
+
Project-URL: Homepage, https://github.com/notatallshaw/nab
|
|
6
|
+
Project-URL: Documentation, https://nab.readthedocs.io/
|
|
7
|
+
Project-URL: Issues, https://github.com/notatallshaw/nab/issues
|
|
8
|
+
Project-URL: Source, https://github.com/notatallshaw/nab
|
|
9
|
+
Project-URL: Changelog, https://github.com/notatallshaw/nab/releases
|
|
10
|
+
Author-email: Damian Shaw <damian.peter.shaw@gmail.com>
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Provides-Extra: nab-vendored-packaging
|
|
23
|
+
Requires-Dist: nab-provider==0.0.16; extra == 'nab-vendored-packaging'
|
|
24
|
+
Provides-Extra: packaging
|
|
25
|
+
Requires-Dist: packaging>=26.3; extra == 'packaging'
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# nab-markersets
|
|
29
|
+
|
|
30
|
+
A PEP 508 marker read as the set of environments it selects. `packaging`
|
|
31
|
+
answers "does this marker hold here"; this answers "can these two ever both
|
|
32
|
+
hold", "does one imply the other", and "is this a contradiction".
|
|
33
|
+
|
|
34
|
+
**Experimental.** Anything here can change in any release, so pin an exact
|
|
35
|
+
version. The intent is to land this algebra in `packaging` itself, and the
|
|
36
|
+
shape below is what that proposal is being tried against; the discussion is
|
|
37
|
+
[pypa/packaging#448](https://github.com/pypa/packaging/issues/448).
|
|
38
|
+
|
|
39
|
+
```pycon
|
|
40
|
+
>>> from nab_markersets.markersets import MarkerSet
|
|
41
|
+
>>> old = MarkerSet.from_marker('python_version < "3.11"')
|
|
42
|
+
>>> new = MarkerSet.from_marker('python_version >= "3.12"')
|
|
43
|
+
>>> old.is_disjoint(new)
|
|
44
|
+
True
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
A set also holds what a marker string cannot: the full set of an absent
|
|
48
|
+
marker, the empty set of a contradiction, and complements the grammar cannot
|
|
49
|
+
spell. `witness` returns a point in the set, which is what separates two
|
|
50
|
+
markers that look like one constraint.
|
|
51
|
+
|
|
52
|
+
```pycon
|
|
53
|
+
>>> minor = MarkerSet.from_marker('python_version >= "3.11"')
|
|
54
|
+
>>> exact = MarkerSet.from_marker('python_full_version >= "3.11.0"')
|
|
55
|
+
>>> minor.equivalent(exact)
|
|
56
|
+
False
|
|
57
|
+
>>> (minor & ~exact).witness()["python_full_version"]
|
|
58
|
+
'3.11.0.dev0'
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Installing
|
|
62
|
+
|
|
63
|
+
The engine runs on `packaging`'s parse tree and its single-atom evaluator, and
|
|
64
|
+
two copies of `packaging` exist: the released one, and the fork
|
|
65
|
+
[`nab`](https://pypi.org/project/nab/) vendors. An extra picks which.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install "nab-markersets[packaging]"
|
|
69
|
+
pip install "nab-markersets[nab-vendored-packaging]"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The first copy at `packaging>=26.3` is bound, so with both installed the fork
|
|
73
|
+
wins and a `Marker` built inside nab keeps the class the algebra tests against.
|
|
74
|
+
A `Marker` from the other copy is accepted too. With nothing that new,
|
|
75
|
+
importing `nab_markersets.markersets` fails and says what it found.
|
|
76
|
+
|
|
77
|
+
## When to use it
|
|
78
|
+
|
|
79
|
+
Whether two lock entries can both apply, whether a dependency is reachable
|
|
80
|
+
inside your `requires-python`, or what a marker still says once you fix the
|
|
81
|
+
platform. The guide walks through those, and through what the decisions do not
|
|
82
|
+
decide:
|
|
83
|
+
<https://nab.readthedocs.io/en/stable/how-to/reason-about-markers.html>
|
|
84
|
+
|
|
85
|
+
## The public API
|
|
86
|
+
|
|
87
|
+
The supported API is the module paths below. Everything else in the package is
|
|
88
|
+
internal and may be renamed or relocated in any release.
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
nab_markersets.errors IntractableMarkerSet, UnserializableMarkerSet
|
|
92
|
+
nab_markersets.markersets DecisionStore, MarkerSet, variable_names
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The package root binds no names, so importing `nab_markersets` pulls in no
|
|
96
|
+
submodules.
|
|
97
|
+
|
|
98
|
+
Two things before you call it. A `MarkerSet` comes from `from_marker`, `full`
|
|
99
|
+
or `empty`, so `pickle.loads` fails on one: the constructor it reaches for
|
|
100
|
+
refuses. And `==` is structural, over the tree the set was built from, where
|
|
101
|
+
`equivalent` is the semantic test.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# nab-markersets
|
|
2
|
+
|
|
3
|
+
A PEP 508 marker read as the set of environments it selects. `packaging`
|
|
4
|
+
answers "does this marker hold here"; this answers "can these two ever both
|
|
5
|
+
hold", "does one imply the other", and "is this a contradiction".
|
|
6
|
+
|
|
7
|
+
**Experimental.** Anything here can change in any release, so pin an exact
|
|
8
|
+
version. The intent is to land this algebra in `packaging` itself, and the
|
|
9
|
+
shape below is what that proposal is being tried against; the discussion is
|
|
10
|
+
[pypa/packaging#448](https://github.com/pypa/packaging/issues/448).
|
|
11
|
+
|
|
12
|
+
```pycon
|
|
13
|
+
>>> from nab_markersets.markersets import MarkerSet
|
|
14
|
+
>>> old = MarkerSet.from_marker('python_version < "3.11"')
|
|
15
|
+
>>> new = MarkerSet.from_marker('python_version >= "3.12"')
|
|
16
|
+
>>> old.is_disjoint(new)
|
|
17
|
+
True
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
A set also holds what a marker string cannot: the full set of an absent
|
|
21
|
+
marker, the empty set of a contradiction, and complements the grammar cannot
|
|
22
|
+
spell. `witness` returns a point in the set, which is what separates two
|
|
23
|
+
markers that look like one constraint.
|
|
24
|
+
|
|
25
|
+
```pycon
|
|
26
|
+
>>> minor = MarkerSet.from_marker('python_version >= "3.11"')
|
|
27
|
+
>>> exact = MarkerSet.from_marker('python_full_version >= "3.11.0"')
|
|
28
|
+
>>> minor.equivalent(exact)
|
|
29
|
+
False
|
|
30
|
+
>>> (minor & ~exact).witness()["python_full_version"]
|
|
31
|
+
'3.11.0.dev0'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Installing
|
|
35
|
+
|
|
36
|
+
The engine runs on `packaging`'s parse tree and its single-atom evaluator, and
|
|
37
|
+
two copies of `packaging` exist: the released one, and the fork
|
|
38
|
+
[`nab`](https://pypi.org/project/nab/) vendors. An extra picks which.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install "nab-markersets[packaging]"
|
|
42
|
+
pip install "nab-markersets[nab-vendored-packaging]"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The first copy at `packaging>=26.3` is bound, so with both installed the fork
|
|
46
|
+
wins and a `Marker` built inside nab keeps the class the algebra tests against.
|
|
47
|
+
A `Marker` from the other copy is accepted too. With nothing that new,
|
|
48
|
+
importing `nab_markersets.markersets` fails and says what it found.
|
|
49
|
+
|
|
50
|
+
## When to use it
|
|
51
|
+
|
|
52
|
+
Whether two lock entries can both apply, whether a dependency is reachable
|
|
53
|
+
inside your `requires-python`, or what a marker still says once you fix the
|
|
54
|
+
platform. The guide walks through those, and through what the decisions do not
|
|
55
|
+
decide:
|
|
56
|
+
<https://nab.readthedocs.io/en/stable/how-to/reason-about-markers.html>
|
|
57
|
+
|
|
58
|
+
## The public API
|
|
59
|
+
|
|
60
|
+
The supported API is the module paths below. Everything else in the package is
|
|
61
|
+
internal and may be renamed or relocated in any release.
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
nab_markersets.errors IntractableMarkerSet, UnserializableMarkerSet
|
|
65
|
+
nab_markersets.markersets DecisionStore, MarkerSet, variable_names
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The package root binds no names, so importing `nab_markersets` pulls in no
|
|
69
|
+
submodules.
|
|
70
|
+
|
|
71
|
+
Two things before you call it. A `MarkerSet` comes from `from_marker`, `full`
|
|
72
|
+
or `empty`, so `pickle.loads` fails on one: the constructor it reaches for
|
|
73
|
+
refuses. And `==` is structural, over the tree the set was built from, where
|
|
74
|
+
`equivalent` is the semantic test.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "nab-markersets"
|
|
3
|
+
version = "0.0.16"
|
|
4
|
+
description = "PEP 508 marker algebra: markers as sets of environments"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "Damian Shaw", email = "damian.peter.shaw@gmail.com" },
|
|
10
|
+
]
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 4 - Beta",
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Programming Language :: Python :: 3.10",
|
|
16
|
+
"Programming Language :: Python :: 3.11",
|
|
17
|
+
"Programming Language :: Python :: 3.12",
|
|
18
|
+
"Programming Language :: Python :: 3.13",
|
|
19
|
+
"Programming Language :: Python :: 3.14",
|
|
20
|
+
"Typing :: Typed",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
# Pick the copy of packaging to run on; `nab_markersets._packaging` binds the
|
|
24
|
+
# first of these at the floor. The floor is where the suite has been run, and
|
|
25
|
+
# it is not open below: the engine reads `_parser.parse_marker`, `_parser.Op`,
|
|
26
|
+
# `_parser.Variable`, `_parser.Value`, `_tokenizer.ParserSyntaxError` and
|
|
27
|
+
# `markers._eval_op`, none of which packaging publishes, so a release may move
|
|
28
|
+
# any of them and `test_the_private_packaging_names_the_engine_reaches` is what
|
|
29
|
+
# says whether one did.
|
|
30
|
+
[project.optional-dependencies]
|
|
31
|
+
packaging = ["packaging>=26.3"]
|
|
32
|
+
nab-vendored-packaging = ["nab-provider==0.0.16"]
|
|
33
|
+
|
|
34
|
+
[project.urls]
|
|
35
|
+
Homepage = "https://github.com/notatallshaw/nab"
|
|
36
|
+
Documentation = "https://nab.readthedocs.io/"
|
|
37
|
+
Issues = "https://github.com/notatallshaw/nab/issues"
|
|
38
|
+
Source = "https://github.com/notatallshaw/nab"
|
|
39
|
+
Changelog = "https://github.com/notatallshaw/nab/releases"
|
|
40
|
+
|
|
41
|
+
[build-system]
|
|
42
|
+
requires = ["hatchling"]
|
|
43
|
+
build-backend = "hatchling.build"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""PEP 508 marker algebra: a marker as the set of environments it selects.
|
|
2
|
+
|
|
3
|
+
The supported API is the module paths below. Everything else in the package is
|
|
4
|
+
internal and may be renamed or relocated in any release.
|
|
5
|
+
|
|
6
|
+
nab_markersets.errors IntractableMarkerSet, UnserializableMarkerSet
|
|
7
|
+
nab_markersets.markersets DecisionStore, MarkerSet, variable_names
|
|
8
|
+
|
|
9
|
+
The package root binds no names, so importing ``nab_markersets`` pulls in no
|
|
10
|
+
submodules.
|
|
11
|
+
"""
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Runtime fallback for :func:`typing.override`, so ``typing_extensions`` is not needed.
|
|
2
|
+
|
|
3
|
+
``override`` runs at class-body time, so unlike the annotation-only helpers it
|
|
4
|
+
cannot hide under ``TYPE_CHECKING``. Looking it up by name rather than by
|
|
5
|
+
interpreter version keeps this free of a version-gated branch.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import typing
|
|
11
|
+
from typing import TYPE_CHECKING
|
|
12
|
+
|
|
13
|
+
__all__ = ["override"]
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from typing_extensions import override
|
|
17
|
+
else:
|
|
18
|
+
override = getattr(typing, "override", lambda method: method)
|