Modernize pre-commit hooks & linting (PR 1/9)#1282
Merged
Marius1311 merged 17 commits intomainfrom Feb 20, 2026
Merged
Conversation
- Remove black and isort pre-commit hooks - Remove pretty-format-yaml hook (replaced by biome in 1c) - Rename ruff hook to ruff-check, add ruff-format hook - Add types_or: [python, pyi, jupyter] to both ruff hooks - Remove [tool.black] and [tool.isort] sections from pyproject.toml - Add I (isort) to [tool.ruff.lint] select
- Remove pyupgrade hook (ruff UP rules cover this) - Remove blacken-docs hook (ruff-format handles code blocks) - Remove rstcheck hook (CI lint-docs is more thorough) - Remove doc8 hook and [tool.doc8] from pyproject.toml
- Add biomejs/pre-commit v2.2.4 (biome-format) + biome.jsonc config - Add tox-dev/pyproject-fmt v2.6.0 - Bump pre-commit-hooks v4.6.0 → v6.0.0 - Bump ruff-pre-commit v0.6.5 → v0.13.2
- requires-python: '>=3.10' → '>=3.12' - Remove Python 3.10/3.11 classifiers - Remove target-version (inferred from requires-python) - Add src = ['src'] for first-party import detection - Add format.docstring-code-format = true
Move 16 safe-to-move local imports to module top level: - scanpy.plotting.palettes in _colors.py - numpy.linalg.norm, scipy.spatial.distance.jensenshannon, sklearn.feature_selection.mutual_info_regression in _lineage.py - networkx, cellrank._utils._parallelize.parallelize in _utils.py - cellrank._utils._key.Key in _base_kernel.py - scvelo.plotting.utils in _random_walk.py - cellrank.kernels._utils._ensure_numeric_ordered in _log_odds.py - mpl_toolkits.axes_grid1.Divider/Size in _heatmap.py - sklearn.svm.SVR in pl/_utils.py - cellrank._utils._linear_solver._is_petsc_slepc_available in _schur.py - cellrank._utils.Lineage, sklearn.utils.sparsefuncs in _cytotrace_kernel.py Add '# circular import' comments to all remaining local imports that must stay local to avoid circular import chains.
- Remove 5 unnecessary noqa comments (no rules triggered) - Add specific codes to 19 remaining noqa comments: D400/D401 for docrep %(copy)s templates D400 for multi-line docstring endings F821 for forward-reference type annotations F401 for unused petsc4py/slepc4py imports C408 for dict() call NPY001 for deprecated np.int alias B006 for mutable default argument
Run all pre-commit hooks on every file to apply consistent formatting: - ruff format: reformat all Python files - ruff check --fix: auto-fix UP007/UP045 (Union→X|Y), C420 (dict.fromkeys), UP042/UP047 (type params), remove unused Union/Optional imports - pyproject-fmt: normalize pyproject.toml - biome: format JSON files - Ignore B905 (zip without strict=) for now (67 pre-existing violations)
np.array is a function, not a type — using it in X | Y union syntax causes TypeError at runtime. These were pre-existing annotation bugs exposed by the ruff UP007/UP045 auto-fixes.
RTD was using Python 3.10, which now fails because requires-python >= 3.12.
Aligns with requires-python >= 3.12 set in commit 5e687f0.
- lint.yml: 3.10 → 3.12 - deployment.yml: 3.10 → 3.12 - docs/installation.rst: >= 3.8 → >= 3.12
Ruff UP017 auto-converted datetime.timezone.utc → datetime.UTC (the modern Python 3.11+ alias). The test's IncTime monkeypatch only exposed a 'timezone' property, not 'UTC'. Add the missing property to the mock.
Zethson
reviewed
Feb 18, 2026
Member
Zethson
left a comment
There was a problem hiding this comment.
I love these kind of PRs. Sorry, just saw this while passing by
Tested locally: docs build succeeds on 3.13.7.
Collaborator
Author
|
Hi @Zethson, thanks a lot for your review, that's great! I'll go over it step by step, but for context, I planned a series of PRs to update CellRank, this is just the first one. I wanted to do the more "radical" changes, like switching to hatch, on a separate PR, that's why it's not included here. |
Collaborator
Author
|
comments
|
Collaborator
Author
Actually I wouldn't do it - that's only really useful if you want to be really strict about typing, i.e. use mypy. We're more leaninant on types, so I think it's fine. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replace the legacy linting/formatting stack (black, isort, flake8, doc8, pyupgrade) with ruff + biome + pyproject-fmt, require Python ≥3.12, and apply bulk reformatting.
This is the first in a series of modernization PRs to align CellRank with the scverse cookiecutter template.
Changes
Pre-commit hooks
ruff-format(single formatter)pre-commit-hooks(check-ast, check-merge-conflict, check-added-large-files, etc.)Python version & ruff config
python_requires = ">=3.12"— drop 3.10/3.11 classifierstarget-version(inferred fromrequires-python), add isort rules ("I"), enabledocstring-code-format, addB905to ignore (67 pre-existingzip()withoutstrict=— to be addressed separately)Code quality
# circular importcomments# noqacomments — replaced with explicit rule codes (e.g.,# noqa: BLE001) or removed where unnecessary (5 removed, 19 annotated)np.array→np.ndarrayin 6 type annotations across 3 files —np.arrayis a function, not a type, sonp.array | NoneraisesTypeErrorat runtime (pre-existing bug exposed by ruff UP007/UP045 auto-fixes)Bulk reformat
pre-commit run --all-filesto convergence — reformats ~67 files.git-blame-ignore-revssogit blame(and GitHub blame UI) skips the reformat commitHousekeeping
.gitignore(adduv.lock,.github/prompts/)Commits
91a3bdfdedd7a1327ac027e75e687f0f1dd1e667313b30a4# noqacomments with explicit rule codes0a8f50a9pre-commit run --all-filese9bbac22.git-blame-ignore-revsfor bulk reformat commitb3b8bd63np.arraytype annotations →np.ndarray63cddb85.gitignoreNotes
0a8f50a9) is listed in.git-blame-ignore-revs— GitHub will automatically ignore it in blame viewszip()withoutstrict=) is intentionally deferred — 67 call sites need individual review for correctness