Skip to content

Adopt the current scverse cookiecutter template - #411

Open
Zethson wants to merge 2 commits into
mainfrom
feat/adopt-scverse-template
Open

Adopt the current scverse cookiecutter template#411
Zethson wants to merge 2 commits into
mainfrom
feat/adopt-scverse-template

Conversation

@Zethson

@Zethson Zethson commented Jul 29, 2026

Copy link
Copy Markdown
Member

Syncs the repo with cookiecutter-scverse@707f3fa, including the mypy type checking the template now ships. .cruft.json is recorded so future cruft update runs work.

Breaking: Python 3.11 is dropped (SPEC 0; spatialdata is already >=3.12).

  • Dependency groups instead of extras; tests run from a hatch matrix (3.12/3.14 stable, 3.14 pre-release).
  • Template ruff/coverage/pytest config, biome.jsonc, CHANGELOG.md, .codecov.yaml, .editorconfig, .gitignore. Removes the duplicate .github/codecov.yml and the broken .bumpversion.cfg; the version still comes from git tags via hatch-vcs.
  • New CI: hatch-driven tests, build check, trusted publishing, pre-commit as a CI job, Dependabot, issue templates. The test-data artifact now downloads for every environment, so 3.12 and pre-release exercise the readers too.
  • Template conf.py (scverse-misc, katex, opengraph); drops the vendored typed_returns extension and autosummary template it replaces. Template dev guide merged above the existing reader-contribution guide.
  • py.typed shipped; mypy src tests runs as a hook. No # type: ignore, no casts, no nitpick ignores, and no mypy settings beyond ignore_missing_imports for the deps that ship neither types nor stubs.

Bugs this found

  • cosmx, merscope and mcmicro passed dtype= to AnnData(...), removed in anndata 0.11 — those readers raised TypeError at runtime.
  • macsima._get_translations returned floats despite declaring dict[str, int]; the values are used as da.pad widths.
  • The # type: ignores in dbit hid that _check_path can return None and that path=None silently listed the working directory.

Notes

  • The old mypy hook was dead: .mypy.ini pinned python_version = 3.10, so mypy aborted on numpy's stubs before checking anything.
  • main currently fails the strict docs build (spatialdata.models.chunks_utils.TypeAliasType has no link target), which breaks RTD. Fixed at the source by inlining that alias in generic.image, plus imageio.v2.imread, a stereoseq section underline and the missing Virshup_2023 entry.
  • sphinx_click is ordered before sphinx_autodoc_typehints, which imports sphinx.ext.autodoc.mock as a submodule and shadows the callable sphinx-click binds at import time. No version pin.
  • [tool.pytest] strict = true rejects markers used by third-party test modules that anndata.tests.helpers and spatialdata.testing import, so four of them are declared in pyproject.toml.

Verification

prek run --all-files, mypy src tests and sphinx -W all clean on 3.14. pytest is 53 passed / 13 skipped / 22 failed, identical to main locally — the 22 are assert f.is_dir() on test data only CI has.

Sync the repository with cookiecutter-scverse@707f3fa, including the
mypy-based type checking the template now ships, and record the template
state in `.cruft.json` so future syncs work.

Packaging and tooling:

- Drop Python 3.11 (SPEC 0, and `spatialdata` already requires >=3.12) and
  advertise 3.12-3.14 plus `Typing :: Typed`.
- Replace the `dev`/`doc`/`test`/`pre` extras with dependency groups, and drive
  testing from a hatch matrix (3.12/3.14 stable, 3.14 pre-release) so local and
  CI runs share a single definition.
- Adopt the template's ruff, coverage and pytest configuration, `biome.jsonc`,
  `.editorconfig`, `.gitignore`, `.codecov.yaml` and `CHANGELOG.md`, and delete
  the now-duplicated `.github/codecov.yml` and the broken `.bumpversion.cfg`
  (the version comes from git tags via hatch-vcs).
- Rebuild the CI on the template's workflows: hatch-driven tests, a package
  build check, trusted publishing on release, pre-commit checks as a CI job,
  Dependabot for hooks and actions, and issue templates. The test-data artifact
  download is kept and now runs for every environment, so the 3.12 and
  pre-release jobs exercise the readers too.
- Switch pre-commit to biome, pyproject-fmt, ruff-check and zizmor, and pin
  every action to a SHA so zizmor passes on `prepare_test_data.yaml` as well.

Documentation:

- Adopt the template's `conf.py` (scverse-misc, katex, opengraph, custom CSS)
  and drop the vendored `typed_returns` extension and autosummary template that
  scverse-misc replaces.
- Merge the template's development guide into `docs/contributing.md` ahead of
  the existing reader-contribution guide, and describe the tag-based release
  flow instead of editing a version number.
- `docs/changelog.md` now includes `CHANGELOG.md`.
- Order `sphinx_click` before `sphinx_autodoc_typehints`: the latter imports
  `sphinx.ext.autodoc.mock` as a submodule, which shadows the callable of the
  same name that sphinx-click binds at import time.
- Fix the references that made the strict build fail (`imageio.v2.imread`, the
  stereoseq `Notes` underline, the missing `Virshup_2023` entry) and inline
  `spatialdata`'s undocumented `Chunks_t` alias in `generic.image`, so the docs
  build clean with no nitpick exceptions.

Typing:

- Ship a `py.typed` marker and type-check `src` and `tests` with mypy, with no
  `# type: ignore`, no casts and no mypy settings beyond `ignore_missing_imports`
  for the dependencies that ship neither inline types nor stubs. Stubs are used
  wherever they exist (pandas, scipy, geopandas, shapely, tqdm, PyYAML,
  xmltodict).
- This surfaced three real bugs: `cosmx`, `merscope` and `mcmicro` passed the
  `dtype=` argument that anndata removed in 0.11, so those readers raised
  `TypeError` at runtime; `mcmicro` now casts via `to_numpy(dtype=float)` to
  keep the previous behaviour.
- `_get_translations` returned floats despite declaring `dict[str, int]`, which
  would have failed when used as `da.pad` widths.
- Replace the remaining `# type: ignore` comments in `dbit` with real checks,
  and narrow the blind `except Exception` in `macsima` to the errors
  `parse_physical_size` actually raises.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov-commenter

codecov-commenter commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 42.39130% with 53 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.15%. Comparing base (a63ca08) to head (a990267).

Files with missing lines Patch % Lines
src/spatialdata_io/readers/curio.py 0.00% 15 Missing ⚠️
src/spatialdata_io/readers/dbit.py 10.00% 9 Missing ⚠️
src/spatialdata_io/readers/cosmx.py 0.00% 6 Missing ⚠️
src/spatialdata_io/readers/_utils/_utils.py 50.00% 4 Missing ⚠️
src/spatialdata_io/readers/merscope.py 33.33% 4 Missing ⚠️
src/spatialdata_io/readers/xenium.py 81.81% 4 Missing ⚠️
src/spatialdata_io/readers/codex.py 0.00% 3 Missing ⚠️
src/spatialdata_io/readers/seqfish.py 40.00% 3 Missing ⚠️
src/spatialdata_io/readers/visium.py 0.00% 2 Missing ⚠️
src/spatialdata_io/readers/mcmicro.py 0.00% 1 Missing ⚠️
... and 2 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #411      +/-   ##
==========================================
- Coverage   63.41%   63.15%   -0.26%     
==========================================
  Files          26       26              
  Lines        3217     3257      +40     
==========================================
+ Hits         2040     2057      +17     
- Misses       1177     1200      +23     
Files with missing lines Coverage Δ
src/spatialdata_io/__init__.py 100.00% <100.00%> (ø)
src/spatialdata_io/converters/legacy_anndata.py 52.70% <100.00%> (+0.64%) ⬆️
src/spatialdata_io/readers/_utils/_image.py 100.00% <ø> (ø)
src/spatialdata_io/readers/generic.py 88.73% <100.00%> (ø)
src/spatialdata_io/readers/macsima.py 95.53% <100.00%> (ø)
src/spatialdata_io/readers/visium_hd.py 75.49% <100.00%> (+0.08%) ⬆️
src/spatialdata_io/readers/mcmicro.py 14.64% <0.00%> (-0.10%) ⬇️
src/spatialdata_io/readers/steinbock.py 35.29% <50.00%> (+0.60%) ⬆️
src/spatialdata_io/readers/stereoseq.py 15.54% <0.00%> (-0.11%) ⬇️
src/spatialdata_io/readers/visium.py 18.54% <0.00%> (ø)
... and 8 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Under Python 3.14's dependency resolution, numpy types `ndarray.mean()` as
`np.float64`, so mypy inferred that for the variable and rejected the `int`
default in the other branch. Annotating the variable keeps both branches valid
without changing the value or the log message.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Zethson
Zethson requested a review from LucaMarconato July 29, 2026 11:11
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.

2 participants