Skip to content

BLD: switch from isort to ruff in prek config - #32408

Merged
timhoffm merged 2 commits into
matplotlib:mainfrom
tacaswell:sty/drop_isort
Sep 30, 2026
Merged

timhoffm merged 2 commits into
matplotlib:mainfrom
tacaswell:sty/drop_isort

Conversation

@tacaswell

Copy link
Copy Markdown
Member

PR summary

We already are using ruff for most of our linting, switch to it as well for import sorting in the examples.

This caused some minor changes to the imports due to ruff not being a perfect drop-in replacement, but I think it is worth a bit of churn to get down to just one lint/formatting tools.

Applying ruff's version of import sorting to the whole code base hits 357 files which is too much churn to be worth it (we already were not running isort on the main library) and I do have some concern that our internal imports may have some cycles and hence sensitive to the import order (the tests do pass, but still seems like a high-risk choice).

AI Disclosure

I used an LLM to translate from isort's spelling of our configuration to ruff's spelling of the configuration. The first commit is LLM work, the second is running ruff.

PR quality check

  • Use an expressive title, e.g. "Fix title font property precedence"
  • [/] New and changed code is tested
  • [/] Plotting related features are demonstrated in an example
  • [/] New features and API changes have release notes
  • [/] Documentation complies with general and docstring guidelines

This drops a job from the hooks which should make them faster.

Assisted-by: opencode:claude-sonnet-5
There are a few trivial changes:

 - drop \ import line continuation
 - slightly different tie-breaking in mixed from .. import .. and import ..
 - accept ruff-style line wrapping

Still only applies to the galleries.
@tacaswell tacaswell added this to the v3.12.0 milestone Sep 28, 2026
@github-actions github-actions Bot added CI: Run cibuildwheel Run wheel building tests on a PR Documentation: examples files in galleries/examples Documentation: tutorials files in galleries/tutorials labels Sep 28, 2026
MinuteLocator, MonthLocator, RRuleLocator, SecondLocator,
WeekdayLocator, YearLocator, rrulewrapper)
from matplotlib.dates import (
FR,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went looking for whether we want this long import line broken up now and then said "where is this even used?", and it is because we are using eval later... I feel like we probably shouldn't be advertising/encouraging the usage of eval in our examples, but that also isn't a part of this PR so just noting the thoughts I had when reading this for now and someone can follow up later.

Comment thread .pre-commit-config.yaml
args: [--fix, --show-fixes]
# Sort imports in the galleries, mirroring the previous isort scope.
- id: ruff-check
name: ruff isort (galleries)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be rolled into the ruff-check above?

Thinking that we'd want to add these files to the per-file-ignores/includes lists for the "I" rule, then we wouldn't have to run a separate command.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 25cd1b2cff..8b1fea6c68 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -46,14 +46,11 @@ repos:
     # Ruff version.
     rev: c59bba8fb259db0fec2bbb77ad8ba51ea7341b56  # frozen: v0.15.20
     hooks:
-      # Run the linter.
+      # Run the linter. Import sorting (I001) is selected repo-wide but
+      # ignored outside the galleries via per-file-ignores in pyproject.toml,
+      # mirroring the previous isort scope.
       - id: ruff-check
         args: [--fix, --show-fixes]
-      # Sort imports in the galleries, mirroring the previous isort scope.
-      - id: ruff-check
-        name: ruff isort (galleries)
-        args: [--fix, --show-fixes, --select=I001]
-        files: ^galleries/tutorials/|^galleries/examples/|^galleries/plot_types/
   - repo: https://github.com/codespell-project/codespell
     rev: 2ccb47ff45ad361a21071a7eedda4c37e6ae8c5a  # frozen: v2.4.2
     hooks:
diff --git a/pyproject.toml b/pyproject.toml
index b6970faa50..91783c92a0 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -213,6 +213,7 @@ select = [
     "E",
     "F",
     "W",
+    "I001",
     "UP035",
     # The following error codes require the preview mode to be enabled.
     "E111",
@@ -287,6 +288,14 @@ force-sort-within-sections = true
 pydata = ["numpy", "matplotlib.pyplot"]
 
 [tool.ruff.lint.per-file-ignores]
+# I001 (import sorting) is only enforced in the galleries (matching the
+# previous isort scope); ignore it everywhere else.
+"ci/**" = ["I001"]
+".circleci/**" = ["I001"]
+"doc/**" = ["I001"]
+"lib/**" = ["I001"]
+"tools/**" = ["I001"]
+"galleries/users_explain/**" = ["I001"]
 "*.pyi" = ["E501"]
 "*.ipynb" = ["E402"]
 "doc/conf.py" = ["E402"]

We can get there, but I'm not sure that it is worth "turn it on and exclude it almost everywhere" to save a second ruff (which is fast) invocation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, I was assuming we wouldn't need so many exclusions or we'd eventually move on that direction. We can update it to that invocation later if we do go that route.

@timhoffm
timhoffm merged commit 825479c into matplotlib:main Sep 30, 2026
39 of 40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI: Run cibuildwheel Run wheel building tests on a PR Documentation: examples files in galleries/examples Documentation: tutorials files in galleries/tutorials

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants