|

2025-01-24

Tips

Python の Linter / Formatter をまとめられる Ruff を試す

PythonCI/CD

新しい Python 用の Linter/Formatter である Ruff を試す

PythonのLinter/Formatter事情

Pythonに限った話ではないですが、チーム開発において、コードの品質と一貫性を保つために欠かせないものといえば、Linter / Formatterですよね。

 

しかし、こういった環境設定に関するツールは 一度設定すると見直す機会が少なく、最新のツールや手法から取り残される… なんてことは「あるある」なのではないかと思います。

 

Python でいうと、よく使っている組みあわせは

  • Flake8 (Linter = スタイル・バグ検出)

  • Black (Formatter = コードの自動整形・一貫性担保)

  • isort (importの並べ替え)

  • mypy (型チェック)

などかと思います。実際、身の回りにはこの組みあわせで動いているプロジェクトが多いです。

 

2025年の1月にはpoetryがバージョン2になったこともあって、最近環境を見直そうと思うようになりました。

その中で Linter/Formatter も見直すことにしたら、最近は Ruff という高速なツールが伸びているということに気付きました。

 

Ruff の登場

Ruff はRustで実装された高速なPython用のLinter兼Formatterです。

特に推されているポイントは下記の通りです。

  • Rust製であり 高速であること

  • 各種Linter/Formatterツールがオールインワンになっていること(Flake8 + Black + isort)みたいな入れ方をしなくてよい

 

公式ドキュメントの How does Ruff compare to Mypy, or Pyright, or Pyre? のページに

Ruff is a linter, not a type checker. (中略) It's recommended that you use Ruff in conjunction with a type checker, like Mypy, Pyright, or Pyre, with Ruff providing faster feedback on lint violations and the type checker providing more detailed feedback on type errors.

とあるとおり、mypy のような型チェック機能は内包されていないので別途入れる必要がありますが、Ruffとmypyだけで済みそうなのは魅力的です。あと、速いは正義ですよね。

 

というわけで、早速既存プロジェクトを置き換えてみます。

 

実際に移行を試してみる

Python 環境側の設定

とりあえず ruff をいれます。

poetry で管理している場合は

poetry add --group dev ruff

ですね。(もちろん poetry をつかっていなければ pip install でOKです。)

ついでにFlake8/Black/isortを消しておきます。

poetry remove pyproject-flake8 isort black

 

VSCode の設定

続いてVSCode側の設定です。

まずは VSCodeのRuff 拡張をインストールします。

Shift + Cmd(Ctrl) + P 等でコマンドパレットを呼び出し「Open User Settings(JSON)」を選択。元々の設定から editor.defaultFormatter を変更します

(プロジェクトローカルのみの設定としたい場合はプロジェクトルート内に .vscode/settings.json を作成)

たとえば、 Black を使っていた場合は

"[python]": { // (中略) "editor.defaultFormatter": "ms-python.black-formatter" },

から

"[python]": { // (中略) "editor.defaultFormatter": "charliermarsh.ruff" },

でOKです。

 

pyproject.toml の設定

地味に面倒な作業はここです。

[tool.flake8][tool.black] などで指定している値を [tool.ruff] として指定し直す必要があります。

たとえば、下記のような簡易的な設定は…

[tool.flake8] max-line-length = 119 max-complexity = 10 select = "C,E,F,W,B" ignore = "E203, W503" [tool.black] line-length = 119

置き換えると下記のようになります。

[tool.ruff] line-length = 119 select = ["C", "E", "F", "W", "B"] ignore = ["E203"]

と、こうみるとそこまで複雑ではないのですが、たとえばこの例でいうと W503 がなくなっていますよね。なぜかというと、Ruffにおいて未実装だから、だったりします。

そういった検証が挟まるので、元々の設定が複雑であればあるほどここは時間が掛かるかもしれません。

 

ちなみにLint 部分は [tool.ruff.lint] 等で指定することも可能です: 公式ドキュメントのConfiguring Ruff のページ が参考になります。

個人的には isort の際の空行の入り方が気になるので no-lines-before の指定を入れています。 (公式ドキュメント: no-lines-before)

[tool.ruff.lint.isort] no-lines-before = ["first-party"]

 

実際に試す

以上でとりあえずの設定はOKです。VSCode上で簡単に動作確認できると思います。

一応コマンドライン上で試す場合は… (poetryの場合)

Lint

poetry run ruff check

Format

poetry run ruff format

となります。(poetry でない場合は PATH が通っていれば poetry run を外せばOKです)

速い! となるはずなのでコマンドで試すのがオススメです。

 

まとめ

今回は Linter/Formatter がオールインワンになっている Ruff の導入手順についてまとめました。

実際試してみると動作はめちゃくちゃ速いですが、個人的には既存構成でもそこまで遅いと感じたことはなかったのでもう少し「待ち」でもいいかなと感じました。

2025/01/24 現在のバージョンは0.9.2ということで、開発も活発なので、 v1 リリースで本格導入かな、という印象です。

 

こういったツールは冒頭でも述べたとおり見直しの機会がなかなかないかもしれませんが、TypeScript/JavaScript であれば Biome のような新しいツールも出てきていたり、サーベイすると意外と乗り換えたほうがいいかも…と思えてくるので、定期的に情報をキャッチアップしておきたいですね。

 


この記事の著者

プロフィール画像

伴 拓也

朝日放送グループホールディングス株式会社 DX・メディアデザイン局 デジタル・メディアチーム

アプリケーションからインフラ、ネットワーク、データエンジニアリングまで幅広い守備範囲が売り。最近はデータ基盤の構築まわりに力を入れて取り組む。 主な実績として、M-1グランプリ敗者復活戦投票システムのマルチクラウド化等。