LoginSignup
16
7

【Python】Linterとして選ばれたのは「Ruff」でした

Last updated at Posted at 2023-10-10

はじめに

2022年頃まで、Pythonの開発でLinterやFormaterを導入する場合、以下のツールを採用することが多く見受けられていました。

ツール 用途
Flake8 Linter
Pylint Linter
isort Import Sorter
Black Formatter

そんな中、これらのツールに対して一石を投じるようなツールが登場しました。それがRuffです。
本稿は、そんなRuffを導入する際の足がかりとして参考になれば幸いです。

Ruffについて

Rustで書かれた非常に高速なPythonのLinterです。

Ruffの特徴

Ruffの特徴として以下のようなものが挙げられます。

⚡️ 既存のリンターよりも 10 ~ 100 倍高速
🐍 経由でインストール可能pip
🛠️ pyproject.tomlサポート
🤝 Python 3.12 との互換性
📦 組み込みのキャッシュにより、変更されていないファイルの再分析を回避します
🔧 自動エラー修正のサポートを修正 (例: 未使用のインポートを自動的に削除)
📏 700 を超える組み込みルール
⚖️ 組み込みの Flake8 ルールセットとほぼ同等
🔌 flake8-bugbear など、数十の Flake8 プラグインのネイティブ再実装
⌨️ VS Codeなどの ファーストパーティエディターの統合
🌎 モノリポに適しており、階層的およびカスケード構成を備えています
https://docs.astral.sh/ruff/ より抜粋

個人的には、以下の点に魅力を感じました。

  • 既存のLinterから置き換えが可能
    • 主要なLinterのルールをサポートしており、一部ツールに関しては移行ツールも提供されています
  • 既存のLinterよりも高速
    • 開発中の待ち時間が減り、開発体験の向上に繋がります
  • PEP621に準拠(pyproject.tomlサポート)
    • ツールごとで独自の設定ファイルで管理する必要がなくなり、メンテナンスが容易になります

静的解析ツールのトレンド

Ruffの公式ブログで公開されていた、Pythonの開発で広く利用されているツールのGitHub Star数の推移図が以下になります。
image.png
Ruffは破竹の勢いでGitHub Starが増えており、注目度の高さが見てとれます。
※本稿執筆時点で確認したところ、Star数は18,000を超えていました。

セットアップ

ローカル環境やエディタ、CI環境への導入方法は以下の通りです。

ローカル環境

ローカルで実行するにあたり、pre-commitを使って実行させる場合は以下のように設定します。

.pre-commit-config.yaml
- repo: https://github.com/astral-sh/ruff-pre-commit
  rev: v0.0.292
  hooks:
    - id: ruff
      args: [--config, pyproject.toml]

エディタ(VSCode)

Ruff公式からVSCode向けのExtentionが提供されているので、そちらを利用します。
https://github.com/astral-sh/ruff-vscode

保存時に自動で実行させたい場合は、以下のように設定します。

settings.json
{
  "[python]": {
    "editor.codeActionsOnSave": {
      "source.fixAll.ruff": true,
      "source.organizeImports.ruff": true
    }
  }
}

他にも柔軟に設定ができるので、上記以外の設定はこちらを参照してください。

CI環境(GitHub Actions)

GitHub Actionsで実行させる場合は、以下のように設定します。

.github/workflows/ruff.yml
name: Ruff
on: [ push, pull_request ]
jobs:
  ruff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: chartboost/ruff-action@v1
        with:
            src: "./src"
            version: 0.0.292
            args: --config pyproject.toml

詳細はこちらを参照してください。

パフォーマンス

実行時間を計測するにあたり、以下のような条件で計測しました。

コードボリューム

  • Pythonファイル数・・・・・・約1800ファイル
  • Pythonファイル合計行数・・・約26万行

設定ファイル

pyproject.toml
[tool.ruff]
target-version="py39"
select = [
    "E",
    "F",
    "W",
    "I",
    "Q",
]
line-length = 119
[tool.ruff.flake8-quotes]
inline-quotes = "single"

[tool.ruff.isort]
force-single-line = true

実行結果

参考までに、Ruffへの移行前と移行後の実行時間を比較してみましたが、20〜30倍ほど高速化されていることが分かります。

ツール 実行時間 備考
Flake8 26.06s user 0.57s system 96% cpu 27.565 total Ruff移行前
isort 4.01s user 2.13s system 70% cpu 8.768 total Ruff移行前
Ruff 1.21s user 0.41s system 106% cpu 1.519 total Flake8とisortのルールは同等

Tips

設定ファイルの統合

Ruffの導入以前はFlake8やisortなどの設定ファイルをそれぞれ管理していましたが、Ruffではpyproject.tomlに統一することができます。
詳細はこちらを参照してください。

Ruff導入前

.isort.cfg
[settings]
force_single_line=true
setup.cfg
[flake8]
ignore =
    E501,
    F821
max-line-length = 119
per-file-ignores =
    ./tests/*: E101

Ruff導入後

pyproject.toml
[tool.ruff]
ignore = [
    "E501",
    "F821",
]
select = [
    "E",
    "F",
    "W",
    "I",
]

line-length = 119

[tool.ruff.isort]
force-single-line = true

[tool.ruff.per-file-ignores]
"./tests/*" = ["E101"]

Flake8のルールをRuffに移行する

Ruff公式が提供してくれているflake8-to-ruffを利用することで、Ruff導入以前に適応していたFlake8の設定をRuffに適応させることができます。

ルールの適応方法

すでに開発が進んでいるプロジェクトであれば、上述した移行ツールなどを利用して、既存のルールをRuffに適応させることが多いと思います。
しかし、新規でプロジェクトを立ち上げる場合は、Ruffのルールを全適応させ、必要に応じて無効化する運用が良いと思います。
Ruffであればルールを増やしたとしてもパフォーマンスに影響が出にくく、かつpyproject.tomlで管理できるため、ルールの管理も容易となります。

さいごに

Ruffはリリースから1年ほどしか経過していませんが、既存のLinterから移行するだけの価値がある、非常に魅力的なツールだと感じました。
また、現在はPythonのFormatterとして有名なBlackをサポートする動きもあり、v0.0.289からアルファリリースとして公開されました。
https://github.com/astral-sh/ruff/discussions/7310

(2023/10/26追記)
v0.1.2からベータ版としてフォーマッタがサポートされました!
公式ブログで紹介されているベンチーマークによると、「Blackより30倍、YAPFよりも100倍高速である」とされています。

Ruffは今後ますます注目されるツールになると思います。
今後の動向から目が離せません。

16
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
7