From 24442bba3540a50a8a441c9a34659d10a580dfbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicholas=20Kr=C3=A4mer?= Date: Fri, 24 May 2024 11:15:22 +0200 Subject: [PATCH] Replace formatters with Ruff (#183) * Replace formatters with Ruff * Reintroduce pydocstyle * Update the GitHub action * Include the format-and-lint merge of format and lint in the documentation * Update the workflows again... --- .github/workflows/ci.yaml | 4 +- .pre-commit-config.yaml | 30 ++++++------ Makefile | 10 ++-- README.md | 18 ++------ matfree/backend/containers.py | 1 - matfree/backend/prng.py | 1 - matfree/backend/typing.py | 1 + matfree/bounds.py | 2 +- matfree/lanczos.py | 5 +- pyproject.toml | 46 +++++++++---------- scripts/generate_api_docs.py | 1 + scripts/tutorials_to_py_light.py | 1 + .../test_frobeniusnorm_squared.py | 1 + tests/test_hutchinson/test_trace.py | 1 + .../test_trace_and_diagonal.py | 1 + .../test_lanczos/test_funm_vector_product.py | 1 + tests/test_lanczos/test_svd_approx.py | 1 - .../test_pinv/test_pseudo_inverse_correct.py | 1 + .../test_funm_vector_product_chebyshev.py | 1 + 19 files changed, 56 insertions(+), 71 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5985495..f903883 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -24,9 +24,9 @@ jobs: - name: Install dependencies run: | pip install --upgrade pip - pip install .[cpu,lint] + pip install .[cpu,format-and-lint] - name: Apply linter - run: make lint + run: make format-and-lint test: name: Test with ${{ matrix.python-version }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 000278c..8bd72ae 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,32 +3,30 @@ default_language_version: python: python3 repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - id: check-merge-conflict - - repo: https://github.com/psf/black - rev: 23.9.1 - hooks: - - id: black - language_version: python3 - - repo: https://github.com/pycqa/isort - rev: 5.12.0 - hooks: - - id: isort - name: isort - - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.292 + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.4.5 hooks: + # Run the linter. - id: ruff + args: [--fix] + # Run the formatter. + - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.5.1 + rev: v1.10.0 hooks: - id: mypy - args: [--ignore-missing-imports] + args: + - --no-strict-optional + - --ignore-missing-imports + - --explicit-package-bases - repo: https://github.com/lyz-code/yamlfix/ - rev: 1.13.0 + rev: 1.16.0 hooks: - id: yamlfix diff --git a/Makefile b/Makefile index 726fb31..9f788bf 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,9 @@ -format: - isort . --quiet - black . --quiet - blackdoc *.md --line-length 82 - -lint: +format-and-lint: pre-commit run --all-files + blackdoc *.md --line-length 82 test: - pytest -x -v + pytest python -m doctest README.md python -m doctest matfree/*.py diff --git a/README.md b/README.md index 7c84855..abdd149 100644 --- a/README.md +++ b/README.md @@ -115,24 +115,14 @@ make test Install all formatting-related dependencies via ```commandline -pip install .[format] +pip install .[format-and-lint] +pre-commit install ``` and format the code via ```commandline -make format +make format-and-lint ``` -To lint the code, install the pre-commit hook - -```commandline -pip install .[lint] -pre-commit install - -``` -and run the linters via -```commandline -make lint -``` Install the documentation-related dependencies as @@ -169,7 +159,7 @@ To make a pull request, proceed as follows: - Fork the repository. - Install all dependencies with `pip install .[full]` or `pip install -e .[full]`. - Make your changes. -- From the root of the project, run the tests via `make test`, and check out `make format` and `make lint` as well. Use the pre-commit hook if you like. +- From the root of the project, run the tests via `make test`, and check out `make format-and-lint` as well. Use the pre-commit hook if you like. When making a pull request, keep in mind the following (rough) guidelines: diff --git a/matfree/backend/containers.py b/matfree/backend/containers.py index 5011a49..9310811 100644 --- a/matfree/backend/containers.py +++ b/matfree/backend/containers.py @@ -1,4 +1,3 @@ """Container types.""" - from typing import NamedTuple # noqa: F401 diff --git a/matfree/backend/prng.py b/matfree/backend/prng.py index 260f9bc..7fc9542 100644 --- a/matfree/backend/prng.py +++ b/matfree/backend/prng.py @@ -1,6 +1,5 @@ """Pseudo-random-number utilities.""" - import jax.random diff --git a/matfree/backend/typing.py b/matfree/backend/typing.py index 8c82c08..c57b00b 100644 --- a/matfree/backend/typing.py +++ b/matfree/backend/typing.py @@ -1,4 +1,5 @@ """Types.""" + # fmt: off from collections.abc import Callable # noqa: F401 from typing import Any, Generic, Iterable, Sequence, Tuple, TypeVar # noqa: F401, UP035 diff --git a/matfree/bounds.py b/matfree/bounds.py index b9635d1..3465657 100644 --- a/matfree/bounds.py +++ b/matfree/bounds.py @@ -4,7 +4,7 @@ def baigolub96_logdet_spd(bound_spectrum, /, nrows, trace, norm_frobenius_squared): - """Bound the log-determinant of a symmatric, positive definite matrix. + """Bound the log-determinant of a symmetric, positive definite matrix. This function implements Theorem 2 in the paper by Bai and Golub (1996). diff --git a/matfree/lanczos.py b/matfree/lanczos.py index a9e3a90..4f0b3aa 100644 --- a/matfree/lanczos.py +++ b/matfree/lanczos.py @@ -365,10 +365,7 @@ def _validate_unit_2_norm(v, /): # but we can make it obvious that the result is unusable. is_not_normalized = np.abs(linalg.vector_norm(v) - 1.0) > 10 * np.finfo_eps(v.dtype) return control_flow.cond( - is_not_normalized, - lambda s: np.nan() * np.ones_like(s), - lambda s: s, - v, + is_not_normalized, lambda s: np.nan() * np.ones_like(s), lambda s: s, v ) diff --git a/pyproject.toml b/pyproject.toml index 7c6a15d..2d75dea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,13 +33,10 @@ test =[ "pytest", "pytest-cases", ] -lint =[ +format-and-lint =[ "matfree[test]", "pre-commit", -] -format =[ - "isort", - "black", + "blackdoc", ] doc = [ "mkdocs", @@ -54,8 +51,7 @@ doc = [ full = [ "matfree[cpu]", "matfree[test]", - "matfree[lint]", - "matfree[format]", + "matfree[format-and-lint]", "matfree[doc]", ] @@ -74,8 +70,11 @@ version_file = "matfree/_version.py" "Issue tracker" = "https://github.com/pnkraemer/matfree/issues" + [tool.ruff] -include = ["*.py", "**/pyproject.toml", "*.ipynb"] +include = ["**.py", "**/pyproject.toml", "**.ipynb"] + +[tool.ruff.lint] # See: https://beta.ruff.rs/docs/rules/ select = [ # pycodestyle (warning, error) @@ -83,8 +82,6 @@ select = [ "E", # Pyflakes: "F", - # pydocstyle: - "D", # pyupgrade: "UP", # flake8-bugbear: @@ -119,24 +116,25 @@ ignore = [ "D213", # zip(..., strict=True/False) is not supported on Python < 3.10 "B905", - # Magic methods don't need a docstring: - "D105", ] -[tool.ruff.per-file-ignores] -# We don't write docstrings for the backend -"matfree/backend/*.py" = ["D103"] +[tool.ruff.format] +# Use `\n` line endings for all files +line-ending = "lf" +# Prefer single quotes over double quotes. +quote-style = "double" +skip-magic-trailing-comma = true + +[tool.ruff.lint.isort] +split-on-trailing-comma = false + [tool.ruff.pydocstyle] convention = "numpy" -[tool.isort] -multi_line_output = "3" -include_trailing_comma = "true" -force_grid_wrap = "0" -use_parentheses = "true" -line_length = "88" - -[tool.black] -line-length = "88" +[tool.pytest.ini_options] +addopts = "-v" +testpaths = [ + "tests" +] diff --git a/scripts/generate_api_docs.py b/scripts/generate_api_docs.py index 8f9039a..5e057c8 100644 --- a/scripts/generate_api_docs.py +++ b/scripts/generate_api_docs.py @@ -1,4 +1,5 @@ """Generate API docs from the source.""" + import pathlib diff --git a/scripts/tutorials_to_py_light.py b/scripts/tutorials_to_py_light.py index 60e917a..be0713c 100644 --- a/scripts/tutorials_to_py_light.py +++ b/scripts/tutorials_to_py_light.py @@ -1,4 +1,5 @@ """Transform py:light scripts into Jupyter notebooks.""" + import contextlib import os from re import sub diff --git a/tests/test_hutchinson/test_frobeniusnorm_squared.py b/tests/test_hutchinson/test_frobeniusnorm_squared.py index eedef0f..3d12613 100644 --- a/tests/test_hutchinson/test_frobeniusnorm_squared.py +++ b/tests/test_hutchinson/test_frobeniusnorm_squared.py @@ -1,4 +1,5 @@ """Test the estimation of squared Frobenius-norms.""" + from matfree import hutchinson from matfree.backend import func, linalg, np, prng, tree_util diff --git a/tests/test_hutchinson/test_trace.py b/tests/test_hutchinson/test_trace.py index c6460a7..6250110 100644 --- a/tests/test_hutchinson/test_trace.py +++ b/tests/test_hutchinson/test_trace.py @@ -1,4 +1,5 @@ """Test trace estimation.""" + from matfree import hutchinson from matfree.backend import func, linalg, np, prng, tree_util diff --git a/tests/test_hutchinson/test_trace_and_diagonal.py b/tests/test_hutchinson/test_trace_and_diagonal.py index 7121d1a..486506a 100644 --- a/tests/test_hutchinson/test_trace_and_diagonal.py +++ b/tests/test_hutchinson/test_trace_and_diagonal.py @@ -1,4 +1,5 @@ """Test joint trace and diagonal estimation.""" + from matfree import hutchinson from matfree.backend import func, np, prng, tree_util diff --git a/tests/test_lanczos/test_funm_vector_product.py b/tests/test_lanczos/test_funm_vector_product.py index a9c9620..69d5fa1 100644 --- a/tests/test_lanczos/test_funm_vector_product.py +++ b/tests/test_lanczos/test_funm_vector_product.py @@ -1,4 +1,5 @@ """Test matrix-function-vector products via Lanczos' algorithm.""" + from matfree import lanczos, test_util from matfree.backend import linalg, np, prng diff --git a/tests/test_lanczos/test_svd_approx.py b/tests/test_lanczos/test_svd_approx.py index b90ded6..69453a1 100644 --- a/tests/test_lanczos/test_svd_approx.py +++ b/tests/test_lanczos/test_svd_approx.py @@ -1,6 +1,5 @@ """Tests for SVD functionality.""" - from matfree import lanczos, test_util from matfree.backend import linalg, np, testing diff --git a/tests/test_pinv/test_pseudo_inverse_correct.py b/tests/test_pinv/test_pseudo_inverse_correct.py index bfdf23b..f16abd5 100644 --- a/tests/test_pinv/test_pseudo_inverse_correct.py +++ b/tests/test_pinv/test_pseudo_inverse_correct.py @@ -1,4 +1,5 @@ """Tests for pseudo-inverse functionality.""" + from matfree import pinv from matfree.backend import func, linalg, np, prng, testing diff --git a/tests/test_polynomial/test_funm_vector_product_chebyshev.py b/tests/test_polynomial/test_funm_vector_product_chebyshev.py index 1e30ecd..f0b6946 100644 --- a/tests/test_polynomial/test_funm_vector_product_chebyshev.py +++ b/tests/test_polynomial/test_funm_vector_product_chebyshev.py @@ -1,4 +1,5 @@ """Test matrix-polynomial-vector algorithms via Chebyshev's recursion.""" + from matfree import polynomial, test_util from matfree.backend import linalg, np, prng