diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9b12727bda..7eb1730daa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -168,7 +168,7 @@ jobs: continue-on-error: true strategy: matrix: - check: ['style', 'doctest', 'typecheck'] + check: ['style', 'doctest', 'typecheck', 'spellcheck'] steps: - uses: actions/checkout@v4 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 137aa49462..2b620a6de3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -40,3 +40,9 @@ repos: - importlib_resources args: ["nibabel"] pass_filenames: false + - repo: https://github.com/codespell-project/codespell + rev: v2.2.6 + hooks: + - id: codespell + additional_dependencies: + - tomli diff --git a/doc/source/devel/devguide.rst b/doc/source/devel/devguide.rst index bce5b64aaa..8748270f11 100644 --- a/doc/source/devel/devguide.rst +++ b/doc/source/devel/devguide.rst @@ -95,20 +95,6 @@ advise that you enable merge summaries within git: See :ref:`configure-git` for more detail. -Pre-commit hooks ----------------- - -NiBabel uses pre-commit_ to help committers validate their changes -before committing. To enable these, you can use pipx_:: - - pipx run pre-commit install - -Or install and run:: - - python -m pip install pre-commit - pre-commit install - - Testing ======= @@ -139,6 +125,55 @@ full set of optional dependencies that are available for 64-bit interpreters. If you are using 32-bit Python, replace ``-x64`` with ``-x86``. +Style guide +=========== + +To ensure code consistency and readability, NiBabel has adopted the following +tools: + +* blue_ - An auto-formatter that aims to reduce diffs to relevant lines +* isort_ - An import sorter that groups stdlib, third-party and local imports. +* flake8_ - A style checker that can catch (but generally not fix) common + errors in code. +* codespell_ - A spell checker targeted at source code. +* pre-commit_ - A pre-commit hook manager that runs the above and various + other checks/fixes. + +While some amount of personal preference is involved in selecting and +configuring auto-formatters, their value lies in largely eliminating the +need to think or argue about style. +With pre-commit turned on, you can write in the style that works for you, +and the NiBabel style will be adopted prior to the commit. + +To apply our style checks uniformly, simply run:: + + tox -e style,spellcheck + +To fix any issues found:: + + tox -e style-fix + tox -e spellcheck -- -w + +Occasionally, codespell has a false positive. To ignore the suggestion, add +the intended word to ``tool.codespell.ignore-words-list`` in ``pyproject.toml``. +However, the ignore list is a blunt instrument and could cause a legitimate +misspelling to be missed. Consider choosing a word that does not trigger +codespell before adding it to the ignore list. + +Pre-commit hooks +---------------- + +NiBabel uses pre-commit_ to help committers validate their changes +before committing. To enable these, you can use pipx_:: + + pipx run pre-commit install + +Or install and run:: + + python -m pip install pre-commit + pre-commit install + + Changelog ========= @@ -168,6 +203,9 @@ Please see `our community guidelines `_. Other projects call these guidelines the "code of conduct". -.. _tox: https://tox.wiki +.. _blue: https://blue.readthedocs.io/ +.. _codespell: https://github.com/codespell-project/codespell +.. _flake8: https://flake8.pycqa.org/ .. _pipx: https://pypa.github.io/pipx/ .. _precommit: https://pre-commit.com/ +.. _tox: https://tox.wiki/ diff --git a/doc/source/gitwash/development_workflow.rst b/doc/source/gitwash/development_workflow.rst index 7c117cfcce..696a939ed8 100644 --- a/doc/source/gitwash/development_workflow.rst +++ b/doc/source/gitwash/development_workflow.rst @@ -334,7 +334,7 @@ Rewriting commit history Do this only for your own feature branches. -There's an embarassing typo in a commit you made? Or perhaps the you +There's an embarrassing typo in a commit you made? Or perhaps the you made several false starts you would like the posterity not to see. This can be done via *interactive rebasing*. diff --git a/nibabel/freesurfer/tests/test_io.py b/nibabel/freesurfer/tests/test_io.py index 2406679d73..183a67ed2e 100644 --- a/nibabel/freesurfer/tests/test_io.py +++ b/nibabel/freesurfer/tests/test_io.py @@ -7,6 +7,7 @@ import warnings from os.path import isdir from os.path import join as pjoin +from pathlib import Path import numpy as np import pytest @@ -46,14 +47,6 @@ ) -def _hash_file_content(fname): - hasher = hashlib.md5() - with open(fname, 'rb') as afile: - buf = afile.read() - hasher.update(buf) - return hasher.hexdigest() - - @freesurfer_test def test_geometry(): """Test IO of .surf""" @@ -179,7 +172,6 @@ def test_annot(): annots = ['aparc', 'aparc.a2005s'] for a in annots: annot_path = pjoin(data_path, 'label', f'lh.{a}.annot') - hash_ = _hash_file_content(annot_path) labels, ctab, names = read_annot(annot_path) assert labels.shape == (163842,) @@ -190,9 +182,10 @@ def test_annot(): labels_orig, _, _ = read_annot(annot_path, orig_ids=True) np.testing.assert_array_equal(labels == -1, labels_orig == 0) # Handle different version of fsaverage - if hash_ == 'bf0b488994657435cdddac5f107d21e8': + content_hash = hashlib.md5(Path(annot_path).read_bytes()).hexdigest() + if content_hash == 'bf0b488994657435cdddac5f107d21e8': assert np.sum(labels_orig == 0) == 13887 - elif hash_ == 'd4f5b7cbc2ed363ac6fcf89e19353504': + elif content_hash == 'd4f5b7cbc2ed363ac6fcf89e19353504': assert np.sum(labels_orig == 1639705) == 13327 else: raise RuntimeError( diff --git a/nibabel/info.py b/nibabel/info.py index 33d1b0aa0d..a608932fa8 100644 --- a/nibabel/info.py +++ b/nibabel/info.py @@ -77,7 +77,7 @@ pip install nibabel[test] pytest --pyargs nibabel -For more inforation, consult the `developer guidelines`_. +For more information, consult the `developer guidelines`_. .. _tox: https://tox.wiki .. _pytest: https://docs.pytest.org diff --git a/pyproject.toml b/pyproject.toml index beb81fb0d4..50905dff56 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -129,3 +129,7 @@ python_version = "3.11" exclude = [ "/tests", ] + +[tool.codespell] +skip = "*/data/*,./nibabel-data" +ignore-words-list = "ans,te,ue,ist,nin,nd,ccompiler,ser" diff --git a/tox.ini b/tox.ini index dd8e1650b9..b5328d081a 100644 --- a/tox.ini +++ b/tox.ini @@ -150,6 +150,15 @@ commands = blue nibabel isort nibabel +[testenv:spellcheck] +description = Check spelling +labels = check +deps = + codespell[toml] +skip_install = true +commands = + codespell . {posargs} + [testenv:typecheck] description = Check type consistency labels = check