🐥

PythonのRuff LinterをVSCodeで使う

2023/06/07に公開

Ruffはrust製の高速なPython用Linterです。

https://github.com/charliermarsh/ruff

README上部に記載の通り既存のPython Linterに比べてはるかに高速であると謳っています。

PylintやFlake8, banditなどのlinterは拡張機能を入れなくてもVSCodeのsettings.jsonに記述すれば使用できるようになります。
訂正: Pylintなども拡張機能を入れる必要があるように変更になりました。
https://code.visualstudio.com/docs/python/linting

RuffをVSCodeと統合するには公式のVSCode拡張をインストールします。

https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff

またlint指摘だけではなく実行時に"--fix"オプションが指定されるとコードの自動修正まで行ってくれます。

lint指摘のハイライト

拡張機能を入れるだけでコード上のlint指摘箇所をハイライトしてくれます。
pythonコードを開くとruff check --no-fixコマンドが走りlintを実行してくれているようです。
lintを実行したくない、拡張機能はいれたままで特定のワークスペースではruffを実行したくない、といった場合は拡張機能を「無効にする(ワークスペース)」状態にするか、settings.jsonに以下のような記載をします

settings.json
{
    "ruff.enable": false, // ruff拡張機能全体を無効化
    "ruff.lint.enable": false // lint機能を実行しない、デフォルトtrue
}

ファイル保存時にRuffの各機能を実行する

ruffがコードを変更する機能は以下の3つ

  • フォーマット(ruff format)
  • check指摘箇所の修正 (ruff check --fix)
  • importの順序整理

ファイル保存時に自動で指摘箇所を修正する(ruff check --fix)場合

settings.json
{
    "[python]": {
        "editor.codeActionsOnSave": {
            "source.fixAll": "explicit"
        }
    }
}

"source.organizeImports": "explicit"を指定するとisortのようにimportの整列をしてくれます。

settings.json
{
    "[python]": {
        "editor.codeActionsOnSave": {
            "source.organizeImports": "explicit"
        }
    }
}

VSCode環境で他のLinter拡張機能を入れているなどしてRuff以外が実行されるのを防ぐためには明示的にruffでfix, import整列を行うことを指定できます。

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

逆にimportの整列はisortでやりたい、という場合はruffのimport整列は明示的にoffにします

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

Formatterとしてruffを指定する場合、defaultFormatterにruffを指定

settings.json
{
    "[python]": {
        "editor.defaultFormatter": "charliermarsh.ruff",
        "editor.formatOnSave": true,
    }
}

つまり3つの機能すべてを使用するなら以下のように記載します

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

他のフォーマッタを使用したい場合は以下のように記述します。この場合ruffのfix(importの自動ソート)が行われた後にBlackによるフォーマットが実行されます。

settings.json
{
    "[python]": {
        "editor.defaultFormatter": "ms-python.black-formatter",
        "editor.formatOnSaveMode": "file", // BlackはSaveModeがfileのみ対応
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
            "source.organizeImports.ruff": "explicit"
        }
    }
}

拡張機能は特定のバージョンのRuffが組み込まれています。そちらを使いたくない場合は"ruff.path": ["/path/to/ruff"]のように使用したいruffのパスをsettings.jsonに記載します。

また"ruff.lint.args"で実行時のオプションを指定できます

settings.json
{
    "ruff.lint.args": ["--extend-exclude=/tests/**/*.py"]
}

Ruffの設定の書き方

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

Ruffで使用するルール、除外するファイルなどの設定はpyproject.tomlruff.toml.ruff.tomlに書けます。

pyproject.toml

[tool.ruff]
# Same as Black.
line-length = 88

# Assume Python 3.10.
target-version = "py310"

[tool.ruff.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 = []

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

Discussion