RuffをPythonコードに。

2024/09/23に公開

なにこれ

Ruffは、Pythonコードの静的解析を行い、コードスタイルの問題や潜在的なバグを検出します。また、コードの自動フォーマット機能も提供しており、コードの一貫性を保つのに役立ちます。Ruffは高速なパフォーマンスを誇り、大規模なコードベースでも効率的に動作します。

以下の役割を担う。

  • 静的解析
  • フォーマッター
  • リンター
  • インポートソーター

https://docs.astral.sh/ruff/

なにが嬉しいの?

  1. 1個だけ入れればOKになる。
    • プラグインの追加が不要。
    • isortとかflake8とか不要。
  2. 動作が早い。
    • Rustでできてる。
    • ruff-lspという専用LSP内蔵。
  3. 自動修正機能搭載。
    • エディタからもCLIからも修正可能。
  4. 設定しやすい。
    • 既存のライブラリ(isortやflake8とか)のルールがそのまま使えると思ってOK
    • pyproject.tomlとかruff.tomlにルールを設定できる。
  5. 様々なエディタで利用可能。
    • vscode
    • vim
    • emacs
    • zed
    • etc

引用

  • ⚡️ (Flake8のような)既存のリンターや(Blackのような)フォーマッタよりも10-100倍高速
  • 🐍 pip経由でインストール可能
  • 🛠️ pyproject.tomlのサポート
  • 🤝 Python 3.13との互換性
  • ⚖️ Flake8、isort、Blackとのドロップインパリティ
  • 📦 未変更ファイルの再分析を回避するためのキャッシュ機能内蔵
  • 🔧 自動エラー修正(例えば、未使用のインポートを自動的に削除)のための修正サポート
  • 📏 800以上の組み込みルール、 800 以上の組み込みルール。flake8-bugbear のような一般的な Flake8 プラグインをネイティブで再実装
  • ⌨️ VS Code などのファーストパーティエディタとの統合
  • 🌎 階層的でカスケード可能なコンフィギュレーションでモノレポフレンドリー。

インストール方法

RuffはPythonパッケージとして提供されており、pipを使用して簡単にインストールできます。

pip install ruff

また、最新の機能や修正を利用したい場合は、pipxを使用してインストールすることも推奨されます。

pipx install ruff
poetry add --group dev ruff

設定方法

ruffではflake8blackなどデフォルトで有効になっているルールがある。
つまりデフォルトで無効になっているルールもある。

デフォルトで有効のものは上書きで設定することになり、デフォルトで無効になっているものは有効にする必要がある。

設定方法の例

RuffはデフォルトでPEP 8に準拠したルールを適用しますが、設定ファイルを使用してカスタマイズが可能です。

  • selectで有効、ignoreで無効
  • FやIとすると関連するルールを全て設定できる。
  • E501とすると特定のルールのみ指定することになる。
  • ルールの適用をディレクトリやファイルで絞り込める。
pyproject.toml
[tool.ruff]
select = ["E502", "F", "I"]  
ignore = ["E501", "F841"]

[tool.ruff.per-file-ignores]
"tests/*.py" = ["E501", "F841"]  

設定例の引用

pyproject.toml
pyproject.toml
# Exclude a variety of commonly ignored directories.
exclude = [
    ".bzr",
    ".direnv",
    ".eggs",
    ".git",
    ".git-rewrite",
    ".hg",
    ".ipynb_checkpoints",
    ".mypy_cache",
    ".nox",
    ".pants.d",
    ".pyenv",
    ".pytest_cache",
    ".pytype",
    ".ruff_cache",
    ".svn",
    ".tox",
    ".venv",
    ".vscode",
    "__pypackages__",
    "_build",
    "buck-out",
    "build",
    "dist",
    "node_modules",
    "site-packages",
    "venv",
]

# Same as Black.
line-length = 88
indent-width = 4

# Assume Python 3.8
target-version = "py38"

[lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`)  codes by default.
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
# McCabe complexity (`C901`) by default.
select = ["E4", "E7", "E9", "F"]
ignore = []

# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[format]
# Like Black, use double quotes for strings.
quote-style = "double"

# Like Black, indent with spaces, rather than tabs.
indent-style = "space"

# Like Black, respect magic trailing commas.
skip-magic-trailing-comma = false

# Like Black, automatically detect the appropriate line ending.
line-ending = "auto"

# Enable auto-formatting of code examples in docstrings. Markdown,
# reStructuredText code/literal blocks and doctests are all supported.
#
# This is currently disabled by default, but it is planned for this
# to be opt-out in the future.
docstring-code-format = false

# Set the line length limit used when formatting code snippets in
# docstrings.
#
# This only has an effect when the `docstring-code-format` setting is
# enabled.
docstring-code-line-length = "dynamic"

設定ファイルの作成とカスタマイズ

Ruffはプロジェクトルートに設定ファイルを配置することで、チェックのルールや動作をカスタマイズできます。設定ファイルは以下のいずれかの形式で作成できます。

  • pyproject.toml
  • .ruff.toml
  • ruff.toml

例: pyproject.toml の設定

[tool.ruff]
# 無効にするエラーチェック
ignore = ["E501", "W503"]

# 最大行長の設定
line-length = 88

# 使用するPythonのバージョン
target-version = "py39"

# 自動修正を有効にする
fix = true

詳細な設定オプションについては、Ruffの公式ドキュメントを参照してください。

基本的な使い方

Ruffを使用してPythonファイルやディレクトリ全体をチェックする基本的なコマンドは以下の通りです。

# 特定のファイルをチェック
ruff path/to/file.py

# ディレクトリ全体をチェック
ruff path/to/directory/
# checkの後にPATHを指定できる。省略すると全てが範囲に指定される。
ruff check

# --fixで修正できる。
ruff check --fix

エディタとの統合

Ruffは多くのエディタと統合でき、リアルタイムでのコードチェックや自動修正をサポートします。以下は一般的なエディタでの設定方法です。

Visual Studio Code (VSCode)

  1. 拡張機能のインストール:

  2. 設定の確認:

    • settings.json に以下を追加してRuffをデフォルトのリンターとして設定します。
    {
        "python.linting.enabled": true,
        "python.linting.ruffEnabled": true,
        "python.formatting.provider": "ruff",
        "editor.formatOnSave": true
    }
    

その他のエディタ

  • Vim/Neovim: alecoc.nvimなどのプラグインを使用してRuffを統合できます。
  • Sublime Text: LSPプラグインと組み合わせてRuffを使用できます。
  • JetBrains製品(PyCharmなど): 外部ツールとしてRuffを設定し、コードチェックに利用できます。

自動修正とフォーマット

Ruffは自動修正機能を提供しており、検出された問題を自動的に修正できます。以下のコマンドを使用します。

# 自動修正を実行
ruff --fix path/to/file_or_directory/

pyproject.tomlfix = true を設定すると、デフォルトで自動修正が有効になります。

他のツールとの連携

Ruffは他の開発ツールとも簡単に統合できます。特に、pre-commitフックとして使用することで、コミット前に自動でコードチェックや修正を行うことが可能です。

pre-commitとの連携

  1. pre-commitのインストール:

    pip install pre-commit
    
  2. .pre-commit-config.yamlの設定:

    repos:
      - repo: https://github.com/charliermarsh/ruff-pre-commit
        rev: v0.0.241  # 最新のタグに置き換えてください
        hooks:
          - id: ruff
            args: [--fix]
    
  3. pre-commitの有効化:

    pre-commit install
    

これにより、コミット時にRuffが自動的にコードをチェックし、必要に応じて修正を行います。

よく使うコマンドとオプション

  • 特定のエラーのみを表示:

    ruff path/to/file.py --select E501,W503
    
  • 特定のエラーを無視:

    ruff path/to/file.py --ignore E501,W503
    
  • 詳細な出力:

    ruff path/to/file.py --verbose
    
  • 特定のディレクトリを除外:

    ruff path/to/project --exclude tests/
    

トラブルシューティング

  • Ruffが認識されない:

    • インストールが正しく行われているか確認してください。ruff --versionコマンドでバージョン情報が表示されるか確認します。
  • 設定ファイルが反映されない:

    • 設定ファイルがプロジェクトルートに配置されていることを確認し、形式(.toml)が正しいかチェックしてください。
  • エディタで動作しない:

    • エディタのRuffプラグインや設定が正しく行われているか確認し、必要に応じて再インストールや設定の見直しを行ってください。

参考文献

公式の設定方法の記載箇所

https://docs.astral.sh/ruff/settings/

公式のルールの記載箇所

https://docs.astral.sh/ruff/rules/

Discussion