diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cbad42b83a..cd52482df0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,6 +28,13 @@ repos: # Don't commit to main branch. - id: no-commit-to-branch +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: "v0.1.6" + hooks: + - id: ruff + types: [file, python] + args: [--fix, --show-fixes] + - repo: https://github.com/codespell-project/codespell rev: "v2.2.6" hooks: diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 0000000000..f3f9f1d3f0 --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,240 @@ +extend = "pyproject.toml" + +lint.ignore = [ + # NOTE: To find a rule code to fix, run: + # ruff --select="ALL" --statistics lib/iris/ + + # Pyflakes (F) + # https://docs.astral.sh/ruff/rules/#pyflakes-f + "F", + + # pycodestyle (E, W) + # https://docs.astral.sh/ruff/rules/#pycodestyle-e-w + "E", + "W", + + # mccabe (C90) + # https://docs.astral.sh/ruff/rules/#mccabe-c90 + "C90", + + # isort (I) + # https://docs.astral.sh/ruff/rules/#isort-i + "I", + + # pep8-naming (N) + # https://docs.astral.sh/ruff/rules/#pep8-naming-n + "N", + + # pydocstyle (D) + # https://docs.astral.sh/ruff/rules/#pydocstyle-d + "D", + + # pyupgrade (UP) + # https://docs.astral.sh/ruff/rules/#pyupgrade-up + "UP", + + # flake8-2020 (YTT) + # https://docs.astral.sh/ruff/rules/#flake8-2020-ytt + "YTT", + + # flake8-annotations (ANN) + # https://docs.astral.sh/ruff/rules/#flake8-annotations-ann + "ANN", + + # flake8-async (ASYNC) + # https://docs.astral.sh/ruff/rules/#flake8-async-async + "ASYNC", + + # flake8-trio (TRIO) + # https://docs.astral.sh/ruff/rules/#flake8-trio-trio + "TRIO", + + # flake8-bandit (S) + # https://docs.astral.sh/ruff/rules/#flake8-bandit-s + "S", + + # flake8-blind-except (BLE) + # https://docs.astral.sh/ruff/rules/#flake8-blind-except-ble + "BLE", + + # flake8-boolean-trap (FBT) + # https://docs.astral.sh/ruff/rules/#flake8-boolean-trap-fbt + "FBT", + + # flake8-bugbear (B) + # https://docs.astral.sh/ruff/rules/#flake8-bugbear-b + "B", + + # flake8-builtins (A) + # https://docs.astral.sh/ruff/rules/#flake8-builtins-a + "A", + + # flake8-commas (COM) + # https://docs.astral.sh/ruff/rules/#flake8-commas-com + "COM", + + # flake8-copyright (CPY) + # https://docs.astral.sh/ruff/rules/#flake8-copyright-cpy + "CPY", + + # flake8-comprehensions (C4) + # https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 + "C4", + + # flake8-datetimez (DTZ) + # https://docs.astral.sh/ruff/rules/#flake8-datetimez-dtz + "DTZ", + + # flake8-debugger (T10) + # https://docs.astral.sh/ruff/rules/#flake8-debugger-t10 + "T10", + + # flake8-django (DJ) + # https://docs.astral.sh/ruff/rules/#flake8-django-dj + "DJ", + + # flake8-errmsg (EM) + # https://docs.astral.sh/ruff/rules/#flake8-errmsg-em + "EM", + + # flake8-executable (EXE) + # https://docs.astral.sh/ruff/rules/#flake8-executable-exe + "EXE", + + # flake8-future-annotations (FA) + # https://docs.astral.sh/ruff/rules/#flake8-future-annotations-fa + "FA", + + # flake8-implicit-str-concat (ISC) + # https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc + "ISC", + + # flake8-import-conventions (ICN) + # https://docs.astral.sh/ruff/rules/#flake8-import-conventions-icn + "ICN", + + # flake8-logging-format (G) + # https://docs.astral.sh/ruff/rules/#flake8-logging-format-g + "G", + + # flake8-no-pep420 (INP) + # https://docs.astral.sh/ruff/rules/#flake8-no-pep420-inp + "INP", + + # flake8-pie (PIE) + # https://docs.astral.sh/ruff/rules/#flake8-pie-pie + "PIE", + + # flake8-print (T20) + # https://docs.astral.sh/ruff/rules/#flake8-print-t20 + "T20", + + # flake8-pyi (PYI) + # https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi + "PYI", + + # flake8-pytest-style (PT) + # https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt + "PT", + + # flake8-quotes (Q) + # https://docs.astral.sh/ruff/rules/#flake8-quotes-q + "Q", + + # flake8-raise (RSE) + # https://docs.astral.sh/ruff/rules/#flake8-raise-rse + "RSE", + + # flake8-return (RET) + # https://docs.astral.sh/ruff/rules/#flake8-return-ret + "RET", + + # flake8-self (SLF) + # https://docs.astral.sh/ruff/rules/#flake8-self-slf + "SLF", + + # flake8-slots (SLOT) + # https://docs.astral.sh/ruff/rules/#flake8-slots-slot + "SLOT", + + # flake8-simplify (SIM) + # https://docs.astral.sh/ruff/rules/#flake8-simplify-sim + "SIM", + + # flake8-tidy-imports (TID) + # https://docs.astral.sh/ruff/rules/#flake8-tidy-imports-tid + "TID", + + # flake8-type-checking (TCH) + # https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch + "TCH", + + # flake8-gettext (INT) + # https://docs.astral.sh/ruff/rules/#flake8-gettext-int + "INT", + + # flake8-unused-arguments (ARG) + # https://docs.astral.sh/ruff/rules/#flake8-unused-arguments-arg + "ARG", + + # flake8-use-pathlib (PTH) + # https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth + "PTH", + + # flake8-todos (TD) + # https://docs.astral.sh/ruff/rules/#flake8-todos-td + "TD", + + # flake8-fixme (FIX) + # https://docs.astral.sh/ruff/rules/#flake8-fixme-fix + "FIX", + + # eradicate (ERA) + # https://docs.astral.sh/ruff/rules/#eradicate-era + "ERA", + + # pandas-vet (PD) + # https://docs.astral.sh/ruff/rules/#pandas-vet-pd + "PD", + + # pygrep-hooks (PGH) + # https://docs.astral.sh/ruff/rules/#pygrep-hooks-pgh + "PGH", + + # Pylint (PL) + # https://docs.astral.sh/ruff/rules/#pylint-pl + "PL", + + # tryceratops (TRY) + # https://docs.astral.sh/ruff/rules/#tryceratops-try + "TRY", + + # flynt (FLY) + # https://docs.astral.sh/ruff/rules/#flynt-fly + "FLY", + + # NumPy-specific rules (NPY) + # https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy + "NPY", + + # Airflow (AIR) + # https://docs.astral.sh/ruff/rules/#airflow-air + "AIR", + + # Perflint (PERF) + # https://docs.astral.sh/ruff/rules/#perflint-perf + "PERF", + + # refurb (FURB) + # https://docs.astral.sh/ruff/rules/#refurb-furb + "FURB", + + # flake8-logging (LOG) + # https://docs.astral.sh/ruff/rules/#flake8-logging-log + "LOG", + + # Ruff-specific rules (RUF) + # https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf + "RUF", +] + diff --git a/MANIFEST.in b/MANIFEST.in index 354b92d735..28eaf30baa 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -14,6 +14,7 @@ exclude .gitignore exclude .mailmap exclude .pre-commit-config.yaml exclude .readthedocs.yml +exclude .ruff.toml exclude CHANGES exclude CODE_OF_CONDUCT.md exclude codecov.yml diff --git a/README.md b/README.md index 233c0edd39..493aa87681 100644 --- a/README.md +++ b/README.md @@ -9,15 +9,15 @@ analysing and visualising Earth science data -| | | -|------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| ⚙️ CI | [![ci-manifest](https://github.com/SciTools/iris/actions/workflows/ci-manifest.yml/badge.svg)](https://github.com/SciTools/iris/actions/workflows/ci-manifest.yml) [![ci-tests](https://github.com/SciTools/iris/actions/workflows/ci-tests.yml/badge.svg)](https://github.com/SciTools/iris/actions/workflows/ci-tests.yml) [![ci-wheels](https://github.com/SciTools/iris/actions/workflows/ci-wheels.yml/badge.svg)](https://github.com/SciTools/iris/actions/workflows/ci-wheels.yml) [![pre-commit](https://results.pre-commit.ci/badge/github/SciTools/iris/main.svg)](https://results.pre-commit.ci/latest/github/SciTools/iris/main) | -| 💬 Community | [![Contributor Covenant](https://img.shields.io/badge/contributor%20covenant-2.1-4baaaa.svg)](https://www.contributor-covenant.org/version/2/1/code_of_conduct/) [![GH Discussions](https://img.shields.io/badge/github-discussions%20%F0%9F%92%AC-yellow?logo=github&logoColor=lightgrey)](https://github.com/SciTools/iris/discussions) [![twitter](https://img.shields.io/twitter/follow/scitools_iris?color=yellow&label=twitter%7Cscitools_iris&logo=twitter&style=plastic)](https://twitter.com/scitools_iris) | -| 📖 Documentation | [![rtd](https://readthedocs.org/projects/scitools-iris/badge/?version=latest)](https://scitools-iris.readthedocs.io/en/latest/?badge=latest) | -| 📈 Health | [![codecov](https://codecov.io/gh/SciTools/iris/branch/main/graph/badge.svg?token=0GeICSIF3g)](https://codecov.io/gh/SciTools/iris) | -| ✨ Meta | [![code style - black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![NEP29](https://raster.shields.io/badge/follows-NEP29-orange.png)](https://numpy.org/neps/nep-0029-deprecation_policy.html) [![license - bds-3-clause](https://img.shields.io/github/license/SciTools/iris)](https://github.com/SciTools/iris/blob/main/LICENSE) [![conda platform](https://img.shields.io/conda/pn/conda-forge/iris.svg)](https://anaconda.org/conda-forge/iris) | -| 📦 Package | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.595182.svg)](https://doi.org/10.5281/zenodo.595182) [![conda-forge](https://img.shields.io/conda/vn/conda-forge/iris?color=orange&label=conda-forge&logo=conda-forge&logoColor=white)](https://anaconda.org/conda-forge/iris) [![pypi](https://img.shields.io/pypi/v/scitools-iris?color=orange&label=pypi&logo=python&logoColor=white)](https://pypi.org/project/scitools-iris/) [![pypi - python version](https://img.shields.io/pypi/pyversions/scitools-iris.svg?color=orange&logo=python&label=python&logoColor=white)](https://pypi.org/project/scitools-iris/) | -| 🧰 Repo | [![commits-since](https://img.shields.io/github/commits-since/SciTools/iris/latest.svg)](https://github.com/SciTools/iris/commits/main) [![contributors](https://img.shields.io/github/contributors/SciTools/iris)](https://github.com/SciTools/iris/graphs/contributors) [![release](https://img.shields.io/github/v/release/scitools/iris)](https://github.com/SciTools/iris/releases) | +| | | +|------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ⚙️ CI | [![ci-manifest](https://github.com/SciTools/iris/actions/workflows/ci-manifest.yml/badge.svg)](https://github.com/SciTools/iris/actions/workflows/ci-manifest.yml) [![ci-tests](https://github.com/SciTools/iris/actions/workflows/ci-tests.yml/badge.svg)](https://github.com/SciTools/iris/actions/workflows/ci-tests.yml) [![ci-wheels](https://github.com/SciTools/iris/actions/workflows/ci-wheels.yml/badge.svg)](https://github.com/SciTools/iris/actions/workflows/ci-wheels.yml) [![pre-commit](https://results.pre-commit.ci/badge/github/SciTools/iris/main.svg)](https://results.pre-commit.ci/latest/github/SciTools/iris/main) | +| 💬 Community | [![Contributor Covenant](https://img.shields.io/badge/contributor%20covenant-2.1-4baaaa.svg)](https://www.contributor-covenant.org/version/2/1/code_of_conduct/) [![GH Discussions](https://img.shields.io/badge/github-discussions%20%F0%9F%92%AC-yellow?logo=github&logoColor=lightgrey)](https://github.com/SciTools/iris/discussions) [![twitter](https://img.shields.io/twitter/follow/scitools_iris?color=yellow&label=twitter%7Cscitools_iris&logo=twitter&style=plastic)](https://twitter.com/scitools_iris) | +| 📖 Documentation | [![rtd](https://readthedocs.org/projects/scitools-iris/badge/?version=latest)](https://scitools-iris.readthedocs.io/en/latest/?badge=latest) | +| 📈 Health | [![codecov](https://codecov.io/gh/SciTools/iris/branch/main/graph/badge.svg?token=0GeICSIF3g)](https://codecov.io/gh/SciTools/iris) | +| ✨ Meta | [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![code style - black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![NEP29](https://raster.shields.io/badge/follows-NEP29-orange.png)](https://numpy.org/neps/nep-0029-deprecation_policy.html) [![license - bds-3-clause](https://img.shields.io/github/license/SciTools/iris)](https://github.com/SciTools/iris/blob/main/LICENSE) [![conda platform](https://img.shields.io/conda/pn/conda-forge/iris.svg)](https://anaconda.org/conda-forge/iris) | +| 📦 Package | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.595182.svg)](https://doi.org/10.5281/zenodo.595182) [![conda-forge](https://img.shields.io/conda/vn/conda-forge/iris?color=orange&label=conda-forge&logo=conda-forge&logoColor=white)](https://anaconda.org/conda-forge/iris) [![pypi](https://img.shields.io/pypi/v/scitools-iris?color=orange&label=pypi&logo=python&logoColor=white)](https://pypi.org/project/scitools-iris/) [![pypi - python version](https://img.shields.io/pypi/pyversions/scitools-iris.svg?color=orange&logo=python&label=python&logoColor=white)](https://pypi.org/project/scitools-iris/) | +| 🧰 Repo | [![commits-since](https://img.shields.io/github/commits-since/SciTools/iris/latest.svg)](https://github.com/SciTools/iris/commits/main) [![contributors](https://img.shields.io/github/contributors/SciTools/iris)](https://github.com/SciTools/iris/graphs/contributors) [![release](https://img.shields.io/github/v/release/scitools/iris)](https://github.com/SciTools/iris/releases) | | |

diff --git a/docs/src/whatsnew/latest.rst b/docs/src/whatsnew/latest.rst index 884bfd376a..05bb9ef7b5 100644 --- a/docs/src/whatsnew/latest.rst +++ b/docs/src/whatsnew/latest.rst @@ -166,6 +166,8 @@ This document explains the changes made to Iris for this release :doc:`../developers_guide/release_do_nothing`. (:pull:`5515`) +#. `@bjlittle`_ adopted and configured the `ruff`_ linter. (:pull:`5623`) + .. comment Whatsnew author names (@github name) in alphabetical order. Note that, @@ -181,4 +183,5 @@ This document explains the changes made to Iris for this release .. _NEP29 Drop Schedule: https://numpy.org/neps/nep-0029-deprecation_policy.html#drop-schedule .. _codespell: https://github.com/codespell-project/codespell +.. _ruff: https://github.com/astral-sh/ruff .. _split attributes project: https://github.com/orgs/SciTools/projects/5?pane=info diff --git a/pyproject.toml b/pyproject.toml index 88b39f1601..5d6e232d22 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,6 +58,37 @@ Discussions = "https://github.com/SciTools/iris/discussions" Documentation = "https://scitools-iris.readthedocs.io/en/stable/" Issues = "https://github.com/SciTools/iris/issues" +[tool.ruff] +# Exclude the following, in addition to the standard set of exclusions. +# https://docs.astral.sh/ruff/settings/#exclude +extend-exclude = [ + "_ff_cross_references.py", + "um_cf_map.py", + "docs/src/sphinxext", + "tools", +] +line-length = 79 +src = [ + "benchmarks", + "lib", + "docs/src", +] +target-version = "py39" + +[tool.ruff.lint] +ignore = [ + # NOTE: Non-permanent exclusions should be added to the ".ruff.toml" file. + + # flake8-implicit-str-concat (ISC) + # https://docs.astral.sh/ruff/rules/single-line-implicit-string-concatenation/ + # NOTE: This rule may cause conflicts when used with "ruff format". + "ISC001", # Implicitly concatenate string literals on one line. + ] + preview = false + select = [ + "ALL", + ] + [tool.setuptools] license-files = ["LICENSE"] zip-safe = false