Home/Blog/How to Use the Flake8, isort, and Black to Ruff Migration Prompt Without Breaking CI
Blog

How to Use the Flake8, isort, and Black to Ruff Migration Prompt Without Breaking CI

P
promptstudio

Move a Python repo from Flake8 plus plugins, isort, and Black to Ruff. Get a rule by rule mapping, a ready tool.ruff block for pyproject.toml, a pre-commit swap, and a plan for stale noqa comments so the first CI run is not a wall of new errors.

How to Use the Flake8, isort, and Black to Ruff Migration Prompt Without Breaking CI

Many Python teams run three tools to keep code tidy: Flake8 with a handful of plugins for linting, isort for import order, and Black for formatting. Ruff can replace all three with one fast binary and one config block in pyproject.toml. The hard part is not installing Ruff. The hard part is moving years of agreed lint behavior across without quietly changing what gets flagged. The Flake8, isort, and Black to Ruff Migration: pyproject.toml Config with Rule Mapping and a noqa Cleanup Plan prompt does that translation for you and shows its work.

Why a straight copy of your config fails

Ruff reimplements Flake8, its popular plugins, isort, and Black, but the defaults differ. Flake8 selects the E, F, W, and C90 families by default. Ruff only enables a smaller subset of E plus F unless you tell it otherwise. If you drop in ruff check and delete .flake8, you may lose checks your team relied on and never notice.

There are also rules Ruff does not implement at all, such as W503 and W504, and rules that exist only in preview, such as E203. Teams using Black usually ignore those exact codes in Flake8, so the good news is that those ignores can often be deleted. The prompt tells you which is which instead of leaving you to read changelogs.

What the prompt produces

  1. A rule mapping table that lists every Flake8 family and plugin, the matching Ruff prefix, and any gap.
  2. A ready pyproject.toml block with line-length and target-version from your Black settings, an explicit select list, translated per-file-ignores, mccabe complexity, isort options, and formatter settings.
  3. A formatter conflict check that removes rules Ruff recommends disabling when you also run ruff format.
  4. A pre-commit swap that removes the Black, isort, and Flake8 hooks and adds the Ruff lint hook with --fix before the format hook.
  5. A noqa cleanup plan using RUF100 to find stale suppressions and --add-noqa for a baseline when the first run is too noisy.
  6. A rollout order that keeps formatting churn in its own commit.

How to fill the inputs

Paste Flake8Config exactly as it appears in setup.cfg, tox.ini, or .flake8, including extend-ignore and per-file-ignores. List every installed plugin in Plugins, and say if you only use one for a single suppression. That detail matters: in the example, flake8-bandit is installed only so tests can silence S101, so the prompt leaves the whole S family out rather than turning on dozens of security checks nobody asked for.

IsortConfig and BlackConfig should include line length, profile, first party packages, and source paths. PythonVersion sets target-version, which controls which pyupgrade style rules are safe. CI tells the prompt whether to rewrite pre-commit hooks, a GitHub Actions job, or a Makefile target.

Reading the example output

The sample repo uses a 100 character line, Python 3.10, bugbear, comprehensions, and pep8-naming. A few decisions in the output are worth copying:

  • The select list is explicit. E, W, F, C90, B, C4, N, and I are written out so behavior matches the old Flake8 run.
  • E203 and W503 ignores are gone, with the reason stated, instead of being copied forward as dead config.
  • W191 is ignored because it overlaps with the formatter, while preview only rules are left alone.
  • The S101 per-file ignore is dropped because S is not selected, and RUF100 will catch any leftover noqa: S101 comments.
  • The hook rev is a placeholder. The prompt never invents a Ruff version, so you pin the one you actually install.

A rollout that reviewers will thank you for

Split the change into four commits. First the config and hook swap. Second, ruff format on its own, with that commit hash added to .git-blame-ignore-revs so blame stays useful. Third, ruff check --fix for import sorting and simple rewrites. Fourth, remove the old tools from dev dependencies once CI is green. Each commit is small enough to review, and if something surprises you, it is easy to revert one step.

Mistakes to avoid

  • Relying on Ruff defaults. Always write select so the rule set is a decision, not an accident.
  • Mixing formatting churn with rule changes. Reviewers cannot see real changes inside thousands of whitespace edits.
  • Leaving stale noqa comments. They hide real problems later. Run RUF100 once after the switch.
  • Guessing plugin equivalents. If a plugin has no Ruff counterpart, keep it out and note the gap, which is what the prompt does.

Who it is for

This prompt suits platform engineers, tech leads, and maintainers of Python services or libraries who want faster linting without a week of config archaeology. Pair it with your test suite and a quick look at Ruff's own rule docs for anything flagged as a gap.

Related PromptDig links