JavaScriptを有効にしてください

【Python】blackとisortをRuffで置き換える

 ·   5 min read

※記事内に商品プロモーションを含むことがあります。

はじめに

PythonのフォーマッタblackとisortをRuffに置き換える設定方法を調査しました。
この記事ではリンター機能には触れません。

検証環境は以下の通りです。

  • Windows 10 Home 22H2
  • Python 3.13.1
  • Ruff 0.11.0
  • black 25.1.0
  • isort 6.0.1

結論

Ruffの以下2つのコマンドでblackとisortを代替できます(設定ファイルを使用すると--select Iオプションは省略可能)。

1
2
ruff format foo.py
ruff check --fix --select I foo.py

上から順にblack, isortの機能に相当します。foo.pyは対象のスクリプトファイルやフォルダに変更して下さい。

また、上記のコマンドではファイルが変更されます。変更せずに差分をターミナルに表示したい場合、以下のように--diffオプションを付けます。

1
2
ruff format --diff foo.py
ruff check --diff --select I foo.py

以降でRuffの利点、コマンドや設定の詳細を述べます。

Ruffの利点

blackやisortはPythonで実装されているのに対して、RuffはRustで実装されています。
そのため、公式サイト にはRuffはblackの10~100倍、高速に動作すると書かれています。

⚡️ 10-100x faster than existing linters (like Flake8) and formatters (like Black)

また、blackやisortをターミナル (PowerShell) で実行したときに文字に色があまり付かないのに対して、Ruffでは色付きで見やすい長所もあります。

blackとisortで変更差分を表示した例:

black-isort-diff

Ruffで変更差分を表示した例:

ruff-diff

Ruffコマンドの詳細

blackとisortの機能は、Ruffの異なるサブコマンドで実行されます。

blackによるスクリプト全体のフォーマットの場合、ruff formatサブコマンドとなります。

コマンド 機能
ruff format コードを修正
ruff format --diff コードの修正箇所を表示

一方、isortによるインポート順のソートは、Ruffのリンター機能に含まれます。
そのため、ruff checkサブコマンドとなります。

コマンド 機能
ruff check コードの問題点を表示
ruff check --diff コードの修正箇所を表示
ruff check --fix コードを修正

また、Ruffのデフォルト設定では、isortの機能は無効になっています。
有効にするには、ruff checkサブコマンドに--select Iオプションを付けます。
例を以下に示します。

1
ruff check --diff --select I foo.py

Iはisortを意味します。

また、Ruffはpyproject.tomlに設定を記述することもできます。その場合は以下のように書きます。

1
2
[tool.ruff.lint]
select = ["I"]

ただし、select = ["I"]とするとisort以外のリンター機能は無効になります。
デフォルトのリンター機能を有効にしたままisortを追加する場合、select = ["E4", "E7", "E9", "F", "B", "I"]として下さい。
いずれにしても、select"I"を追加した場合、コマンドから--select Iオプションを省略してもisortの機能が有効になります。

Ruffのデフォルト設定

次に、blackとisortに関連するRuffのデフォルト設定をpyproject.toml形式で示します。

black関連

Ruffのフォーマットに関するデフォルト設定は、blackのデフォルト設定とほぼ同じです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[tool.ruff]
# 1行の最大文字数
line-length = 88

# インデント1個あたりの半角スペースの数
indent-width = 4

# Pythonの最小バージョン
target-version = "py39"
# ただし以下のような書き方が推奨される。
# [project]
# requires-python = ">=3.9"

[tool.ruff.format]
# 文字列をダブルクォーテーションで囲む。
# "double" | "single" | "preserve"
quote-style = "double"

# インデントはタブではなく半角スペース
# "space" | "tab"
indent-style = "space"

# falseの場合、改行されたリスト等の要素の末尾にカンマを付ける
skip-magic-trailing-comma = false

# 改行の文字コード。
# "auto" | "lf" | "cr-lf" | "native"
line-ending = "auto"

# docstrings内のPythonコードをフォーマットするか否か。
# Markdown, reStructuredTextのコードブロックやdoctestsをサポートしている。
# 将来のバージョンではデフォルトでtrueになる予定
docstring-code-format = false

# docstrings内のPythonコードをフォーマットするときの1行の長さの設定。
# `docstring-code-format`がtrueの場合のみ有効。
# int | "dynamic"
docstring-code-line-length = "dynamic"

isort関連

Ruffのisortに関するデフォルト設定も、isortのデフォルト設定とほぼ同じです。
ただし、isortとblackのデフォルト設定は競合しているため(後述)、black側に統一されています。

Ruffのisortに関する設定は約30個と多いです。
ここでは3つの設定のデフォルト値を示します。

1
2
3
4
5
6
7
8
9
[tool.ruff.lint.isort]
# trueの場合、大文字と小文字を区別する
case-sensitive = false

# trueの場合、アルファベット順ではなく文字数でソート(短い方が先頭)する
length-sort = false

# importセクションの順
section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]

blackとisortの競合

blackとisortのデフォルト設定では、from importの文が最大長さを超えたときの処理が異なります。
black(およびRuff)のデフォルト設定では、以下のように1要素ずつ改行されます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from numpy import (
    cos,
    int8,
    int16,
    int32,
    int64,
    sin,
    tan,
    uint8,
    uint16,
    uint32,
    uint64,
)

isortのデフォルト設定では、最大長さに収まり、かつ行数が少なくなるように改行されます。
ただし、設定でblackと同じスタイルに変更できます。

1
2
from numpy import (cos, int8, int16, int32, int64, sin, tan, uint8, uint16,
                   uint32, uint64)
シェアする

Helve
WRITTEN BY
Helve
関西在住、電機メーカ勤務のエンジニア。X(旧Twitter)で新着記事を配信中です

サイト内検索