Skip to content

🏗️ Split CI into lint/typecheck/test/build and type-clean src/devol#10

Merged
dariocazzani merged 1 commit into
mainfrom
feat/ci-matrix-and-job-split
May 3, 2026
Merged

🏗️ Split CI into lint/typecheck/test/build and type-clean src/devol#10
dariocazzani merged 1 commit into
mainfrom
feat/ci-matrix-and-job-split

Conversation

@dariocazzani
Copy link
Copy Markdown
Contributor

What does this PR do?

Upgrades CI from a single pytest-only job on Python 3.11 to four parallel jobs (lint, typecheck, test, build) running across a 3.11/3.12/3.13 matrix. To make the new gates actually pass, the src package is brought up to full mypy --strict cleanliness and the whole tree is brought up to ruff cleanliness. A real CLI bug surfaced by mypy is fixed along the way.

Details

CI workflow

  • Replace ci.yml with four jobs: lint, typecheck, test (3.11/3.12/3.13 matrix), build
  • lint runs ruff check + ruff format --check
  • typecheck runs mypy with existing strict settings, scoped to src/devol
  • build runs uv build + twine check to validate release artifacts
  • All jobs blocking

Type cleanup in src/devol/

  • Parametrize every NDArray annotation as NDArray[np.float64] via a per-module FloatArray alias
  • Resolve numpy's "returning Any" quirks by explicitly typing intermediate results
  • Cast np.sum/np.cos results to float in functions declared to return plain float
  • Bring Identity/Energy fitness classes up to strict typing (previously had untyped defs)
  • Drop a handful of stale # TODO scratch comments from algorithm.py

Real bug fix caught by mypy

DiffusionEvolution.run() required initial_population with no default, but the CLI called algo.run() with no argument. Running devol --config … --function sphere would have crashed. Default is now None, matching the public docstring in the README.

Ruff cleanup

  • Apply safe ruff auto-fixes across the repo (unused imports, f-strings without placeholders, import ordering)
  • Run ruff format so the format check passes
  • Exclude examples/ from ruff via pyproject.toml — they're demo code not in the published wheel, and they'll get their own cleanup PR
  • Add noqa: N806 on numpy meshgrid X, Y, Z in tests/ci/n_peaks.py (matrix capital-letter convention)

Verification

Locally, all four gates pass:

uv run ruff check                  # All checks passed!
uv run ruff format --check         # 20 files already formatted
uv run mypy src/devol              # Success: no issues found in 8 source files
uv run pytest                      # 15 passed
uv build && twine check dist/*     # PASSED

Out of scope

  • Cleaning up examples/ (deferred, separate PR)
  • benchmark/ is already ruff-clean and runs on 3.11+; its types are not yet strict but mypy doesn't cover it by design

…checks

Replace the single-job CI with four parallel jobs:

- lint: ruff check + ruff format --check (Python 3.13)
- typecheck: mypy --strict on src/devol (Python 3.13)
- test: pytest on Python 3.11, 3.12, 3.13
- build: uv build + twine check to validate release artifacts

All jobs are blocking. To make the new jobs actually pass, this also:

- Fixes the CLI bug mypy caught (run() was missing a default for
  initial_population, so `devol --config ... --function sphere`
  crashed with a TypeError)
- Introduces a FloatArray = NDArray[np.float64] alias per module and
  parametrizes every NDArray annotation in src/devol
- Resolves numpy "returning Any" typing quirks by explicitly typing
  intermediate results
- Casts np.sum/np.cos results to float where a plain float is declared
- Removes stale TODO scratch comments from algorithm.py
- Excludes examples/ from ruff (they are demo code, not part of the
  published wheel, and will get their own cleanup PR)
- Applies ruff auto-fixes (unused imports, f-strings without
  placeholders, import ordering) across the repo
- Runs ruff format across the repo so the check passes
- Adds noqa: N806 for numpy meshgrid X, Y, Z convention in tests/ci

After these changes: ruff, ruff format, mypy --strict, and pytest (x3)
all pass locally and in CI.
@dariocazzani dariocazzani merged commit 3a7a512 into main May 3, 2026
6 checks passed
@dariocazzani dariocazzani deleted the feat/ci-matrix-and-job-split branch May 3, 2026 16:12
dariocazzani added a commit that referenced this pull request May 3, 2026
The core devol package only uses numpy, pydantic, and pydantic-yaml, but
the shipped dependency list forced every user to install torch,
torchvision, gymnasium, and matplotlib — a ~2 GB footprint for a library
whose runtime doesn't touch any of them.

- Required deps reduced to numpy, pydantic, pydantic-yaml
- Drop unused pydantic-settings (leftover from an abandoned branch)
- Move torch, torchvision, gymnasium[classic-control], matplotlib into
  the examples extra (where cartpole/mnist/live-two-peaks actually use
  them)
- Add twine to the dev extra so the build CI job works from a sync
- Add an `all` meta-extra that pulls dev + examples + benchmark
- Narrow the wheel target to src/devol so examples/ and benchmark/
  ship only in the repo, not in the pip install
- Add pytest pythonpath config — narrowing the wheel removed the
  accidental side-effect that let `tests.ci.n_peaks` resolve via
  editable install, so configure it explicitly
- Update README with an Installation section covering the extras
- Update CHANGELOG with the dependency changes, the wheel narrowing,
  and the earlier CI/typing work from PR #10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant