contractme 2.4.1__tar.gz → 2.4.2__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.
- {contractme-2.4.1 → contractme-2.4.2}/.gitlab-ci.yml +26 -0
- {contractme-2.4.1 → contractme-2.4.2}/CHANGELOG.md +11 -0
- {contractme-2.4.1 → contractme-2.4.2}/CLAUDE.md +4 -0
- {contractme-2.4.1 → contractme-2.4.2}/PKG-INFO +4 -2
- {contractme-2.4.1 → contractme-2.4.2}/README.md +3 -1
- {contractme-2.4.1 → contractme-2.4.2}/justfile +5 -0
- {contractme-2.4.1 → contractme-2.4.2}/pyproject.toml +6 -2
- contractme-2.4.2/release_notes.md +8 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/contracting.py +13 -7
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_contracting.py +22 -1
- contractme-2.4.2/tox.ini +21 -0
- {contractme-2.4.1 → contractme-2.4.2}/uv.lock +186 -13
- contractme-2.4.1/release_notes.md +0 -12
- {contractme-2.4.1 → contractme-2.4.2}/.flake8 +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/.gitignore +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/.pre-commit-config.yaml +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/.python-version +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/.vscode/settings.json +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/LICENSE +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/context7.json +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/docs/comparison-facts.yaml +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/docs/comparison.md +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/docs/types.md +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/release/prerelease.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/release/pypi_mint_token.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/release/release_notes.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/__init__.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/annotations.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/config.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/policy.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/probing.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/py.typed +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/records.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/result.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/skills/contractme/SKILL.md +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/testing.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/typecheck.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/types/__init__.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/types/containers.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/types/data.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/types/identifiers.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/types/network.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/types/numeric.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/types/paths.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/types/predicates.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/types/system.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/types/temporal.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/types/text.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/src/contractme/typeshape.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/conftest.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_annotations.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_annotations_future.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_async.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_canaries.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_contracting_optimized_python.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_evaluation_order.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_hypothesis.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_hypothesis_async.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_layering.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_literal.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_optimized_policy.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_policy.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_predicate_source.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_probing.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_records.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_reentrancy.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_show_source.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_typechecks.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_types.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_types_advanced.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_types_extra.py +0 -0
- {contractme-2.4.1 → contractme-2.4.2}/tests/test_typeshape.py +0 -0
|
@@ -44,6 +44,7 @@ stages:
|
|
|
44
44
|
- pyproject.toml
|
|
45
45
|
- uv.lock
|
|
46
46
|
- justfile
|
|
47
|
+
- tox.ini
|
|
47
48
|
- .flake8
|
|
48
49
|
- .gitlab-ci.yml
|
|
49
50
|
when: always
|
|
@@ -128,6 +129,31 @@ checks-optimized:
|
|
|
128
129
|
reports:
|
|
129
130
|
junit: obj/tests_report_optimized.xml
|
|
130
131
|
|
|
132
|
+
# Python 3.14: one extra job runs both version-sensitive gates
|
|
133
|
+
# (coverage + the -O run) through tox; lint and types stay on 3.13 in `checks`.
|
|
134
|
+
# UV_PYTHON makes the outer `uv run` use the image's interpreter instead of
|
|
135
|
+
# downloading .python-version's 3.13. A draft MR tolerates failures here, like
|
|
136
|
+
# the lax mode of `checks`.
|
|
137
|
+
checks-py314:
|
|
138
|
+
extends: .uv
|
|
139
|
+
stage: test
|
|
140
|
+
interruptible: true
|
|
141
|
+
variables:
|
|
142
|
+
PYTHON_VERSION: "3.14"
|
|
143
|
+
UV_PYTHON: "3.14"
|
|
144
|
+
rules:
|
|
145
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TITLE =~ /^(draft|wip):/i
|
|
146
|
+
changes: *code-paths
|
|
147
|
+
allow_failure: true
|
|
148
|
+
- !reference [.on-code-change, rules]
|
|
149
|
+
script:
|
|
150
|
+
- uv run just tox -e py314
|
|
151
|
+
artifacts:
|
|
152
|
+
reports:
|
|
153
|
+
junit:
|
|
154
|
+
- obj/py314/tests_report.xml
|
|
155
|
+
- obj/py314/tests_report_optimized.xml
|
|
156
|
+
|
|
131
157
|
# Validate the tag against pyproject + CHANGELOG, extract the release notes,
|
|
132
158
|
# then build dists.
|
|
133
159
|
build:
|
|
@@ -7,6 +7,17 @@ section whose heading matches the tag via
|
|
|
7
7
|
and GitLab release description — so every `## vX.Y.Z` heading must match its
|
|
8
8
|
tag exactly.
|
|
9
9
|
|
|
10
|
+
## v2.4.2
|
|
11
|
+
|
|
12
|
+
* On Python 3.14, `@annotated` stacked over `@precondition` (or any contracted function
|
|
13
|
+
passed to `typing.get_type_hints`) works again: it raised
|
|
14
|
+
`NameError: name 'ClassVar' is not defined` at decoration since v2.4.0
|
|
15
|
+
([#104](https://gitlab.com/leogermond/contractme/-/issues/104)).
|
|
16
|
+
* The test suite runs on Python 3.13 and 3.14, locally (`just tox`) and in CI
|
|
17
|
+
([9b69657](https://gitlab.com/leogermond/contractme/-/commit/9b69657)).
|
|
18
|
+
* `just types` installs pyright with its bundled node, so a broken nodeenv no longer fails CI
|
|
19
|
+
([51e80c6](https://gitlab.com/leogermond/contractme/-/commit/51e80c6)).
|
|
20
|
+
|
|
10
21
|
## v2.4.1
|
|
11
22
|
|
|
12
23
|
* A failed `Predicate` constraint is named by its source when it is a lambda
|
|
@@ -24,6 +24,10 @@ just test-optimized # differential run: contracts compiled out via -O, valid-p
|
|
|
24
24
|
# behavior must be identical (mirrors the checks-optimized CI
|
|
25
25
|
# job). Contract-violation tests skip themselves via
|
|
26
26
|
# tests/conftest.py:contract_violation().
|
|
27
|
+
just tox [args...] # cov + test-optimized on Python 3.13 and 3.14 (tox.ini, tox-uv:
|
|
28
|
+
# each env synced from uv.lock's dev group); mirrors the
|
|
29
|
+
# checks-py314 CI job:
|
|
30
|
+
# just tox -e py314 -- -x
|
|
27
31
|
just fmt # format code (black)
|
|
28
32
|
just lint # black --check + flake8
|
|
29
33
|
just types # type checking (pinned pyright from the dev deps — matches CI)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: contractme
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.2
|
|
4
4
|
Summary: Executable specifications for python. Keep control of the code AI writes for you.
|
|
5
5
|
Project-URL: Repository, https://gitlab.com/leogermond/contractme
|
|
6
6
|
Author-email: Leo Germond <leo.germond@gmail.com>
|
|
@@ -495,7 +495,9 @@ cost nothing where it matters.
|
|
|
495
495
|
`just test`
|
|
496
496
|
|
|
497
497
|
Dev commands are `just` recipes — bare `just` lists them; `just check` runs the
|
|
498
|
-
full local gate (tests + coverage, the `-O` differential run, lint, types)
|
|
498
|
+
full local gate (tests + coverage, the `-O` differential run, lint, types); `just tox`
|
|
499
|
+
runs the version-sensitive gates (coverage, the `-O` run) on every supported Python
|
|
500
|
+
(3.13, 3.14).
|
|
499
501
|
|
|
500
502
|
# Deploy new version
|
|
501
503
|
|
|
@@ -476,7 +476,9 @@ cost nothing where it matters.
|
|
|
476
476
|
`just test`
|
|
477
477
|
|
|
478
478
|
Dev commands are `just` recipes — bare `just` lists them; `just check` runs the
|
|
479
|
-
full local gate (tests + coverage, the `-O` differential run, lint, types)
|
|
479
|
+
full local gate (tests + coverage, the `-O` differential run, lint, types); `just tox`
|
|
480
|
+
runs the version-sensitive gates (coverage, the `-O` run) on every supported Python
|
|
481
|
+
(3.13, 3.14).
|
|
480
482
|
|
|
481
483
|
# Deploy new version
|
|
482
484
|
|
|
@@ -24,6 +24,11 @@ cov *args:
|
|
|
24
24
|
test-optimized *args:
|
|
25
25
|
uv run python -O -m pytest -W ignore::pytest.PytestConfigWarning "$@"
|
|
26
26
|
|
|
27
|
+
# Envs and args pass through to tox (e.g. `just tox -e py314 -- -x`); see tox.ini.
|
|
28
|
+
[doc('Coverage gate + -O differential run on every supported Python (3.13, 3.14)')]
|
|
29
|
+
tox *args:
|
|
30
|
+
uv run tox "$@"
|
|
31
|
+
|
|
27
32
|
# Format the code (black, line length 100)
|
|
28
33
|
fmt:
|
|
29
34
|
uv run black .
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "contractme"
|
|
3
|
-
version = "2.4.
|
|
3
|
+
version = "2.4.2"
|
|
4
4
|
description = "Executable specifications for python. Keep control of the code AI writes for you."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -30,7 +30,9 @@ build-backend = "hatchling.build"
|
|
|
30
30
|
[dependency-groups]
|
|
31
31
|
dev = [
|
|
32
32
|
"epycs>=1.4.0",
|
|
33
|
-
|
|
33
|
+
# [nodejs] ships node as a wheel: pyright's nodeenv fallback crashes on
|
|
34
|
+
# some node release listings (CI image has no node of its own)
|
|
35
|
+
"pyright[nodejs]==1.1.407",
|
|
34
36
|
"pytest>=8.3.5",
|
|
35
37
|
"pytest-cov>=6.0.0",
|
|
36
38
|
"black>=25.9.0",
|
|
@@ -42,6 +44,8 @@ dev = [
|
|
|
42
44
|
"croniter>=2.0.0",
|
|
43
45
|
"pycountry>=23.12.11",
|
|
44
46
|
"pyyaml>=6.0",
|
|
47
|
+
"tox>=4.67.12",
|
|
48
|
+
"tox-uv>=1.37.5",
|
|
45
49
|
]
|
|
46
50
|
|
|
47
51
|
[tool.pytest.ini_options]
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
* On Python 3.14, `@annotated` stacked over `@precondition` (or any contracted function
|
|
2
|
+
passed to `typing.get_type_hints`) works again: it raised
|
|
3
|
+
`NameError: name 'ClassVar' is not defined` at decoration since v2.4.0
|
|
4
|
+
([#104](https://gitlab.com/leogermond/contractme/-/issues/104)).
|
|
5
|
+
* The test suite runs on Python 3.13 and 3.14, locally (`just tox`) and in CI
|
|
6
|
+
([9b69657](https://gitlab.com/leogermond/contractme/-/commit/9b69657)).
|
|
7
|
+
* `just types` installs pyright with its bundled node, so a broken nodeenv no longer fails CI
|
|
8
|
+
([51e80c6](https://gitlab.com/leogermond/contractme/-/commit/51e80c6)).
|
|
@@ -34,7 +34,6 @@ from contextvars import ContextVar
|
|
|
34
34
|
from itertools import accumulate, islice
|
|
35
35
|
from typing import (
|
|
36
36
|
Callable,
|
|
37
|
-
ClassVar,
|
|
38
37
|
NamedTuple,
|
|
39
38
|
Protocol,
|
|
40
39
|
Self,
|
|
@@ -379,15 +378,19 @@ def get_kw_for_postcondition_after(result, conditional: Callable) -> dict:
|
|
|
379
378
|
|
|
380
379
|
|
|
381
380
|
class _ContractWrapper[**F_Params, F_Ret]:
|
|
382
|
-
"""The engine's contracted-callable wrapper (the non-``optimized`` path).
|
|
381
|
+
"""The engine's contracted-callable wrapper (the non-``optimized`` path).
|
|
382
|
+
|
|
383
|
+
Its annotations are the wrapped function's, as for any ``functools.wraps``
|
|
384
|
+
wrapper (issue #104): the class body declares no annotation, since a class
|
|
385
|
+
``__annotations__`` dict is what an instance attribute lookup finds first —
|
|
386
|
+
on Python 3.14, where ``update_wrapper`` copies ``__annotate__`` instead of
|
|
387
|
+
``__annotations__``, ``get_type_hints`` would read the class's own hints
|
|
388
|
+
instead. Its attributes are declared in ``__init__``, invisible at runtime."""
|
|
383
389
|
|
|
384
|
-
# set by `functools.update_wrapper` in `__init__`
|
|
385
|
-
__name__: str
|
|
386
|
-
__qualname__: str
|
|
387
390
|
# a class-level mark, out of reach of `functools.wraps` (which copies the
|
|
388
391
|
# instance `__dict__`): how `config.no_contracts` recognises the engine's
|
|
389
|
-
# wrapper without importing it (issue #74)
|
|
390
|
-
contractme_engine_wrapper
|
|
392
|
+
# wrapper without importing it (issue #74); unannotated, see the docstring
|
|
393
|
+
contractme_engine_wrapper = True
|
|
391
394
|
|
|
392
395
|
def __init__(
|
|
393
396
|
self,
|
|
@@ -398,6 +401,9 @@ class _ContractWrapper[**F_Params, F_Ret]:
|
|
|
398
401
|
accepts: F_Pred,
|
|
399
402
|
rejects: F_Pred,
|
|
400
403
|
):
|
|
404
|
+
# set by `functools.update_wrapper`
|
|
405
|
+
self.__name__: str
|
|
406
|
+
self.__qualname__: str
|
|
401
407
|
functools.update_wrapper(self, original_call)
|
|
402
408
|
self.call_and_run_contracts = call_and_run_contracts
|
|
403
409
|
self.contractme_wrapped = original_call
|
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
# These tests exercise the raw pre/postcondition machinery on purpose; don't take them
|
|
4
4
|
# as the recommended style.
|
|
5
5
|
import functools
|
|
6
|
+
from typing import get_type_hints
|
|
6
7
|
|
|
7
8
|
import pytest
|
|
8
9
|
from conftest import contract_violation
|
|
9
10
|
import contractme
|
|
10
|
-
from contractme import precondition, postcondition
|
|
11
|
+
from contractme import annotated, precondition, postcondition
|
|
11
12
|
from contractme.contracting import ContractedFunction
|
|
12
13
|
import math
|
|
13
14
|
|
|
@@ -470,6 +471,26 @@ def test_contracted_function_names_itself_like_a_function():
|
|
|
470
471
|
assert isinstance(step, ContractedFunction)
|
|
471
472
|
|
|
472
473
|
|
|
474
|
+
def test_contracted_function_has_the_wrapped_type_hints():
|
|
475
|
+
# issue #104: on Python 3.14, `get_type_hints` read the wrapper class's own
|
|
476
|
+
# annotations, evaluated in the wrapped function's globals (NameError)
|
|
477
|
+
def step(x: int, label: str = "") -> int:
|
|
478
|
+
return x
|
|
479
|
+
|
|
480
|
+
contracted = precondition(lambda x: x > 0)(step)
|
|
481
|
+
assert get_type_hints(contracted, include_extras=True) == get_type_hints(step)
|
|
482
|
+
# `@annotated` stacked over `@precondition` reads those hints at decoration time
|
|
483
|
+
assert annotated(contracted)(1) == 1
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
def test_contracted_function_class_declares_no_runtime_annotation():
|
|
487
|
+
# issue #104, on every Python version: a class annotation is what an instance
|
|
488
|
+
# attribute lookup of `__annotations__` finds once `update_wrapper` copies only
|
|
489
|
+
# `__annotate__` (Python 3.14) — the wrapper's hints must be the wrapped function's
|
|
490
|
+
contracted = precondition(lambda x: x > 0)(lambda x: x)
|
|
491
|
+
assert get_type_hints(type(contracted)) == {}
|
|
492
|
+
|
|
493
|
+
|
|
473
494
|
def test_cannot_have_precondition_of_a_constructor():
|
|
474
495
|
with pytest.raises(RuntimeError):
|
|
475
496
|
|
contractme-2.4.2/tox.ini
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# The version-sensitive gates, once per supported Python: `just tox` (all envs)
|
|
2
|
+
# or `just tox -e py314`. Lint and types stay single-version (`just check`).
|
|
3
|
+
[tox]
|
|
4
|
+
env_list = py313, py314
|
|
5
|
+
requires = tox-uv>=1.37
|
|
6
|
+
# obj/ is already ignored by git, black and flake8; the dot hides it from pyright
|
|
7
|
+
work_dir = {tox_root}/obj/.tox
|
|
8
|
+
|
|
9
|
+
[testenv]
|
|
10
|
+
# installs uv.lock's `dev` group into the env (uv sync), no duplicated dep list
|
|
11
|
+
runner = uv-venv-lock-runner
|
|
12
|
+
dependency_groups = dev
|
|
13
|
+
pass_env = UV_*
|
|
14
|
+
# the recipes' `uv run` reuses this env as tox synced it (UV_PROJECT_ENVIRONMENT
|
|
15
|
+
# is set by tox-uv); a resync would rebuild it on .python-version's 3.13
|
|
16
|
+
set_env = UV_NO_SYNC = 1
|
|
17
|
+
# no fail-fast, like `just check`: the -O run still reports when cov fails
|
|
18
|
+
ignore_errors = true
|
|
19
|
+
commands =
|
|
20
|
+
just cov --junitxml=obj/{env_name}/tests_report.xml {posargs}
|
|
21
|
+
just test-optimized --junitxml=obj/{env_name}/tests_report_optimized.xml {posargs}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
version = 1
|
|
2
|
-
revision =
|
|
2
|
+
revision = 5
|
|
3
3
|
requires-python = ">=3.13"
|
|
4
4
|
|
|
5
5
|
[[package]]
|
|
@@ -41,6 +41,15 @@ wheels = [
|
|
|
41
41
|
{ url = "https://files.pythonhosted.org/packages/1b/46/863c90dcd3f9d41b109b7f19032ae0db021f0b2a81482ba0a1e28c84de86/black-25.9.0-py3-none-any.whl", hash = "sha256:474b34c1342cdc157d307b56c4c65bce916480c4a8f6551fdc6bf9b486a7c4ae", size = 203363, upload-time = "2025-09-19T00:27:35.724Z" },
|
|
42
42
|
]
|
|
43
43
|
|
|
44
|
+
[[package]]
|
|
45
|
+
name = "cachetools"
|
|
46
|
+
version = "7.3.0"
|
|
47
|
+
source = { registry = "https://pypi.org/simple" }
|
|
48
|
+
sdist = { url = "https://files.pythonhosted.org/packages/5f/6b/6c1553e1e8f672f9423344a1915aad1537439ad3d14a3fbc1a02159cfd94/cachetools-7.3.0.tar.gz", hash = "sha256:3f63fc208410f0c3a3b37883c4903ecdacd6f0b259134e6d2e82debd5b2e01de", size = 48563, upload-time = "2026-11-05T20:38:46.434Z" }
|
|
49
|
+
wheels = [
|
|
50
|
+
{ url = "https://files.pythonhosted.org/packages/29/aa/e54a49d0927b2fa7b86bc94dbde57125e38e8cfca7a31b6764e8dbf35e9f/cachetools-7.3.0-py3-none-any.whl", hash = "sha256:2105787c94619bde7072624fec0fe7b8a08bb7bf6c757c318f8925573c6f07c9", size = 19575, upload-time = "2026-11-05T20:38:44.928Z" },
|
|
51
|
+
]
|
|
52
|
+
|
|
44
53
|
[[package]]
|
|
45
54
|
name = "click"
|
|
46
55
|
version = "8.3.0"
|
|
@@ -64,7 +73,7 @@ wheels = [
|
|
|
64
73
|
|
|
65
74
|
[[package]]
|
|
66
75
|
name = "contractme"
|
|
67
|
-
version = "2.4.
|
|
76
|
+
version = "2.4.2"
|
|
68
77
|
source = { editable = "." }
|
|
69
78
|
dependencies = [
|
|
70
79
|
{ name = "annotated-types" },
|
|
@@ -89,11 +98,13 @@ dev = [
|
|
|
89
98
|
{ name = "epycs" },
|
|
90
99
|
{ name = "flake8" },
|
|
91
100
|
{ name = "pycountry" },
|
|
92
|
-
{ name = "pyright" },
|
|
101
|
+
{ name = "pyright", extra = ["nodejs"] },
|
|
93
102
|
{ name = "pytest" },
|
|
94
103
|
{ name = "pytest-cov" },
|
|
95
104
|
{ name = "pyyaml" },
|
|
96
105
|
{ name = "rust-just" },
|
|
106
|
+
{ name = "tox" },
|
|
107
|
+
{ name = "tox-uv" },
|
|
97
108
|
]
|
|
98
109
|
|
|
99
110
|
[package.metadata]
|
|
@@ -113,11 +124,13 @@ dev = [
|
|
|
113
124
|
{ name = "epycs", specifier = ">=1.4.0" },
|
|
114
125
|
{ name = "flake8", specifier = ">=7.2.0" },
|
|
115
126
|
{ name = "pycountry", specifier = ">=23.12.11" },
|
|
116
|
-
{ name = "pyright", specifier = "==1.1.407" },
|
|
127
|
+
{ name = "pyright", extras = ["nodejs"], specifier = "==1.1.407" },
|
|
117
128
|
{ name = "pytest", specifier = ">=8.3.5" },
|
|
118
129
|
{ name = "pytest-cov", specifier = ">=6.0.0" },
|
|
119
130
|
{ name = "pyyaml", specifier = ">=6.0" },
|
|
120
131
|
{ name = "rust-just", specifier = ">=1.34" },
|
|
132
|
+
{ name = "tox", specifier = ">=4.67.12" },
|
|
133
|
+
{ name = "tox-uv", specifier = ">=1.37.5" },
|
|
121
134
|
]
|
|
122
135
|
|
|
123
136
|
[[package]]
|
|
@@ -161,6 +174,15 @@ wheels = [
|
|
|
161
174
|
{ url = "https://files.pythonhosted.org/packages/d0/39/783980e78cb92c2d7bdb1fc7dbc86e94ccc6d58224d76a7f1f51b6c51e30/croniter-6.2.2-py3-none-any.whl", hash = "sha256:a5d17b1060974d36251ea4faf388233eca8acf0d09cbd92d35f4c4ac8f279960", size = 45422, upload-time = "2026-03-15T08:43:46.626Z" },
|
|
162
175
|
]
|
|
163
176
|
|
|
177
|
+
[[package]]
|
|
178
|
+
name = "distlib"
|
|
179
|
+
version = "0.4.4"
|
|
180
|
+
source = { registry = "https://pypi.org/simple" }
|
|
181
|
+
sdist = { url = "https://files.pythonhosted.org/packages/68/bc/d36966de7304047a1001a7559fbf266c464bb5d8cc85464536ef8c9bcc32/distlib-0.4.4.tar.gz", hash = "sha256:ca4175b4ac7f71223cc30ed7248c45d2b38c2439d8ee6e498ab67ed63cf3508d", size = 621304, upload-time = "2026-10-16T13:56:34.203Z" }
|
|
182
|
+
wheels = [
|
|
183
|
+
{ url = "https://files.pythonhosted.org/packages/c1/2b/238f02a4927fa2e27aa995371d240a468b52e42eae44a678434aff736b38/distlib-0.4.4-py2.py3-none-any.whl", hash = "sha256:cf09d55b1e85a89576b036aeb71550bfd68320f3f21761ca329eadadad918638", size = 472099, upload-time = "2026-10-16T13:56:32.053Z" },
|
|
184
|
+
]
|
|
185
|
+
|
|
164
186
|
[[package]]
|
|
165
187
|
name = "epycs"
|
|
166
188
|
version = "1.5.0"
|
|
@@ -170,6 +192,15 @@ wheels = [
|
|
|
170
192
|
{ url = "https://files.pythonhosted.org/packages/50/01/aa81bef60e1aa2ce606ba7c86f7119ed6e1e3bf30a9e8b33a507681847c8/epycs-1.5.0-py3-none-any.whl", hash = "sha256:79a99b197eb251f80fd0a42bb54404e170c030e0df3698402f4037ac07ce9878", size = 10452, upload-time = "2025-03-23T14:25:43.476Z" },
|
|
171
193
|
]
|
|
172
194
|
|
|
195
|
+
[[package]]
|
|
196
|
+
name = "filelock"
|
|
197
|
+
version = "4.2.9"
|
|
198
|
+
source = { registry = "https://pypi.org/simple" }
|
|
199
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a3/1d/d730c664fcb4f1d264a722722a3134cf0881854f73c1fd58abf87572f232/filelock-4.2.9.tar.gz", hash = "sha256:96530b7c538d4ea08493ab067247aab7948c54d8cd622cce711c97cccc5d9896", size = 663116, upload-time = "2026-11-04T18:37:10.014Z" }
|
|
200
|
+
wheels = [
|
|
201
|
+
{ url = "https://files.pythonhosted.org/packages/00/05/76184fe08339723d643ab47887a8e4de8f2921ca4e008617ab7490af7857/filelock-4.2.9-py3-none-any.whl", hash = "sha256:a379c50a729e5b68c8519a4d26489f755d9769960a236ecd838190e2a78db2e9", size = 164734, upload-time = "2026-11-04T18:37:08.273Z" },
|
|
202
|
+
]
|
|
203
|
+
|
|
173
204
|
[[package]]
|
|
174
205
|
name = "flake8"
|
|
175
206
|
version = "7.3.0"
|
|
@@ -233,13 +264,29 @@ wheels = [
|
|
|
233
264
|
{ url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" },
|
|
234
265
|
]
|
|
235
266
|
|
|
267
|
+
[[package]]
|
|
268
|
+
name = "nodejs-wheel-binaries"
|
|
269
|
+
version = "24.19.0"
|
|
270
|
+
source = { registry = "https://pypi.org/simple" }
|
|
271
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c0/76/7e97195e14346598565a0de4ca8bdbd5e634b3fb5b1ba590b7b1b89f8a63/nodejs_wheel_binaries-24.19.0.tar.gz", hash = "sha256:db217eef8cab8551667863379b08db4d9067403f6cbbe87481eb40edceb8aa9b", size = 8058, upload-time = "2026-08-19T21:47:19.671Z" }
|
|
272
|
+
wheels = [
|
|
273
|
+
{ url = "https://files.pythonhosted.org/packages/8c/52/0774b52c7be8151ad9d5aff44edc100c3f13d6d8eb3765f63ffa40e69fe8/nodejs_wheel_binaries-24.19.0-py2.py3-none-macosx_13_0_arm64.whl", hash = "sha256:e12cbfd69089504e42fb14194ce734a9dcf3eb38c820ca63dd511d36fb964e9c", size = 56047203, upload-time = "2026-08-19T21:46:43.448Z" },
|
|
274
|
+
{ url = "https://files.pythonhosted.org/packages/67/3a/4fdbbfecf2c23d52c0e3f68de7f7c1b3c97a26d328c69c5f6c49c48e340e/nodejs_wheel_binaries-24.19.0-py2.py3-none-macosx_13_0_x86_64.whl", hash = "sha256:1c890adf4b7e6556ccc1ca66c866bb81884b6c9a581dee4e530dc7f78fb9d514", size = 56219459, upload-time = "2026-08-19T21:46:48.45Z" },
|
|
275
|
+
{ url = "https://files.pythonhosted.org/packages/5f/a8/0147149415195c59b8a72a594916bfb80d6be4d586f9fbfda313889e0efc/nodejs_wheel_binaries-24.19.0-py2.py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:4e029dadfae1295876063c96b236f673487e8c27379fe146c1e2250283520227", size = 60588256, upload-time = "2026-08-19T21:46:53.298Z" },
|
|
276
|
+
{ url = "https://files.pythonhosted.org/packages/f4/89/6631d0982353da1bb7bc00bb1988f702822c62b42634f57999ee53b5c337/nodejs_wheel_binaries-24.19.0-py2.py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:4196a947bcc883f2003ab101762d729f3e99b5e86b75bd09151563403e2eceb8", size = 61123607, upload-time = "2026-08-19T21:46:58.117Z" },
|
|
277
|
+
{ url = "https://files.pythonhosted.org/packages/32/a2/fa30f0841e4602995782e124359f9b910c7b481d98decf61ef0b2fc3ebfb/nodejs_wheel_binaries-24.19.0-py2.py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:352e048ab4dd35e7de5f338d1cc4fcbf77a0e93da30bf7336a8217ee246b31d7", size = 62632842, upload-time = "2026-08-19T21:47:03.42Z" },
|
|
278
|
+
{ url = "https://files.pythonhosted.org/packages/18/01/22d97ca72213f66cc386ee638db30c2e62757fdf761c6029074bced83d1c/nodejs_wheel_binaries-24.19.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:28d078b2ced9e2069516e652dc4b1380e7a1a7f2d3934eccd1611586d283ba4c", size = 63250653, upload-time = "2026-08-19T21:47:07.938Z" },
|
|
279
|
+
{ url = "https://files.pythonhosted.org/packages/88/d1/e3be8fa327a795bcaf7a19cd84299e338a7bce32ff0665fdce9cfa22573c/nodejs_wheel_binaries-24.19.0-py2.py3-none-win_amd64.whl", hash = "sha256:67e3abeb9c3830cae8c8487ae8a2af7cc27dfa75af06145cee5ca7d1857c81bd", size = 42448503, upload-time = "2026-08-19T21:47:12.093Z" },
|
|
280
|
+
{ url = "https://files.pythonhosted.org/packages/1d/37/34cf28ba1691a060174948a9927fe61091982d6048b2e403071a9acce443/nodejs_wheel_binaries-24.19.0-py2.py3-none-win_arm64.whl", hash = "sha256:d9074c665ea68b04e183d82482c86dc907d3a9bd15eb6cf85542cb785266bb36", size = 40090155, upload-time = "2026-08-19T21:47:16.032Z" },
|
|
281
|
+
]
|
|
282
|
+
|
|
236
283
|
[[package]]
|
|
237
284
|
name = "packaging"
|
|
238
|
-
version = "
|
|
285
|
+
version = "26.3"
|
|
239
286
|
source = { registry = "https://pypi.org/simple" }
|
|
240
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
287
|
+
sdist = { url = "https://files.pythonhosted.org/packages/7d/fa/3944b40b07da9ce895c0e6303a5ab7d53da063554f534556b134a54d6093/packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", size = 313412, upload-time = "2026-08-04T18:15:28.737Z" }
|
|
241
288
|
wheels = [
|
|
242
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
289
|
+
{ url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956, upload-time = "2026-08-04T18:15:27.159Z" },
|
|
243
290
|
]
|
|
244
291
|
|
|
245
292
|
[[package]]
|
|
@@ -253,20 +300,20 @@ wheels = [
|
|
|
253
300
|
|
|
254
301
|
[[package]]
|
|
255
302
|
name = "platformdirs"
|
|
256
|
-
version = "4.5
|
|
303
|
+
version = "4.14.5"
|
|
257
304
|
source = { registry = "https://pypi.org/simple" }
|
|
258
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
305
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d7/9a/8475be631fb33ca1466915e70fd594c42a4e84b512db650eaa14f90fe75d/platformdirs-4.14.5.tar.gz", hash = "sha256:32e9921db7385aa8169bee4fe9501923e5715ba9fb7ea3b9c69b0d8e0639f7a1", size = 71464, upload-time = "2026-11-04T16:54:50.358Z" }
|
|
259
306
|
wheels = [
|
|
260
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
307
|
+
{ url = "https://files.pythonhosted.org/packages/7c/ae/ecbbbfd0e4343a6a521d49b3c8656fb4643dee2a4f6eaf941cf3280391a8/platformdirs-4.14.5-py3-none-any.whl", hash = "sha256:8e778c6fa421516f4d3369449f8df3b0e1b72c0e0005fe88e3ec772d0a14e750", size = 35402, upload-time = "2026-11-04T16:54:48.875Z" },
|
|
261
308
|
]
|
|
262
309
|
|
|
263
310
|
[[package]]
|
|
264
311
|
name = "pluggy"
|
|
265
|
-
version = "1.
|
|
312
|
+
version = "1.7.0"
|
|
266
313
|
source = { registry = "https://pypi.org/simple" }
|
|
267
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
314
|
+
sdist = { url = "https://files.pythonhosted.org/packages/bf/db/7fc19e6f2dc92a966727031389fc2e08b558f0f25eb7403c1119ad4713cd/pluggy-1.7.0.tar.gz", hash = "sha256:d1eaa46ebb595891b860ab086b4d09c8588af65ebd4361b8e8f4bb8920b90ba8", size = 123304, upload-time = "2026-10-15T09:50:58.343Z" }
|
|
268
315
|
wheels = [
|
|
269
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
316
|
+
{ url = "https://files.pythonhosted.org/packages/40/9e/2b38731e0fc536806f16490e1a12d7f0dc2a1235aa8cc07bcc75416a7daa/pluggy-1.7.0-py3-none-any.whl", hash = "sha256:7dd7b0d8832ba3cb632c306926ded123429211b83641b35dc5c41ad2d34f9bec", size = 27082, upload-time = "2026-10-15T09:50:56.808Z" },
|
|
270
317
|
]
|
|
271
318
|
|
|
272
319
|
[[package]]
|
|
@@ -296,6 +343,18 @@ wheels = [
|
|
|
296
343
|
{ url = "https://files.pythonhosted.org/packages/c2/2f/81d580a0fb83baeb066698975cb14a618bdbed7720678566f1b046a95fe8/pyflakes-3.4.0-py2.py3-none-any.whl", hash = "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f", size = 63551, upload-time = "2025-06-20T18:45:26.937Z" },
|
|
297
344
|
]
|
|
298
345
|
|
|
346
|
+
[[package]]
|
|
347
|
+
name = "pyproject-api"
|
|
348
|
+
version = "1.12.4"
|
|
349
|
+
source = { registry = "https://pypi.org/simple" }
|
|
350
|
+
dependencies = [
|
|
351
|
+
{ name = "packaging" },
|
|
352
|
+
]
|
|
353
|
+
sdist = { url = "https://files.pythonhosted.org/packages/7b/10/806fcc3ddb672150199bf769af4c90016654829b02f039c3d58f23a08fb7/pyproject_api-1.12.4.tar.gz", hash = "sha256:79d0584a851fc945150715fa7871b0d72f48000e848b2298193d160cc18b3c89", size = 67794, upload-time = "2026-11-04T07:34:27.978Z" }
|
|
354
|
+
wheels = [
|
|
355
|
+
{ url = "https://files.pythonhosted.org/packages/2e/32/06e1a59b084b1cebdbb3ffc2b440396c6d43956820684ccd12e6afbdfd14/pyproject_api-1.12.4-py3-none-any.whl", hash = "sha256:5cb6235adb84998753e3b37d50820391854a6a967914b08051fc8f534a1c12b0", size = 14385, upload-time = "2026-11-04T07:34:26.518Z" },
|
|
356
|
+
]
|
|
357
|
+
|
|
299
358
|
[[package]]
|
|
300
359
|
name = "pyright"
|
|
301
360
|
version = "1.1.407"
|
|
@@ -309,6 +368,11 @@ wheels = [
|
|
|
309
368
|
{ url = "https://files.pythonhosted.org/packages/dc/93/b69052907d032b00c40cb656d21438ec00b3a471733de137a3f65a49a0a0/pyright-1.1.407-py3-none-any.whl", hash = "sha256:6dd419f54fcc13f03b52285796d65e639786373f433e243f8b94cf93a7444d21", size = 5997008, upload-time = "2025-10-24T23:17:13.159Z" },
|
|
310
369
|
]
|
|
311
370
|
|
|
371
|
+
[package.optional-dependencies]
|
|
372
|
+
nodejs = [
|
|
373
|
+
{ name = "nodejs-wheel-binaries" },
|
|
374
|
+
]
|
|
375
|
+
|
|
312
376
|
[[package]]
|
|
313
377
|
name = "pytest"
|
|
314
378
|
version = "8.3.5"
|
|
@@ -349,6 +413,18 @@ wheels = [
|
|
|
349
413
|
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
|
|
350
414
|
]
|
|
351
415
|
|
|
416
|
+
[[package]]
|
|
417
|
+
name = "python-discovery"
|
|
418
|
+
version = "1.9.4"
|
|
419
|
+
source = { registry = "https://pypi.org/simple" }
|
|
420
|
+
dependencies = [
|
|
421
|
+
{ name = "filelock" },
|
|
422
|
+
]
|
|
423
|
+
sdist = { url = "https://files.pythonhosted.org/packages/0f/d7/1e94df7d1636bf00b9f261bf88a4adc0414f14931ff60511eb0f34c250d1/python_discovery-1.9.4.tar.gz", hash = "sha256:c01b45fe515c1d268b57c57d554bb0e1d320b8e9eb5490bb2f4f577be26e4380", size = 140385, upload-time = "2026-11-04T05:25:52.097Z" }
|
|
424
|
+
wheels = [
|
|
425
|
+
{ url = "https://files.pythonhosted.org/packages/c5/44/b248f3b1a23f44d8de172e2767748082c41cbd9353009af72f4b11b00afa/python_discovery-1.9.4-py3-none-any.whl", hash = "sha256:b468f365040b40f4cb39918b0766d3e5a2f340968e07df752fbc96f1bb4641ab", size = 44220, upload-time = "2026-11-04T05:25:50.514Z" },
|
|
426
|
+
]
|
|
427
|
+
|
|
352
428
|
[[package]]
|
|
353
429
|
name = "pytokens"
|
|
354
430
|
version = "0.1.10"
|
|
@@ -436,6 +512,61 @@ wheels = [
|
|
|
436
512
|
{ url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" },
|
|
437
513
|
]
|
|
438
514
|
|
|
515
|
+
[[package]]
|
|
516
|
+
name = "tomli-w"
|
|
517
|
+
version = "1.2.0"
|
|
518
|
+
source = { registry = "https://pypi.org/simple" }
|
|
519
|
+
sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184, upload-time = "2025-01-15T12:07:24.262Z" }
|
|
520
|
+
wheels = [
|
|
521
|
+
{ url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675, upload-time = "2025-01-15T12:07:22.074Z" },
|
|
522
|
+
]
|
|
523
|
+
|
|
524
|
+
[[package]]
|
|
525
|
+
name = "tox"
|
|
526
|
+
version = "4.67.12"
|
|
527
|
+
source = { registry = "https://pypi.org/simple" }
|
|
528
|
+
dependencies = [
|
|
529
|
+
{ name = "cachetools" },
|
|
530
|
+
{ name = "colorama" },
|
|
531
|
+
{ name = "filelock" },
|
|
532
|
+
{ name = "packaging" },
|
|
533
|
+
{ name = "platformdirs" },
|
|
534
|
+
{ name = "pluggy" },
|
|
535
|
+
{ name = "pyproject-api" },
|
|
536
|
+
{ name = "python-discovery" },
|
|
537
|
+
{ name = "tomli-w" },
|
|
538
|
+
{ name = "virtualenv" },
|
|
539
|
+
]
|
|
540
|
+
sdist = { url = "https://files.pythonhosted.org/packages/8c/41/3e3d9dee587244fadd8f4227958a19cf83eb2f5a4df7318fb4e2b19d12bb/tox-4.67.12.tar.gz", hash = "sha256:d94739a6830f8a8b113cc0f95a505bdfd34289a237c70160c8ba785b7fceef6c", size = 424991, upload-time = "2026-11-05T23:31:33.879Z" }
|
|
541
|
+
wheels = [
|
|
542
|
+
{ url = "https://files.pythonhosted.org/packages/6f/8d/20c1fd28ed9b899a518bab1908e519454ea383f588b659627c2f0b5c6c07/tox-4.67.12-py3-none-any.whl", hash = "sha256:d3ba259e8e28d3a2c69219d1aa979acfcc6a031a41d4b5ce099667bb47fccbfb", size = 263266, upload-time = "2026-11-05T23:31:31.905Z" },
|
|
543
|
+
]
|
|
544
|
+
|
|
545
|
+
[[package]]
|
|
546
|
+
name = "tox-uv"
|
|
547
|
+
version = "1.37.5"
|
|
548
|
+
source = { registry = "https://pypi.org/simple" }
|
|
549
|
+
dependencies = [
|
|
550
|
+
{ name = "tox-uv-bare" },
|
|
551
|
+
{ name = "uv" },
|
|
552
|
+
]
|
|
553
|
+
wheels = [
|
|
554
|
+
{ url = "https://files.pythonhosted.org/packages/a5/e4/425b97dbf64516e376a9675e800be0042e15537dff2cd97ab6cfbbdc9291/tox_uv-1.37.5-py3-none-any.whl", hash = "sha256:d74a5c1937a6d0f7498284c3767f95e2e9c0e28e8e2d9c3a6343c8c8b5905fae", size = 7823, upload-time = "2026-11-04T05:48:59.608Z" },
|
|
555
|
+
]
|
|
556
|
+
|
|
557
|
+
[[package]]
|
|
558
|
+
name = "tox-uv-bare"
|
|
559
|
+
version = "1.37.5"
|
|
560
|
+
source = { registry = "https://pypi.org/simple" }
|
|
561
|
+
dependencies = [
|
|
562
|
+
{ name = "packaging" },
|
|
563
|
+
{ name = "tox" },
|
|
564
|
+
]
|
|
565
|
+
sdist = { url = "https://files.pythonhosted.org/packages/51/4f/d8909e69db5697e3eb41d662fd240ae95287e842362c2e9d5c5ec076890d/tox_uv_bare-1.37.5.tar.gz", hash = "sha256:65026a7964c610c84f30f8e7e9d27f69109bcd0e303e31693015be4e8db568bf", size = 34955, upload-time = "2026-11-04T05:49:02.217Z" }
|
|
566
|
+
wheels = [
|
|
567
|
+
{ url = "https://files.pythonhosted.org/packages/70/a6/6585101c4e435c51fe9ca9321562d26322899d99e559465d111699ffaf6d/tox_uv_bare-1.37.5-py3-none-any.whl", hash = "sha256:38a88874153100baf0d2911779e4f928846689a66b0d45fb65dcdb2f0f28ad9d", size = 22793, upload-time = "2026-11-04T05:49:00.778Z" },
|
|
568
|
+
]
|
|
569
|
+
|
|
439
570
|
[[package]]
|
|
440
571
|
name = "typing-extensions"
|
|
441
572
|
version = "4.13.2"
|
|
@@ -444,3 +575,45 @@ sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e3549295
|
|
|
444
575
|
wheels = [
|
|
445
576
|
{ url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" },
|
|
446
577
|
]
|
|
578
|
+
|
|
579
|
+
[[package]]
|
|
580
|
+
name = "uv"
|
|
581
|
+
version = "0.13.7"
|
|
582
|
+
source = { registry = "https://pypi.org/simple" }
|
|
583
|
+
sdist = { url = "https://files.pythonhosted.org/packages/71/73/0021f6679b1b686f2fdb7cb9914a9d953428644e3057b173edc181d1590c/uv-0.13.7.tar.gz", hash = "sha256:5e766791cb825d7a07e2ef9e622d307b48754fb682a31ba7bc5f272fab9ea395", size = 7550003, upload-time = "2026-11-03T02:42:34.944Z" }
|
|
584
|
+
wheels = [
|
|
585
|
+
{ url = "https://files.pythonhosted.org/packages/a6/e8/bda02e68c92b896e2c27581843c461e1007cb68c67c0b357d1e4849e6311/uv-0.13.7-py3-none-linux_armv6l.whl", hash = "sha256:89df450624dec8c48b8b5a7adb654928cc50e95753f869c70cd65ef8333f2197", size = 18121202, upload-time = "2026-11-03T02:41:43.776Z" },
|
|
586
|
+
{ url = "https://files.pythonhosted.org/packages/3d/5b/e0379e7b172659420b1ec99a8e8229830aa85ea59684847c80b1c959a056/uv-0.13.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:fd04bf01ba5f2829f4f94ca8f0c24a743f21e73d75045613ed6fc2fd66fc7bda", size = 17194673, upload-time = "2026-11-03T02:41:46.959Z" },
|
|
587
|
+
{ url = "https://files.pythonhosted.org/packages/40/a5/8756c38ace102fa13fd4e653e8bc40e1f65924f1c0a0d23350339dac97e5/uv-0.13.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f91a229093163eefca89ea1b220a221d64c3beade05d03519a6584d1797a5a5f", size = 14454941, upload-time = "2026-11-03T02:41:50.208Z" },
|
|
588
|
+
{ url = "https://files.pythonhosted.org/packages/96/72/da1119f94034d7173e6c8e2cd77a6299744458f0af3cb8e3a04d5cd419d1/uv-0.13.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:a90f5d95716ab83091f0f73a8e7ec64e557abf2a28537fcd719b2ac88e6f725a", size = 17656749, upload-time = "2026-11-03T02:41:52.729Z" },
|
|
589
|
+
{ url = "https://files.pythonhosted.org/packages/f3/a8/d554d757e372d2dc8788e4c07601e440c09ce31535e3107180690233f4a2/uv-0.13.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:952dcae9b1a7742f2fab28e82391fbfabe8807e4e9363f674b0f6be1053b8dd4", size = 17815154, upload-time = "2026-11-03T02:41:55.393Z" },
|
|
590
|
+
{ url = "https://files.pythonhosted.org/packages/19/db/70ad6aeef83b9566ec1cbfa345a1a976af13413863086aa85809cba16b53/uv-0.13.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:94f65a8ac5826dff76a93cb3cafbaad15def1788c63da2ce5ce09e0bd1303e7a", size = 17827605, upload-time = "2026-11-03T02:41:58.237Z" },
|
|
591
|
+
{ url = "https://files.pythonhosted.org/packages/78/55/fafeedc33a903456e7fd5fa442e7116331451c50e68e6fa985df47c06b3a/uv-0.13.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57ff66891d9a738ec087c23fdde842ac8e5eb63189ffed6ee95caee1b82ceb54", size = 18466549, upload-time = "2026-11-03T02:42:01.031Z" },
|
|
592
|
+
{ url = "https://files.pythonhosted.org/packages/d0/5e/50494a1cac0ff7030edc430c8ac86ee91ca43c54134d399b0f7a137930c7/uv-0.13.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:917733990ebc178318af0321d6873823ed5da707e1c4b1e5060ac2065a81f1f3", size = 19781452, upload-time = "2026-11-03T02:42:03.787Z" },
|
|
593
|
+
{ url = "https://files.pythonhosted.org/packages/28/b2/7fc68c91580168907f557c8824521973a3f63d1e3629ae3478aaeeebef7f/uv-0.13.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1bc8543d930464bbb22ac01bb1a660a448235e558014914de1e1cd5b993361b8", size = 19493895, upload-time = "2026-11-03T02:42:06.604Z" },
|
|
594
|
+
{ url = "https://files.pythonhosted.org/packages/b9/93/0e053a2ca4523ee9825ccbedeb7121470d0a188933f11688b6d90d7f5c08/uv-0.13.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c9bdc4a872b60a93c5f26c0791089ea11585a4f9d3b3c017d78eb8487505e25", size = 17202345, upload-time = "2026-11-03T02:42:09.344Z" },
|
|
595
|
+
{ url = "https://files.pythonhosted.org/packages/cf/c8/2d0da4535b8607cf224023724cbf8d4572d1a3e33c2c9629100af6b522bb/uv-0.13.7-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:08f16fd463926786b702b497473511deae4b3e17a2fa6d22180950d6059a120d", size = 16636343, upload-time = "2026-11-03T02:42:12.122Z" },
|
|
596
|
+
{ url = "https://files.pythonhosted.org/packages/28/3d/e7db43beff8b219ec392346f11b8aad325bc87bb282eea57e64cbe0aba56/uv-0.13.7-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:d30cafb7070901ba35353ec64cf228ae46caf79ac0f6fae329f95468b1482531", size = 18026164, upload-time = "2026-11-03T02:42:14.745Z" },
|
|
597
|
+
{ url = "https://files.pythonhosted.org/packages/7d/85/dc25db684d7e8c8c1c6927d78a29b64c7ef5479e8f17c7a2d1b74af4af21/uv-0.13.7-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:158953b8669bee6f4bc2babdd997e34ff9f0d57170093cfe907f64448292b7c3", size = 17911506, upload-time = "2026-11-03T02:42:17.752Z" },
|
|
598
|
+
{ url = "https://files.pythonhosted.org/packages/04/c3/0ca099ff442fb6a01a59b7582d8733f187183d491bc86e6f96c9203c3e1e/uv-0.13.7-py3-none-musllinux_1_1_i686.whl", hash = "sha256:8fc6019740794df995085f7b278d99dc11ccacffad9c63957278d3a6e272280b", size = 17946690, upload-time = "2026-11-03T02:42:20.53Z" },
|
|
599
|
+
{ url = "https://files.pythonhosted.org/packages/2a/22/065e097ca6051ae7022d7c5c9d1591dcff97ed5609fb9eb450d8ee22fa17/uv-0.13.7-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:8b8ac028ae4ebb2a3f9d04907c61794f2cf8d7a7002bfbb4019a3dee28351fb2", size = 18949870, upload-time = "2026-11-03T02:42:23.574Z" },
|
|
600
|
+
{ url = "https://files.pythonhosted.org/packages/c4/f2/3cfb8543acb8dc07b228d2517a0962b124ab97bd859690617d957248129c/uv-0.13.7-py3-none-win32.whl", hash = "sha256:5f37cc4d4660e4aee8a24d0dc179a0b0ce99506259c6796d37fa69bca9543a03", size = 16094323, upload-time = "2026-11-03T02:42:26.697Z" },
|
|
601
|
+
{ url = "https://files.pythonhosted.org/packages/8e/4f/041b59d2a38807a3e31ef41064cf3e45d2752fe0409d89040d52778049ae/uv-0.13.7-py3-none-win_amd64.whl", hash = "sha256:2835e2ab397d0db86323b9975dce75ecd76aa9cfa0d6a2aea84734aae7f8c9b3", size = 15330939, upload-time = "2026-11-03T02:42:29.422Z" },
|
|
602
|
+
{ url = "https://files.pythonhosted.org/packages/44/8d/1594dce4465d9699467a639b25aafd335ce1e5917f8bb60c9c0bed9e0859/uv-0.13.7-py3-none-win_arm64.whl", hash = "sha256:55e741a380a98008fc4985cf069855f36bc50242ef438e21a466786f5bc84da8", size = 15633037, upload-time = "2026-11-03T02:42:32.095Z" },
|
|
603
|
+
]
|
|
604
|
+
|
|
605
|
+
[[package]]
|
|
606
|
+
name = "virtualenv"
|
|
607
|
+
version = "21.15.5"
|
|
608
|
+
source = { registry = "https://pypi.org/simple" }
|
|
609
|
+
dependencies = [
|
|
610
|
+
{ name = "distlib" },
|
|
611
|
+
{ name = "filelock" },
|
|
612
|
+
{ name = "packaging" },
|
|
613
|
+
{ name = "platformdirs" },
|
|
614
|
+
{ name = "python-discovery" },
|
|
615
|
+
]
|
|
616
|
+
sdist = { url = "https://files.pythonhosted.org/packages/69/74/745e612b69ad14a534b7bc233c4574b968eb2c21a276ea172e8f0fc13f51/virtualenv-21.15.5.tar.gz", hash = "sha256:fb869ea32930530ccc87549877b53268c2a4d4a7d7f2c384042eca05170350e6", size = 5639868, upload-time = "2026-11-04T05:13:20.929Z" }
|
|
617
|
+
wheels = [
|
|
618
|
+
{ url = "https://files.pythonhosted.org/packages/9d/d6/f9ac78f115e32e0d76adda9db72b74425b86495ae274cd7b58c660f5d1c1/virtualenv-21.15.5-py3-none-any.whl", hash = "sha256:bcf98c32139cf3df7f0cc2c8c48ca150645c20e66f8c4fe6c1e5e40bcae73947", size = 5680750, upload-time = "2026-11-04T05:13:19.057Z" },
|
|
619
|
+
]
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
* A failed `Predicate` constraint is named by its source when it is a lambda
|
|
2
|
-
(`Predicate(lambda s: s.islower())`), by its qualified name otherwise, in `type_error`,
|
|
3
|
-
`@record` and the `@annotated` header, where it used to print `<function <lambda> at 0x…>`;
|
|
4
|
-
a lambda with default arguments, or whose source cannot be proven to match, falls back to
|
|
5
|
-
its qualified name ([#80](https://gitlab.com/leogermond/contractme/-/issues/80)).
|
|
6
|
-
* A passing check and every `accepts`/`rejects` probe build no message, unions included:
|
|
7
|
-
the text is written only for the failure that gets reported
|
|
8
|
-
([#80](https://gitlab.com/leogermond/contractme/-/issues/80)).
|
|
9
|
-
* The `@annotated` header lists its constraints as `under constraints [...]`, where it used
|
|
10
|
-
to show a tuple ([#80](https://gitlab.com/leogermond/contractme/-/issues/80)).
|
|
11
|
-
* v2.4.0 never reached PyPI (its CI build failed on the in-project uv cache): v2.4.1 ships
|
|
12
|
-
its changes too, see below ([5739ee2](https://gitlab.com/leogermond/contractme/-/commit/5739ee2)).
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|