pytest-balance 0.1.0__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.
- pytest_balance-0.1.0/.commitlintrc.yml +2 -0
- pytest_balance-0.1.0/.github/workflows/ci.yml +115 -0
- pytest_balance-0.1.0/.github/workflows/release.yml +115 -0
- pytest_balance-0.1.0/.gitignore +33 -0
- pytest_balance-0.1.0/CHANGELOG.md +77 -0
- pytest_balance-0.1.0/LICENSE +21 -0
- pytest_balance-0.1.0/Makefile +28 -0
- pytest_balance-0.1.0/PKG-INFO +358 -0
- pytest_balance-0.1.0/README.md +325 -0
- pytest_balance-0.1.0/cliff.toml +58 -0
- pytest_balance-0.1.0/pyproject.toml +98 -0
- pytest_balance-0.1.0/src/pytest_balance/__init__.py +3 -0
- pytest_balance-0.1.0/src/pytest_balance/__main__.py +5 -0
- pytest_balance-0.1.0/src/pytest_balance/algorithms/__init__.py +0 -0
- pytest_balance-0.1.0/src/pytest_balance/algorithms/lpt.py +68 -0
- pytest_balance-0.1.0/src/pytest_balance/algorithms/partitioner.py +62 -0
- pytest_balance-0.1.0/src/pytest_balance/ci/__init__.py +0 -0
- pytest_balance-0.1.0/src/pytest_balance/ci/detect.py +209 -0
- pytest_balance-0.1.0/src/pytest_balance/ci/splitter.py +46 -0
- pytest_balance-0.1.0/src/pytest_balance/cli.py +367 -0
- pytest_balance-0.1.0/src/pytest_balance/plugin.py +255 -0
- pytest_balance-0.1.0/src/pytest_balance/py.typed +0 -0
- pytest_balance-0.1.0/src/pytest_balance/report.py +64 -0
- pytest_balance-0.1.0/src/pytest_balance/store/__init__.py +0 -0
- pytest_balance-0.1.0/src/pytest_balance/store/merger.py +53 -0
- pytest_balance-0.1.0/src/pytest_balance/store/models.py +41 -0
- pytest_balance-0.1.0/src/pytest_balance/store/reader.py +94 -0
- pytest_balance-0.1.0/src/pytest_balance/store/writer.py +53 -0
- pytest_balance-0.1.0/src/pytest_balance/xdist/__init__.py +0 -0
- pytest_balance-0.1.0/src/pytest_balance/xdist/hooks.py +37 -0
- pytest_balance-0.1.0/src/pytest_balance/xdist/scheduler.py +154 -0
- pytest_balance-0.1.0/tests/__init__.py +0 -0
- pytest_balance-0.1.0/tests/conftest.py +1 -0
- pytest_balance-0.1.0/tests/test_algorithms/__init__.py +0 -0
- pytest_balance-0.1.0/tests/test_algorithms/test_lpt.py +121 -0
- pytest_balance-0.1.0/tests/test_algorithms/test_partitioner.py +61 -0
- pytest_balance-0.1.0/tests/test_ci/__init__.py +0 -0
- pytest_balance-0.1.0/tests/test_ci/test_detect.py +116 -0
- pytest_balance-0.1.0/tests/test_ci/test_splitter.py +67 -0
- pytest_balance-0.1.0/tests/test_cli.py +158 -0
- pytest_balance-0.1.0/tests/test_plugin.py +186 -0
- pytest_balance-0.1.0/tests/test_report.py +39 -0
- pytest_balance-0.1.0/tests/test_store/__init__.py +0 -0
- pytest_balance-0.1.0/tests/test_store/test_merger.py +85 -0
- pytest_balance-0.1.0/tests/test_store/test_models.py +65 -0
- pytest_balance-0.1.0/tests/test_store/test_reader.py +103 -0
- pytest_balance-0.1.0/tests/test_store/test_writer.py +70 -0
- pytest_balance-0.1.0/tests/test_xdist/__init__.py +0 -0
- pytest_balance-0.1.0/tests/test_xdist/_simulator.py +212 -0
- pytest_balance-0.1.0/tests/test_xdist/test_scheduler.py +392 -0
- pytest_balance-0.1.0/tests/test_xdist/test_scheduler_stateful.py +39 -0
- pytest_balance-0.1.0/uv.lock +531 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
permissions: {}
|
|
4
|
+
|
|
5
|
+
concurrency:
|
|
6
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
7
|
+
cancel-in-progress: true
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
push:
|
|
11
|
+
branches: [main]
|
|
12
|
+
pull_request:
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
commitlint:
|
|
16
|
+
name: Commit messages
|
|
17
|
+
if: github.event_name == 'pull_request'
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
23
|
+
with:
|
|
24
|
+
fetch-depth: 0
|
|
25
|
+
- uses: wagoid/commitlint-github-action@f133a0d95090ef2609192b4a21f54e20af819ea9 # v6
|
|
26
|
+
|
|
27
|
+
format:
|
|
28
|
+
name: Format
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
permissions:
|
|
31
|
+
contents: read
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
34
|
+
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
|
|
35
|
+
with:
|
|
36
|
+
enable-cache: true
|
|
37
|
+
- run: uv sync
|
|
38
|
+
- run: uv run ruff format --check src tests
|
|
39
|
+
|
|
40
|
+
lint:
|
|
41
|
+
name: Lint
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
permissions:
|
|
44
|
+
contents: read
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
47
|
+
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
|
|
48
|
+
with:
|
|
49
|
+
enable-cache: true
|
|
50
|
+
- run: uv sync
|
|
51
|
+
- run: uv run ruff check src tests
|
|
52
|
+
|
|
53
|
+
lock:
|
|
54
|
+
name: Lockfile
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
permissions:
|
|
57
|
+
contents: read
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
60
|
+
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
|
|
61
|
+
with:
|
|
62
|
+
enable-cache: true
|
|
63
|
+
- run: uv lock --check
|
|
64
|
+
|
|
65
|
+
typecheck:
|
|
66
|
+
name: Typecheck
|
|
67
|
+
runs-on: ubuntu-latest
|
|
68
|
+
permissions:
|
|
69
|
+
contents: read
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
72
|
+
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
|
|
73
|
+
with:
|
|
74
|
+
enable-cache: true
|
|
75
|
+
- run: uv sync
|
|
76
|
+
- run: uv run mypy src
|
|
77
|
+
|
|
78
|
+
test:
|
|
79
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
permissions:
|
|
82
|
+
contents: read
|
|
83
|
+
strategy:
|
|
84
|
+
fail-fast: false
|
|
85
|
+
matrix:
|
|
86
|
+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
87
|
+
steps:
|
|
88
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
89
|
+
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
|
|
90
|
+
with:
|
|
91
|
+
enable-cache: true
|
|
92
|
+
- run: uv sync --python ${{ matrix.python-version }}
|
|
93
|
+
- run: uv run pytest --cov --cov-report=xml --tb=short
|
|
94
|
+
if: matrix.python-version == '3.14'
|
|
95
|
+
- run: uv run pytest --tb=short
|
|
96
|
+
if: matrix.python-version != '3.14'
|
|
97
|
+
- uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe # v5
|
|
98
|
+
if: matrix.python-version == '3.14'
|
|
99
|
+
with:
|
|
100
|
+
files: coverage.xml
|
|
101
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
102
|
+
fail_ci_if_error: false
|
|
103
|
+
|
|
104
|
+
test-without-xdist:
|
|
105
|
+
name: Test (without xdist)
|
|
106
|
+
runs-on: ubuntu-latest
|
|
107
|
+
permissions:
|
|
108
|
+
contents: read
|
|
109
|
+
steps:
|
|
110
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
111
|
+
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
|
|
112
|
+
with:
|
|
113
|
+
enable-cache: true
|
|
114
|
+
- run: uv sync --no-group dev
|
|
115
|
+
- run: uv run pytest --tb=short -k "not test_xdist"
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
permissions: {}
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: false
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
ci-check:
|
|
15
|
+
name: CI Gate
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
timeout-minutes: 10
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
22
|
+
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
|
|
23
|
+
with:
|
|
24
|
+
enable-cache: true
|
|
25
|
+
|
|
26
|
+
- name: Verify tag matches package version
|
|
27
|
+
env:
|
|
28
|
+
TAG_REF: ${{ github.ref }}
|
|
29
|
+
run: |
|
|
30
|
+
TAG="${TAG_REF#refs/tags/v}"
|
|
31
|
+
PY_VER=$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
|
|
32
|
+
echo "Tag: $TAG | pyproject: $PY_VER"
|
|
33
|
+
if [ "$TAG" != "$PY_VER" ]; then
|
|
34
|
+
echo "::error::Tag v$TAG does not match pyproject.toml version $PY_VER"
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
- run: uv sync
|
|
39
|
+
- run: uv run ruff format --check src tests
|
|
40
|
+
- run: uv run ruff check src tests
|
|
41
|
+
- run: uv run mypy src
|
|
42
|
+
- run: uv run pytest --tb=short
|
|
43
|
+
|
|
44
|
+
build:
|
|
45
|
+
name: Build package
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
timeout-minutes: 5
|
|
48
|
+
permissions:
|
|
49
|
+
contents: read
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
52
|
+
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
|
|
53
|
+
- run: uv build
|
|
54
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
55
|
+
with:
|
|
56
|
+
name: dist
|
|
57
|
+
path: dist/
|
|
58
|
+
|
|
59
|
+
publish:
|
|
60
|
+
name: Publish to PyPI
|
|
61
|
+
needs: [build, ci-check]
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
timeout-minutes: 5
|
|
64
|
+
environment: PyPI
|
|
65
|
+
permissions:
|
|
66
|
+
id-token: write
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
69
|
+
with:
|
|
70
|
+
name: dist
|
|
71
|
+
path: dist/
|
|
72
|
+
- uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
|
|
73
|
+
with:
|
|
74
|
+
attestations: true
|
|
75
|
+
|
|
76
|
+
release:
|
|
77
|
+
name: GitHub Release
|
|
78
|
+
needs: [build, ci-check]
|
|
79
|
+
runs-on: ubuntu-latest
|
|
80
|
+
timeout-minutes: 5
|
|
81
|
+
permissions:
|
|
82
|
+
contents: write
|
|
83
|
+
steps:
|
|
84
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
85
|
+
with:
|
|
86
|
+
fetch-depth: 0
|
|
87
|
+
|
|
88
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
89
|
+
with:
|
|
90
|
+
name: dist
|
|
91
|
+
path: dist/
|
|
92
|
+
|
|
93
|
+
- name: Generate checksums
|
|
94
|
+
run: |
|
|
95
|
+
cd dist
|
|
96
|
+
sha256sum * > SHA256SUMS
|
|
97
|
+
|
|
98
|
+
- name: Generate release notes
|
|
99
|
+
id: cliff
|
|
100
|
+
uses: orhun/git-cliff-action@c93ef52f3d0ddcdcc9bd5447d98d458a11cd4f72 # v4
|
|
101
|
+
with:
|
|
102
|
+
config: cliff.toml
|
|
103
|
+
args: --latest --strip header
|
|
104
|
+
env:
|
|
105
|
+
GITHUB_REPO: ${{ github.repository }}
|
|
106
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
107
|
+
|
|
108
|
+
- uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
|
|
109
|
+
with:
|
|
110
|
+
body: ${{ steps.cliff.outputs.content }}
|
|
111
|
+
prerelease: ${{ contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc') }}
|
|
112
|
+
files: |
|
|
113
|
+
dist/*.whl
|
|
114
|
+
dist/*.tar.gz
|
|
115
|
+
dist/SHA256SUMS
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.egg-info/
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
|
|
9
|
+
# Tool caches (pytest, mypy, ruff)
|
|
10
|
+
.cache/
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
|
|
15
|
+
# Duration store
|
|
16
|
+
.balance/
|
|
17
|
+
|
|
18
|
+
# IDE
|
|
19
|
+
.idea/
|
|
20
|
+
.vscode/
|
|
21
|
+
*.swp
|
|
22
|
+
|
|
23
|
+
# OS
|
|
24
|
+
.DS_Store
|
|
25
|
+
|
|
26
|
+
# Coverage
|
|
27
|
+
.coverage
|
|
28
|
+
|
|
29
|
+
# Review
|
|
30
|
+
.full-review/
|
|
31
|
+
|
|
32
|
+
# Ongoing documentation
|
|
33
|
+
docs/
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.1.0] - 2026-06-15
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **store:** Estimate from call-phase durations only
|
|
9
|
+
- **store:** Dedup merged records per phase
|
|
10
|
+
- **plugin:** Set outcome on recorded durations
|
|
11
|
+
- **store:** Record test outcome in durations
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [0.1.0a3] - 2026-06-10
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- **cli:** Add --alpha to the standalone plan command
|
|
18
|
+
- **cli:** Expose --balance-ema-alpha to the ema estimator
|
|
19
|
+
- **cli:** Validate the EMA alpha range
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- **store:** Name the default EMA alpha constant
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
## [0.1.0a2] - 2026-06-09
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
- **algorithms:** Add LPT compute_order
|
|
30
|
+
- **xdist:** Record scheduling history for invariant diagnostics
|
|
31
|
+
- **xdist:** Fail loud on scheduler bookkeeping invariant
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
- **xdist:** Subclass WorkStealingScheduling
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## [0.1.0a1] - 2026-04-09
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
- Add release workflow, changelog config, and commit linting
|
|
42
|
+
- **xdist:** Add duration-aware scheduler with work-stealing
|
|
43
|
+
- Add plugin core with CI splitting and duration recording
|
|
44
|
+
- Add post-run balance report
|
|
45
|
+
- **ci:** Add duration-aware CI test splitter
|
|
46
|
+
- **ci:** Add CI environment auto-detection
|
|
47
|
+
- **store:** Add JSONL merger with dedup
|
|
48
|
+
- **store:** Add JSONL reader with EMA/median/last estimation
|
|
49
|
+
- **store:** Add JSONL duration writer
|
|
50
|
+
- **algorithms:** Add scope-aware test partitioner
|
|
51
|
+
- **algorithms:** Add LPT partitioning algorithm
|
|
52
|
+
- **store:** Add TestDuration and DurationEstimate models
|
|
53
|
+
- Initialize project scaffolding
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
### Changed
|
|
57
|
+
- Fix warnings, naming, and scheduler performance
|
|
58
|
+
- Defer plugin imports to reduce pytest startup overhead
|
|
59
|
+
- Stream JSONL reads to reduce memory usage
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
- **xdist:** Initialize numnodes from tx spec config
|
|
64
|
+
- Correct README CI file patterns and sanitize run_id
|
|
65
|
+
- Align build config and clean up project metadata
|
|
66
|
+
- Address critical review findings
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
[0.1.0]: https://github.com/ggueret/pytest-balance/compare/v0.1.0a3...v0.1.0
|
|
71
|
+
|
|
72
|
+
[0.1.0a3]: https://github.com/ggueret/pytest-balance/compare/v0.1.0a2...v0.1.0a3
|
|
73
|
+
|
|
74
|
+
[0.1.0a2]: https://github.com/ggueret/pytest-balance/compare/v0.1.0a1...v0.1.0a2
|
|
75
|
+
|
|
76
|
+
[0.1.0a1]: https://github.com/ggueret/pytest-balance/tree/v0.1.0a1
|
|
77
|
+
<!-- generated by git-cliff -->
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Geoffrey Guéret
|
|
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,28 @@
|
|
|
1
|
+
.PHONY: install lint typecheck test format check all clean
|
|
2
|
+
|
|
3
|
+
install:
|
|
4
|
+
uv sync
|
|
5
|
+
|
|
6
|
+
lint:
|
|
7
|
+
uv run ruff check src tests
|
|
8
|
+
|
|
9
|
+
typecheck:
|
|
10
|
+
uv run mypy src
|
|
11
|
+
|
|
12
|
+
test:
|
|
13
|
+
uv run pytest
|
|
14
|
+
|
|
15
|
+
format:
|
|
16
|
+
uv run ruff format src tests
|
|
17
|
+
uv run ruff check --fix src tests
|
|
18
|
+
|
|
19
|
+
check:
|
|
20
|
+
uv run ruff format --check src tests
|
|
21
|
+
uv run ruff check src tests
|
|
22
|
+
uv run mypy src
|
|
23
|
+
|
|
24
|
+
all: lint typecheck test
|
|
25
|
+
|
|
26
|
+
clean:
|
|
27
|
+
rm -rf .cache .coverage htmlcov dist build *.egg-info
|
|
28
|
+
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|