「綺麗なコードを書きたい」という気持ちは、すべてのエンジニアの心に宿る願いです。
しかしながら、「納期が…」「まずは動くものを…」という現代社会におけるとめどない流れの中でままならないことも多いでしょう。
そんな悩みを解決する一助となるコードフォーマッター。
今回はPythonのコードフォーマッターの中で、昨今最も注目を浴びているRuffについて紹介します。
Ruffとは
RuffはRust製のPythonコードフォーマッターです。Rust製ですが、Python向けツールとなります。
ここ最近、Rustはその汎用性と高速さを武器に、さまざまなソフトウェアのサポートツールが続々と生まれてきています。そのような流れにおける傑作の1つなのがRuffです。
とにかく速い、という特徴がありますが、その他の特徴も下記に列挙します。
- (
Flake8のような)既存linterや(Blackのような)既存フォーマッターより10~100倍高速 pipでインストール可能pyproject.tomlサポート- 最新安定版のPython 3.12もサポート
Flake8、isort、Blackと共存可能- キャッシュ搭載、変更なしのファイルを再検査しない
- (使われていない
importの削除など)自動エラー修正 - 700を越える規約ルール含む
- VSCode等、各種エディタをサポート(
ruff-lspによるもの) - モノレポフレンドリー
とにかく全部盛りで、しかも高速というのが売りです。
FastAPI開発者など、Python界隈の名だたるビッグネームがその高速さを称賛しています。
Ruffのインストール
ここまででRuffの魅力は伝わったはずなので早速インストールしましょう。
先述した通り、pipでインストールできます。
pip install ruff$ ruff --version
ruff 0.1.3Ruffの簡単なサンプル
動作を確認するために、修正点のあるコードを書いてみましょう。
import datetime as dt
def hello_world():
print("Hello world!")もちろんこのコードは正常に動作します。ただ、美しくはありません。
このコードをRuffで修正してみましょう。
ruff check ファイル名でコードの検査ができます。ファイル名を.にすることで、カレントディレクトリを起点に検査可能です。
ruff check .これによって、以下のように出力されます。
使われていないdatetimeモジュールがあることを報告しています。
wrong.py:1:20: F401 [*] `datetime` imported but unused
Found 1 error.
[*] 1 fixable with the `--fix` option.--fixオプションをつけることで、このコードを自動修正してくれます。
ruff check --fix .すると、コードから使っていないdatetimeモジュールが取り除かれました。
このように、必要ではないコードが除去されたことでよりクリーンなコードへと生まれ変わるのです。
Ruffの設定
開発チームでコード規約を作る際、共通の設定にしたくなるケースは多々あります。
Ruffはpyproject.toml、ruff.toml、または.ruff.tomlを親ディレクトリに設置することによってコード規約を設定可能です。
例として、pyproject.tomlをルートディレクトリに作ってみましょう。
以下は一行が長すぎる場合にNGを出すパターンです。(Flake8でデフォルトの79文字)
[tool.ruff]
line-length=79
[tool.ruff.lint]
extend-select = ["E501"]Ruffで検査、整形
以下のコードを検査してみましょう。
def so_long_list():
l = ['Apple', 'Banana', 'Chocolate', 'Cookie', 'Peech', 'Orange', 'Cake', 'Pizza', 'Cheeze', 'Beer']
[print(i) for i in l]ruff check .これは下記のような出力をします。
wrong.py:2:5: E741 Ambiguous variable name: `l`
wrong.py:2:80: E501 Line too long (104 > 79)
Found 2 errors.ついでに曖昧な変数名についても注意されました。一旦、本筋とは違うのでfood_listに修正します。
def so_long_list():
food_list = ['Apple', 'Banana', 'Chocolate', 'Cookie', 'Peech', 'Orange', 'Cake', 'Pizza', 'Cheeze', 'Beer']
[print(food) for food in food_list]これで一行の長さだけ報告されるようになります。
ここで、フォーマッター機能を試しましょう。formatコマンドによって、コードの整形が可能です。
ruff format .この実行によって、以下のようにコードが整形されます。
def so_long_list():
food_list = [
"Apple",
"Banana",
"Chocolate",
"Cookie",
"Peech",
"Orange",
"Cake",
"Pizza",
"Cheeze",
"Beer",
]
[print(food) for food in food_list]一行の長さを正当にし、配列を読みやすくしてくれました。
Ruffで覚えておくべきコマンド、オプション
Ruffは高速でありつつ、多くの機能が含まれているので主要なコマンドとオプションを覚えておきましょう。
| コマンド | 説明 |
|---|---|
| コードの分析を行う |
| コード規約ルールの説明を表示 |
| キャッシュクリア |
| コード整形を行う |
| オプション | 説明 |
|---|---|
ruff check --fix | 修正を適用 |
ruff check --watch | 監視モードでリアルタイム検査 |
ruff check --config [設定ファイルパス] | 設定ファイルを指定 |
ruff format --diff | 整形対象を表示 |
まずはこのあたりを覚えておくことをおすすめします。
その他のコマンドやオプションを知りたい方はこちらから参照してみてください。
Pythonのコードを高速にチェックしたいならRuff
今回は小さなコードスニペットの検査だけだったので、高速にチェックが終わってしまいましたが、これが大きなプロジェクトになればなるほどRuffの高速さが顕著になっていきます。
すでにBlackやFlake8、isortを取り入れているプロジェクトでも、Ruffの導入は比較的安全なので、ぜひ検討してみてください。
GitHub Actionsやpre-commitと組み合わせることも多いlinterですが、開発者体験を底上げしてくれる高速なlinter兼フォーマッターのRuffは導入必須な素晴らしいツールです。
pre-commitでPythonプロジェクトをblack/flake8/isort/mypy/banditで管理する




