RuffでPythonコードの品質を楽に底上げする

photo of golden cogwheel on black background

Ruffとは

Ruff は Python の リンター(バグの芽やコード規約違反の検出)と フォーマッタ(整形)を ひとつにまとめた高速なコード品質改善ツールです。Rustで実装されているので動作がキビキビしており、未使用インポートの削除や軽微な書き換えなどの自動修正(Autofix)まで一本でこなします。VS Codeなどのエディタとも連携しやすく、保存時に「整形+Lint+自動修正」を回す運用が簡単に作れます。

フォーマット/Lint/Autofix(自動修正)を中心に、VS Code連携設定の最小例、そして実際にどうコードが変わるのかまで記載します。

実装サンプルとそのポイント

インストール

どれか一つでOKです。

# pip / uv
pip install ruff
# または
uv add ruff

基本コマンド

基本コマンドはこれだけ。

ruff check    # Lint(問題検出)
ruff format   # フォーマット(整形)

実例:未使用インポート削除と軽いオートフィックス(ruff check --fix)

before: app.py
使用しないimportを含むなど低品質なサンプルコード。

import os
import sys
from pathlib import Path

def cwd():
    temp = 42
    return Path.cwd()

コマンド(修正箇所確認)

修正が必要な個所を理由とともに表示してくれる。

ruff check

app.py:1:1 F401 'os' imported but unused
app.py:2:1 F401 'sys' imported but unused
app.py:5:5 F841 local variable 'temp' is assigned to but never used
[*] 2 fixable with the `--fix` option.

コマンド(自動修正実行)

–fix を指定することで未使用インポートなど修正が必要な個所を自動修正してくれる。

ただし未使用なローカル変数 temp (F841)についても自動修正するには –unsafe-fixes を指定する必要があり。

ruff check --fix

after: app.py

from pathlib import Path

def cwd():
    temp = 42
    return Path.cwd()

実例:インポート整列(isort 相当、I ルール)

before: imports_demo.py

パッケージのインポート順が不適当な例。

from mypkg.utils import foo
import requests
import json
from pathlib import Path
import numpy as np

コマンド

以下のコマンドを実行するとパッケージのインポート順を自動修正する。

ruff check --select I --fix

after

import json
from pathlib import Path

import numpy as np
import requests

from mypkg.utils import foo
  • 標準 → サードパーティ → ローカル の順でグループ化。
  • 各グループは アルファベット順

実例:読みやすさの底上げ(ruff format)

特に複数人で開発する場合、コーディング規約に従ってコードフォーマットが統一されているほうが保守の観点からも好ましい。そこで必要になるのがコードの自動成型機能。

before: format_demo.py

1行で辞書型のdataが宣言されていたりとフォーマットがバラバラな低品質コード。

def compute(a,b,c=  3,*,scale= 1.5,verbose=False):
    if verbose: print('start');   result=a+b+c*scale;  return result
data = {"a":1,"b":[1,2,3,4,5,6,7,8,9,10],"c":(1,2,3)}
long = "a very long piece of text that will exceed the 88 character line length when concatenated " + "so the formatter should wrap it nicely and keep things readable for humans"
def greet(name:str="world")->None: print('hello, '+name)

コマンド

–fix なしで自動的にフォーマット成形される点に注意。

ruff format

after

成形されており読みやすい。

def compute(a, b, c=3, *, scale=1.5, verbose=False):
    if verbose:
        print("start")
    result = a + b + c * scale
    return result


data = {
    "a": 1,
    "b": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    "c": (1, 2, 3),
}

long = (
    "a very long piece of text that will exceed the 88 character line length "
    "when concatenated so the formatter should wrap it nicely and keep things "
    "readable for humans"
)


def greet(name: str = "world") -> None:
    print("hello, " + name)

ポイント

  • 関数シグネチャの空白型注釈のスペース調整。
  • セミコロン連結を 1行1文 に分割。
  • 長い文字列は括弧内の複数行に自動折り返し(line-length 準拠)。
  • 辞書/リスト/タプルのスペース・カンマ・末尾カンマを安定化。

小ネタ:整形内容だけ見たいときは ruff format --diff

迷ったらこの順番で実行(CLIワンショット例)

全部ケア

ruff check --fix .
ruff check --select I --fix .
ruff format .

pyproject.tomlの設定

ruffのいいところは各機能の設定をpyproject.tomlで指定できる点。デフォルト強め+少し足すのがラクです。Ruffは既定で Flake8 の F 系+一部 E 系が有効。

[tool.ruff]
line-length = 88
target-version = "py311"   # 例:プロジェクトの下限に合わせる(py37〜py313対応)

[tool.ruff.lint]
# 既定の選択に加えて、行長(E501)とインポート整列(I; isort相当)を有効化
select = ["E4", "E7", "E9", "F", "E501", "I"]

# (任意)“Unsafe”な自動修正もまとめて許可したい場合(意味が変わる可能性あり)
# unsafe-fixes = true

VS Code連携

VS Code上でファイル保存時にruffによる静的解析+自動修正を実行する環境を構築することもできる。

下準備としてRuff開発元のAstral Softwareの提供する拡張機能をインストールしておく。

そしてプロジェクト側の .vscode/settings.json に下記を追記することで、コードを保存する際に必要に応じでフォーマット+自動修正+インポート整列が実行される。この設定をしておくだけで自動的にコード品質が楽に底上げされるのでここまでを1セットとしたい。

{
  "[python]": {
    "editor.defaultFormatter": "charliermarsh.ruff",
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
      "source.fixAll.ruff": "explicit",
      "source.organizeImports.ruff": "explicit"
    }
  }
}

まとめ

Ruffを導入してPythonのコード品質を自動的に底上げする方法についてまとめました。特にVS Codeとの連携はコーディングと同時にコード品質を一定にしてくれるので非常に重宝しています。

コメント