Skip to content

Commit 162cf40

Browse files
committed
Factor-based tox + tiered CI + strict type checking
Restructure tox.toml with composable factor scheme: - Runtime: {python}-{beartype}-{backend} (e.g. py312-bt022-numpy24) - Typecheck: {python}-{beartype}-type-{checker} (e.g. py312-bt022-type-pyright1408) - Factor deps via `replace = "if"` + `condition = "factor.*"` in TOML - Generative env_list via product dicts for Cartesian factor combos Split dep groups (optional/static/dev), add strict pyright and mypy configs. Add tox-aware test filtering (conftest.py), env name validation script, tiered CI (PR/push/nightly), and CONTRIBUTING.md.
1 parent 4f3f190 commit 162cf40

File tree

12 files changed

+631
-332
lines changed

12 files changed

+631
-332
lines changed

.github/workflows/ci.yml

Lines changed: 51 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ name: CI
33
on:
44
push:
55
branches: [main]
6-
tags: ["v*"]
76
pull_request:
87

98
concurrency:
@@ -41,7 +40,7 @@ jobs:
4140
steps:
4241
- uses: actions/checkout@v6
4342
- uses: astral-sh/setup-uv@v7
44-
- run: uv run pyright src/
43+
- run: uv run pyright src/ tests/typing/
4544

4645
typecheck-compat:
4746
runs-on: ubuntu-latest
@@ -51,7 +50,7 @@ jobs:
5150
- run: uv run pytest tests/test_typecheck.py -v
5251

5352
# -----------------------------------------------------------------------
54-
# Test — always run (single locked env, default Python)
53+
# Test — always run (locked dev env)
5554
# -----------------------------------------------------------------------
5655

5756
test:
@@ -60,85 +59,84 @@ jobs:
6059
steps:
6160
- uses: actions/checkout@v6
6261
- uses: astral-sh/setup-uv@v7
63-
- run: uv run tox run
62+
- run: uv run tox run -e dev
6463

6564
# -----------------------------------------------------------------------
66-
# Full matrix — only on version tags (v*)
65+
# PR: fast compat matrix
6766
# -----------------------------------------------------------------------
6867

69-
test-matrix:
70-
if: startsWith(github.ref, 'refs/tags/v')
68+
compat-pr:
69+
if: github.event_name == 'pull_request'
7170
needs: [test]
7271
runs-on: ubuntu-latest
7372
strategy:
7473
fail-fast: false
7574
matrix:
76-
env: ["py313", "py314"]
77-
name: ${{ matrix.env }}
75+
python: [py312, py314]
76+
beartype: [bt022]
77+
backend: [numpy24, jax09, torch210, optree019]
78+
exclude:
79+
- { python: py314, backend: torch210 }
80+
name: ${{ matrix.python }}-${{ matrix.beartype }}-${{ matrix.backend }}
7881
steps:
7982
- uses: actions/checkout@v6
8083
- uses: astral-sh/setup-uv@v7
81-
- run: uv run tox run -e "${{ matrix.env }}"
84+
- run: uv run tox run -e "${{ matrix.python }}-${{ matrix.beartype }}-${{ matrix.backend }}"
8285

83-
compat:
84-
if: startsWith(github.ref, 'refs/tags/v')
86+
typecheck-pr:
87+
if: github.event_name == 'pull_request'
8588
needs: [test]
8689
runs-on: ubuntu-latest
8790
strategy:
8891
fail-fast: false
8992
matrix:
90-
env:
91-
- numpy22
92-
- numpy23
93-
- numpy24
94-
- jax05
95-
- jax06
96-
- jax07
97-
- jax08
98-
- jax09
99-
- torch26
100-
- torch27
101-
- torch28
102-
- torch29
103-
- torch210
104-
- bt020
105-
- bt021
106-
- bt022
107-
- bt020-jax
108-
- bt021-jax
109-
- bt022-jax
110-
- bt020-torch
111-
- bt021-torch
112-
- bt022-torch
113-
- optree014
114-
- optree015
115-
- optree016
116-
- optree017
117-
- optree018
118-
- optree019
93+
include:
94+
- { env: py312-bt022-type-pyright1408 }
95+
- { env: py312-bt022-type-mypy119 }
96+
- { env: py312-bt022-type-ty }
11997
name: ${{ matrix.env }}
12098
steps:
12199
- uses: actions/checkout@v6
122100
- uses: astral-sh/setup-uv@v7
123101
- run: uv run tox run -e "${{ matrix.env }}"
124102

125-
typecheck-matrix:
126-
if: startsWith(github.ref, 'refs/tags/v')
103+
# -----------------------------------------------------------------------
104+
# Push: medium compat matrix
105+
# -----------------------------------------------------------------------
106+
107+
compat-push:
108+
if: github.event_name == 'push'
109+
needs: [test]
110+
runs-on: ubuntu-latest
111+
strategy:
112+
fail-fast: false
113+
matrix:
114+
python: [py312, py313, py314]
115+
beartype: [bt022]
116+
backend: [numpy24, jax09, torch210, optree019]
117+
exclude:
118+
- { python: py314, backend: torch210 }
119+
name: ${{ matrix.python }}-${{ matrix.beartype }}-${{ matrix.backend }}
120+
steps:
121+
- uses: actions/checkout@v6
122+
- uses: astral-sh/setup-uv@v7
123+
- run: uv run tox run -e "${{ matrix.python }}-${{ matrix.beartype }}-${{ matrix.backend }}"
124+
125+
typecheck-push:
126+
if: github.event_name == 'push'
127127
needs: [test]
128128
runs-on: ubuntu-latest
129129
strategy:
130130
fail-fast: false
131131
matrix:
132-
env:
133-
- pyright1392
134-
- pyright1400
135-
- pyright1408
136-
- mypy115
137-
- mypy116
138-
- mypy117
139-
- mypy118
140-
- mypy119
141-
- ty
132+
include:
133+
- { env: py312-bt022-type-pyright1392 }
134+
- { env: py312-bt022-type-pyright1400 }
135+
- { env: py312-bt022-type-pyright1408 }
136+
- { env: py312-bt022-type-mypy115 }
137+
- { env: py312-bt022-type-mypy117 }
138+
- { env: py312-bt022-type-mypy119 }
139+
- { env: py312-bt022-type-ty }
142140
name: ${{ matrix.env }}
143141
steps:
144142
- uses: actions/checkout@v6

.github/workflows/nightly.yml

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: Nightly
2+
3+
on:
4+
schedule:
5+
- cron: "0 4 * * *"
6+
workflow_dispatch:
7+
8+
concurrency:
9+
group: ${{ github.workflow }}
10+
cancel-in-progress: true
11+
12+
jobs:
13+
# -----------------------------------------------------------------------
14+
# Broad version compat — py312 × all beartype × all backends
15+
# -----------------------------------------------------------------------
16+
17+
compat-nightly:
18+
runs-on: ubuntu-latest
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
python: [py312]
23+
beartype: [bt020, bt021, bt022]
24+
backend:
25+
- numpy22
26+
- numpy23
27+
- numpy24
28+
- jax05
29+
- jax06
30+
- jax07
31+
- jax08
32+
- jax09
33+
- torch26
34+
- torch27
35+
- torch28
36+
- torch29
37+
- torch210
38+
- optree014
39+
- optree015
40+
- optree016
41+
- optree017
42+
- optree018
43+
- optree019
44+
name: ${{ matrix.python }}-${{ matrix.beartype }}-${{ matrix.backend }}
45+
steps:
46+
- uses: actions/checkout@v6
47+
- uses: astral-sh/setup-uv@v7
48+
- run: uv run tox run -e "${{ matrix.python }}-${{ matrix.beartype }}-${{ matrix.backend }}"
49+
50+
# -----------------------------------------------------------------------
51+
# Latest backends on py313/py314
52+
# -----------------------------------------------------------------------
53+
54+
compat-nightly-py:
55+
runs-on: ubuntu-latest
56+
strategy:
57+
fail-fast: false
58+
matrix:
59+
python: [py313, py314]
60+
beartype: [bt022]
61+
backend: [numpy24, jax09, torch210, optree019]
62+
exclude:
63+
- { python: py314, backend: torch210 }
64+
name: ${{ matrix.python }}-${{ matrix.beartype }}-${{ matrix.backend }}
65+
steps:
66+
- uses: actions/checkout@v6
67+
- uses: astral-sh/setup-uv@v7
68+
- run: uv run tox run -e "${{ matrix.python }}-${{ matrix.beartype }}-${{ matrix.backend }}"
69+
70+
# -----------------------------------------------------------------------
71+
# All typechecker versions
72+
# -----------------------------------------------------------------------
73+
74+
typecheck-nightly:
75+
runs-on: ubuntu-latest
76+
strategy:
77+
fail-fast: false
78+
matrix:
79+
include:
80+
- { env: py312-bt022-type-pyright1392 }
81+
- { env: py312-bt022-type-pyright1400 }
82+
- { env: py312-bt022-type-pyright1408 }
83+
- { env: py312-bt022-type-mypy115 }
84+
- { env: py312-bt022-type-mypy116 }
85+
- { env: py312-bt022-type-mypy117 }
86+
- { env: py312-bt022-type-mypy118 }
87+
- { env: py312-bt022-type-mypy119 }
88+
- { env: py312-bt022-type-ty }
89+
name: ${{ matrix.env }}
90+
steps:
91+
- uses: actions/checkout@v6
92+
- uses: astral-sh/setup-uv@v7
93+
- run: uv run tox run -e "${{ matrix.env }}"

CLAUDE.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,21 @@ src/shapix/
3939
## Running tests
4040

4141
```bash
42-
uv run pytest tests/
42+
uv run pytest tests/ # all tests locally
43+
uv run tox run -e dev # locked env with all deps
44+
uv run tox run -e py312-bt022-numpy24 # factor-based compat env
4345
```
46+
47+
## Tox factor scheme
48+
49+
Runtime envs: `{python}-{beartype}-{backend}` (e.g. `py312-bt022-numpy24`)
50+
Typecheck envs: `{python}-{beartype}-type-{checker}` (e.g. `py312-bt022-type-pyright1408`)
51+
52+
Factor deps are merged by tox. `tests/conftest.py` filters tests by backend via `TOX_ENV_NAME`.
53+
`tools/validate_tox_env.py` validates env names in `commands_pre`.
54+
55+
## Type checking
56+
57+
- pyright: `strict` mode with targeted suppressions for beartype internals
58+
- mypy: `strict = true` with `ignore_missing_imports = true`
59+
- ty: defaults only (`ty.toml` sets python-version)

CONTRIBUTING.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Contributing
2+
3+
## Local development
4+
5+
```bash
6+
uv sync # install all deps (dev + optional + static)
7+
uv run pytest tests/ # run all tests
8+
uv run pyright src/ # type-check source
9+
uv run tox run -e dev # locked env with all deps
10+
```
11+
12+
## Tox environment naming
13+
14+
Environments follow a **factor-based** naming scheme. Factor deps are merged automatically.
15+
16+
### Runtime: `{python}-{beartype}-{backend}`
17+
18+
| Factor | Values |
19+
|----------|--------|
20+
| Python | `py312`, `py313`, `py314` |
21+
| beartype | `bt020`, `bt021`, `bt022` |
22+
| Backend | `numpy22`..`numpy24`, `jax05`..`jax09`, `torch26`..`torch210`, `optree014`..`optree019` |
23+
24+
```bash
25+
uv run tox run -e py312-bt022-numpy24 # numpy 2.4 on py3.12
26+
uv run tox run -e py314-bt022-jax09 # jax 0.9 on py3.14
27+
```
28+
29+
### Typecheck: `{python}-{beartype}-type-{checker}`
30+
31+
```bash
32+
uv run tox run -e py312-bt022-type-pyright1408
33+
uv run tox run -e py312-bt022-type-mypy119
34+
uv run tox run -e py312-bt022-type-ty
35+
```
36+
37+
The `type` factor installs all backends so all imports resolve during type checking.
38+
39+
## CI tiers
40+
41+
| Tier | Trigger | Runtime envs | Typecheck envs |
42+
|------|---------|-------------|----------------|
43+
| PR | pull_request | py{312,314} × bt022 × latest backends | latest checkers |
44+
| Push | push to main | py{312,313,314} × bt022 × latest backends | broader checker versions |
45+
| Nightly | cron 04:00 UTC | py312 × all beartype × all versions | all checker versions |
46+
47+
## Adding a new backend version
48+
49+
1. Add the factor to `tox.toml` (e.g. `[env.numpy25]`)
50+
2. Add the factor name to `tools/validate_tox_env.py` `BACKENDS` set
51+
3. Add to CI matrix in `.github/workflows/ci.yml` and `nightly.yml`

0 commit comments

Comments
 (0)