nab-python 0.0.2__tar.gz → 0.0.4__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_python-0.0.4/.gitignore +20 -0
- nab_python-0.0.4/LICENSE +1 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/PKG-INFO +4 -4
- nab_python-0.0.4/benchmarks/README.md +53 -0
- nab_python-0.0.4/benchmarks/_profile_runner.py +139 -0
- nab_python-0.0.4/benchmarks/cache/.gitignore +1 -0
- nab_python-0.0.4/benchmarks/canary.py +470 -0
- nab_python-0.0.4/benchmarks/canary_results/.gitignore +2 -0
- nab_python-0.0.4/benchmarks/compare.py +132 -0
- nab_python-0.0.4/benchmarks/results/.gitignore +2 -0
- nab_python-0.0.4/benchmarks/scenarios/ai-stack-lowest-direct.toml +864 -0
- nab_python-0.0.4/benchmarks/scenarios/ai-stack-lowest.toml +864 -0
- nab_python-0.0.4/benchmarks/scenarios/ai-stack.toml +814 -0
- nab_python-0.0.4/benchmarks/scenarios/airflow-lowest-direct.toml +257 -0
- nab_python-0.0.4/benchmarks/scenarios/airflow-lowest.toml +255 -0
- nab_python-0.0.4/benchmarks/scenarios/airflow.toml +234 -0
- nab_python-0.0.4/benchmarks/scenarios/big-packages-lowest-direct.toml +78 -0
- nab_python-0.0.4/benchmarks/scenarios/big-packages-lowest.toml +78 -0
- nab_python-0.0.4/benchmarks/scenarios/big-packages.toml +67 -0
- nab_python-0.0.4/benchmarks/scenarios/cross-tracker-lowest-direct.toml +110 -0
- nab_python-0.0.4/benchmarks/scenarios/cross-tracker-lowest.toml +110 -0
- nab_python-0.0.4/benchmarks/scenarios/cross-tracker.toml +101 -0
- nab_python-0.0.4/benchmarks/scenarios/ecosystem-lowest-direct.toml +531 -0
- nab_python-0.0.4/benchmarks/scenarios/ecosystem-lowest.toml +531 -0
- nab_python-0.0.4/benchmarks/scenarios/ecosystem.toml +490 -0
- nab_python-0.0.4/benchmarks/scenarios/forums-lowest-direct.toml +1349 -0
- nab_python-0.0.4/benchmarks/scenarios/forums-lowest.toml +1349 -0
- nab_python-0.0.4/benchmarks/scenarios/forums.toml +1251 -0
- nab_python-0.0.4/benchmarks/scenarios/pdm-lowest-direct.toml +336 -0
- nab_python-0.0.4/benchmarks/scenarios/pdm-lowest.toml +336 -0
- nab_python-0.0.4/benchmarks/scenarios/pdm.toml +315 -0
- nab_python-0.0.4/benchmarks/scenarios/pip-lowest-direct.toml +2132 -0
- nab_python-0.0.4/benchmarks/scenarios/pip-lowest.toml +2132 -0
- nab_python-0.0.4/benchmarks/scenarios/pip.toml +2027 -0
- nab_python-0.0.4/benchmarks/scenarios/poetry-lowest-direct.toml +545 -0
- nab_python-0.0.4/benchmarks/scenarios/poetry-lowest.toml +545 -0
- nab_python-0.0.4/benchmarks/scenarios/poetry.toml +504 -0
- nab_python-0.0.4/benchmarks/scenarios/pytorch-lowest-direct.toml +175 -0
- nab_python-0.0.4/benchmarks/scenarios/pytorch-lowest.toml +175 -0
- nab_python-0.0.4/benchmarks/scenarios/pytorch.toml +163 -0
- nab_python-0.0.4/benchmarks/scenarios/quick-lowest-direct.toml +13 -0
- nab_python-0.0.4/benchmarks/scenarios/quick-lowest.toml +13 -0
- nab_python-0.0.4/benchmarks/scenarios/quick.toml +11 -0
- nab_python-0.0.4/benchmarks/scenarios/rip-lowest-direct.toml +121 -0
- nab_python-0.0.4/benchmarks/scenarios/rip-lowest.toml +121 -0
- nab_python-0.0.4/benchmarks/scenarios/rip.toml +109 -0
- nab_python-0.0.4/benchmarks/scenarios/universal.toml +351 -0
- nab_python-0.0.4/benchmarks/scenarios/unsupported-lowest-direct.toml +215 -0
- nab_python-0.0.4/benchmarks/scenarios/unsupported-lowest.toml +215 -0
- nab_python-0.0.4/benchmarks/scenarios/unsupported.toml +204 -0
- nab_python-0.0.4/benchmarks/scenarios/uv-lowest-direct.toml +1764 -0
- nab_python-0.0.4/benchmarks/scenarios/uv-lowest.toml +1764 -0
- nab_python-0.0.4/benchmarks/scenarios/uv.toml +1640 -0
- nab_python-0.0.4/benchmarks/scenarios.py +685 -0
- nab_python-0.0.4/benchmarks/strategy_sweep.py +365 -0
- nab_python-0.0.4/benchmarks/strategy_sweep_results/summary.json +21931 -0
- nab_python-0.0.4/benchmarks/strategy_sweep_summary.py +147 -0
- nab_python-0.0.4/benchmarks/universal_scenarios.py +262 -0
- nab_python-0.0.4/benchmarks/universal_summary.py +49 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/pyproject.toml +4 -4
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_build/env.py +1 -1
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_build/runner.py +14 -3
- nab_python-0.0.4/src/nab_python/_conflict_kind.py +20 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_lockfile/builder.py +222 -27
- nab_python-0.0.4/src/nab_python/_lockfile/disjointness.py +407 -0
- nab_python-0.0.4/src/nab_python/_lockfile/pylock.py +588 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_lockfile/requirements.py +8 -7
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_provider/extras.py +7 -7
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_provider/listing.py +29 -9
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_provider/metadata_resolver.py +31 -13
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_provider/sources.py +3 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_testing/coordinator_fake.py +17 -6
- nab_python-0.0.4/src/nab_python/_toml.py +16 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/PROVENANCE.md +2 -2
- nab_python-0.0.4/src/nab_python/_vendor/packaging/_range_utils.py +998 -0
- nab_python-0.0.4/src/nab_python/_vendor/packaging/_version_utils.py +90 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/metadata.py +19 -4
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/pylock.py +1 -0
- nab_python-0.0.4/src/nab_python/_vendor/packaging/ranges.py +2112 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/specifiers.py +436 -121
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/tags.py +8 -6
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/config.py +647 -9
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/download.py +39 -9
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/fetch.py +60 -15
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/lockfile.py +88 -2
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/metadata.py +23 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/provider.py +82 -33
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/requirements_file.py +129 -15
- nab_python-0.0.4/src/nab_python/resolve.py +926 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/universal/matrix.py +130 -33
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/universal/provider.py +20 -5
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/universal/reresolve.py +1 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/universal/resolve.py +266 -34
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/universal/validate.py +8 -15
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/universal/wheel_selection.py +92 -57
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/workspace.py +8 -2
- nab_python-0.0.4/tests/__init__.py +1 -0
- nab_python-0.0.4/tests/property_python/__init__.py +0 -0
- nab_python-0.0.4/tests/property_python/strategies.py +205 -0
- nab_python-0.0.4/tests/property_python/test_extras_pep685.py +288 -0
- nab_python-0.0.4/tests/property_python/test_lockfile_pep751.py +486 -0
- nab_python-0.0.4/tests/property_python/test_marker_overlay.py +135 -0
- nab_python-0.0.4/tests/property_python/test_multi_index_pep503.py +207 -0
- nab_python-0.0.4/tests/property_python/test_resolver_pep440.py +189 -0
- nab_python-0.0.4/tests/ruff.toml +30 -0
- nab_python-0.0.4/tests/test_async_transports.py +460 -0
- nab_python-0.0.4/tests/test_build_backend.py +360 -0
- nab_python-0.0.4/tests/test_build_runner.py +925 -0
- nab_python-0.0.4/tests/test_cache.py +260 -0
- nab_python-0.0.4/tests/test_cached_client.py +948 -0
- nab_python-0.0.4/tests/test_config.py +1860 -0
- nab_python-0.0.4/tests/test_download.py +371 -0
- nab_python-0.0.4/tests/test_fetch.py +1167 -0
- nab_python-0.0.4/tests/test_local_index.py +350 -0
- nab_python-0.0.4/tests/test_lockfile.py +3020 -0
- nab_python-0.0.4/tests/test_metadata.py +105 -0
- nab_python-0.0.4/tests/test_multi_index.py +273 -0
- nab_python-0.0.4/tests/test_provider.py +4775 -0
- nab_python-0.0.4/tests/test_requirements_file.py +407 -0
- nab_python-0.0.4/tests/test_resolve.py +2534 -0
- nab_python-0.0.4/tests/test_resolver_packaging.py +503 -0
- nab_python-0.0.4/tests/test_simple_client_filenames.py +107 -0
- nab_python-0.0.4/tests/test_simple_client_hashes.py +25 -0
- nab_python-0.0.4/tests/test_vcs.py +515 -0
- nab_python-0.0.4/tests/test_vcs_admission.py +283 -0
- nab_python-0.0.4/tests/test_workspace.py +354 -0
- nab_python-0.0.4/tests/universal/__init__.py +0 -0
- nab_python-0.0.4/tests/universal/property_universal/__init__.py +0 -0
- nab_python-0.0.4/tests/universal/property_universal/strategies.py +41 -0
- nab_python-0.0.4/tests/universal/property_universal/test_alignment.py +229 -0
- nab_python-0.0.4/tests/universal/property_universal/test_matrix.py +302 -0
- nab_python-0.0.4/tests/universal/property_universal/test_provider_pep425.py +248 -0
- nab_python-0.0.4/tests/universal/property_universal/test_validate.py +143 -0
- nab_python-0.0.4/tests/universal/test_matrix.py +519 -0
- nab_python-0.0.4/tests/universal/test_reresolve.py +391 -0
- nab_python-0.0.4/tests/universal/test_resolve.py +1375 -0
- nab_python-0.0.4/tests/universal/test_universal_provider.py +554 -0
- nab_python-0.0.4/tests/universal/test_validate.py +951 -0
- nab_python-0.0.4/tests/universal/test_wheel_selection.py +461 -0
- nab_python-0.0.2/LICENSE +0 -21
- nab_python-0.0.2/src/nab_python/_lockfile/disjointness.py +0 -207
- nab_python-0.0.2/src/nab_python/_lockfile/pylock.py +0 -323
- nab_python-0.0.2/src/nab_python/_vendor/packaging/ranges.py +0 -1803
- nab_python-0.0.2/src/nab_python/resolve.py +0 -497
- {nab_python-0.0.2 → nab_python-0.0.4}/README.md +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/__init__.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_build/__init__.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_build/errors.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_lockfile/__init__.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_packaging_provider.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_provider/__init__.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_provider/build_remote.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_provider/lookahead.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_provider/priority.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_testing/__init__.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vcs_admission.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/__init__.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/LICENSE +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/LICENSE.APACHE +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/LICENSE.BSD +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/__init__.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/_elffile.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/_manylinux.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/_musllinux.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/_parser.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/_structures.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/_tokenizer.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/dependency_groups.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/direct_url.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/errors.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/licenses/__init__.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/licenses/_spdx.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/markers.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/py.typed +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/requirements.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/utils.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/_vendor/packaging/version.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/build_backend.py +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/py.typed +0 -0
- {nab_python-0.0.2 → nab_python-0.0.4}/src/nab_python/universal/__init__.py +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
*.egg-info/
|
|
4
|
+
dist/
|
|
5
|
+
build/
|
|
6
|
+
.pytest_cache/
|
|
7
|
+
.hypothesis/
|
|
8
|
+
.coverage*
|
|
9
|
+
.ruff_cache/
|
|
10
|
+
.hatch/
|
|
11
|
+
docs/_build/
|
|
12
|
+
|
|
13
|
+
*token*.txt
|
|
14
|
+
*.pypirc
|
|
15
|
+
.pypirc
|
|
16
|
+
|
|
17
|
+
# Profiling artefacts. By convention these live in `profiling/` at
|
|
18
|
+
# the workspace root and never inside `docs/`, so the Sphinx build
|
|
19
|
+
# never has to scan them.
|
|
20
|
+
profiling/
|
nab_python-0.0.4/LICENSE
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../LICENSE
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nab-python
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: Index-backed provider, lockfile emitter, and downloader for nab
|
|
5
5
|
Project-URL: Homepage, https://github.com/notatallshaw/nab
|
|
6
6
|
Project-URL: Documentation, https://nab.readthedocs.io/
|
|
7
7
|
Project-URL: Issues, https://github.com/notatallshaw/nab/issues
|
|
8
8
|
Project-URL: Source, https://github.com/notatallshaw/nab
|
|
9
|
-
Project-URL: Changelog, https://github.com/notatallshaw/nab/
|
|
9
|
+
Project-URL: Changelog, https://github.com/notatallshaw/nab/releases
|
|
10
10
|
Author-email: Damian Shaw <damian.peter.shaw@gmail.com>
|
|
11
11
|
License-Expression: MIT
|
|
12
12
|
License-File: LICENSE
|
|
@@ -20,8 +20,8 @@ Classifier: Typing :: Typed
|
|
|
20
20
|
Requires-Python: >=3.10
|
|
21
21
|
Requires-Dist: build>=1.2
|
|
22
22
|
Requires-Dist: installer>=0.7
|
|
23
|
-
Requires-Dist: nab-index==0.0.
|
|
24
|
-
Requires-Dist: nab-resolver==0.0.
|
|
23
|
+
Requires-Dist: nab-index==0.0.4
|
|
24
|
+
Requires-Dist: nab-resolver==0.0.4
|
|
25
25
|
Requires-Dist: pyproject-hooks>=1.2
|
|
26
26
|
Requires-Dist: tomli-w>=1.2
|
|
27
27
|
Requires-Dist: tomli>=2.0
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Benchmarks
|
|
2
|
+
|
|
3
|
+
nab ships two benchmark suites that exercise the single-environment
|
|
4
|
+
and the universal resolver against real-world scenarios.
|
|
5
|
+
|
|
6
|
+
## Single-environment scenarios
|
|
7
|
+
|
|
8
|
+
`nab-python/benchmarks/scenarios.py` runs scenarios drawn from
|
|
9
|
+
real-world resolver issues across pip, uv, poetry, pex, and
|
|
10
|
+
pip-tools. Scenario TOML files live under
|
|
11
|
+
`nab-python/benchmarks/scenarios/`.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
python nab-python/benchmarks/scenarios.py
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The runner records wall-clock, decision-count, and round-count
|
|
18
|
+
metrics, and writes a JSON summary under
|
|
19
|
+
`nab-python/benchmarks/results/<commit>/`.
|
|
20
|
+
|
|
21
|
+
## Universal-resolution scenarios
|
|
22
|
+
|
|
23
|
+
`nab-python/benchmarks/universal_scenarios.py` runs
|
|
24
|
+
universal-resolution scenarios sourced from public uv/poetry/pex
|
|
25
|
+
slowness reports. The cases stress cross-tuple alignment, marker
|
|
26
|
+
divergence, and pre-release handling.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
python nab-python/benchmarks/universal_scenarios.py
|
|
30
|
+
python nab-python/benchmarks/universal_summary.py
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`universal_summary.py` walks the latest results directory and
|
|
34
|
+
prints a markdown table.
|
|
35
|
+
|
|
36
|
+
## Scenario shape
|
|
37
|
+
|
|
38
|
+
Each scenario is a top-level TOML table keyed by name, with at least
|
|
39
|
+
`requirements` and a fixed `datetime` (used as the
|
|
40
|
+
`uploaded-prior-to` cutoff). Optional knobs include constraints,
|
|
41
|
+
marker overlay, dist policy, and build policy.
|
|
42
|
+
|
|
43
|
+
## What the suites cover
|
|
44
|
+
|
|
45
|
+
* Tight version-cluster cases (e.g. boto3, awscli).
|
|
46
|
+
* Conflict graphs that have hit pip's default resolver budget
|
|
47
|
+
(numpy/scipy/scikit-learn matrices).
|
|
48
|
+
* Universal-mode fork-explosion cases (xinference, vllm,
|
|
49
|
+
ultralytics, copick).
|
|
50
|
+
|
|
51
|
+
The suites are diagnostic harnesses that flag regressions on pull
|
|
52
|
+
requests. Walltime is noisy; decision count and round count are
|
|
53
|
+
the load-bearing numbers.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
r"""Single-scenario profiling runner.
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
# sampling profiler (requires .venv-3.15)
|
|
5
|
+
.venv-3.15/bin/python -m profiling.sampling run -r 5khz --flamegraph \
|
|
6
|
+
-o profile.html nab-python/benchmarks/_profile_runner.py <scenario>
|
|
7
|
+
|
|
8
|
+
# cProfile (any venv)
|
|
9
|
+
python nab-python/benchmarks/_profile_runner.py <scenario> --cprofile
|
|
10
|
+
|
|
11
|
+
<scenario> is a bare name (first TOML match wins) or ``toml_stem:name``,
|
|
12
|
+
e.g. ``pip-lowest:cburroughs-v3``.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import argparse
|
|
18
|
+
import cProfile
|
|
19
|
+
import pstats
|
|
20
|
+
import sys
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
if sys.version_info >= (3, 11):
|
|
24
|
+
import tomllib
|
|
25
|
+
else:
|
|
26
|
+
import tomli as tomllib # type: ignore[no-redef]
|
|
27
|
+
|
|
28
|
+
sys.path.insert(0, str(Path(__file__).parent))
|
|
29
|
+
|
|
30
|
+
import scenarios as sc
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def find_scenario(spec: str) -> tuple[str, dict]:
|
|
34
|
+
if ":" in spec:
|
|
35
|
+
toml_stem, name = spec.split(":", 1)
|
|
36
|
+
toml_path = sc.SCENARIOS_DIR / f"{toml_stem}.toml"
|
|
37
|
+
try:
|
|
38
|
+
with toml_path.open("rb") as f:
|
|
39
|
+
data = tomllib.load(f)
|
|
40
|
+
except FileNotFoundError:
|
|
41
|
+
sys.exit(f"no TOML file for stem {toml_stem!r}")
|
|
42
|
+
if name not in data:
|
|
43
|
+
sys.exit(f"scenario {name!r} not found in {toml_stem}.toml")
|
|
44
|
+
return name, data[name]
|
|
45
|
+
for path in sorted(sc.SCENARIOS_DIR.glob("*.toml")):
|
|
46
|
+
with path.open("rb") as f:
|
|
47
|
+
data = tomllib.load(f)
|
|
48
|
+
if spec in data:
|
|
49
|
+
return spec, data[spec]
|
|
50
|
+
sys.exit(f"scenario {spec!r} not found")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def build_inputs(name: str, scenario: dict) -> dict:
|
|
54
|
+
python_version = scenario["python_version"]
|
|
55
|
+
requirement_strings = list(scenario["requirements"])
|
|
56
|
+
constraint_strings = scenario.get("constraints", [])
|
|
57
|
+
marker_environment = sc.parse_marker_environment(name, scenario)
|
|
58
|
+
build_policy_overrides = sc.parse_build_packages(name, scenario)
|
|
59
|
+
|
|
60
|
+
# BUILD_REMOTE + marker_environment overlay is unsupported; drop overrides.
|
|
61
|
+
if marker_environment and build_policy_overrides:
|
|
62
|
+
build_policy_overrides = {}
|
|
63
|
+
|
|
64
|
+
resolution_strategy = sc.ResolutionStrategy(scenario.get("resolution", "highest"))
|
|
65
|
+
vcs_config = sc.VcsConfig(
|
|
66
|
+
policy=sc.VcsPolicy(scenario.get("vcs_policy", "block")),
|
|
67
|
+
allowed_schemes=frozenset(scenario.get("vcs_allowed_schemes", [])),
|
|
68
|
+
allowed_repos=tuple(scenario.get("vcs_allowed_repos", [])),
|
|
69
|
+
require_pin=scenario.get("vcs_require_pin", True),
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
if scenario.get("project_name"):
|
|
73
|
+
requirement_strings += sc.expand_project_extras(
|
|
74
|
+
scenario["project_name"],
|
|
75
|
+
scenario.get("project_extras", []),
|
|
76
|
+
scenario.get("optional_dependencies", {}),
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
marker_env = sc.scenario_marker_env(python_version, marker_environment)
|
|
80
|
+
requirements = sc.parse_requirements(
|
|
81
|
+
requirement_strings, vcs_config=vcs_config, marker_environment=marker_env
|
|
82
|
+
)
|
|
83
|
+
constraints = (
|
|
84
|
+
sc.parse_requirements(
|
|
85
|
+
constraint_strings, vcs_config=vcs_config, marker_environment=marker_env
|
|
86
|
+
)
|
|
87
|
+
if constraint_strings
|
|
88
|
+
else None
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
datetime_str = scenario.get("datetime")
|
|
92
|
+
return {
|
|
93
|
+
"requirements": requirements,
|
|
94
|
+
"python_version": python_version,
|
|
95
|
+
"uploaded_prior_to": sc.parse_datetime(datetime_str) if datetime_str else None,
|
|
96
|
+
"constraints": constraints,
|
|
97
|
+
"marker_environment": marker_environment or None,
|
|
98
|
+
"indexes": sc.parse_indexes(name, scenario),
|
|
99
|
+
"index_overrides": sc.parse_index_overrides(name, scenario) or None,
|
|
100
|
+
"build_policy_overrides": build_policy_overrides or None,
|
|
101
|
+
"resolution_strategy": resolution_strategy,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def report(name: str, data: dict) -> None:
|
|
106
|
+
stats = data["stats"]
|
|
107
|
+
state = "OK" if data["result"]["success"] else f"FAIL {data['result']['error']}"
|
|
108
|
+
print(
|
|
109
|
+
f"{name}: {state} in {stats['wall_time_seconds']}s, "
|
|
110
|
+
f"{stats['decisions']} decisions, {stats['conflicts']} conflicts"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def main() -> None:
|
|
115
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
116
|
+
parser.add_argument("scenario", help="bare name or toml_stem:name")
|
|
117
|
+
parser.add_argument(
|
|
118
|
+
"--cprofile",
|
|
119
|
+
action="store_true",
|
|
120
|
+
help="profile in-process and print the top functions by self time",
|
|
121
|
+
)
|
|
122
|
+
parser.add_argument("--limit", type=int, default=30)
|
|
123
|
+
args = parser.parse_args()
|
|
124
|
+
|
|
125
|
+
name, scenario = find_scenario(args.scenario)
|
|
126
|
+
inputs = build_inputs(name, scenario)
|
|
127
|
+
|
|
128
|
+
if not args.cprofile:
|
|
129
|
+
report(name, sc.resolve_scenario(**inputs))
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
profiler = cProfile.Profile()
|
|
133
|
+
data = profiler.runcall(sc.resolve_scenario, **inputs)
|
|
134
|
+
report(name, data)
|
|
135
|
+
pstats.Stats(profiler).sort_stats("tottime").print_stats(args.limit)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
if __name__ == "__main__":
|
|
139
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*
|