17
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[VSCode] Ruffの設定メモ

Last updated at Posted at 2023-11-11

はじめに

VSCode 用の Ruff extension for Visual Studio Code の設定

環境

vscode
Version: 1.84.2 (user setup)
Commit: 1a5daa3a0231a0fbba4f14db7ec463cf99d7768e
Date: 2023-11-09T10:51:52.184Z
Electron: 25.9.2
ElectronBuildId: 24603566
Chromium: 114.0.5735.289
Node.js: 18.15.0
V8: 11.4.183.29-electron.0
OS: Windows_NT x64 10.0.22631
code --list-extensions --show-versions
charliermarsh.ruff@2023.50.0

インストール

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

Extension の設定

Ruff に渡せるセッティングは、以下の通り。

  • lint.args
  • path
  • interpreter
  • importStrategy
  • lint.run
  • enable
  • organizeImports
  • fixAll
  • codeAction.fixViolation.enable
  • codeAction.disableRuleComment.enable
  • showNotification

さらに、ReadMe に記載がないが

  • format.args
  • trace.server

も渡せる。

実際に VSCode へ渡すときは、settings.jsonに以下のように記載する。

settings.json
{
  "ruff.lint.args": [], // ruff checkに渡す追加のコマンドライン引数。設定ファイル(ruff.tomlなど)より優先される
  "ruff.path": [], // ruffの実行パス
  "ruff.interpreter": [], // pythonの実行パス
  "ruff.importStrategy": "fromEnvironment", // "fromEnvironment": 環境にruffがインストールされている場合は、そちらを使う。 "useBundled": Extension付属のruffを使う。
  "ruff.lint.run": "onType", // "onType": 入力度にruffを実行。 "onSave":保存時にruffを実行。
  "ruff.enable": true, // ruffを有効にするか否か。
  "ruff.organizeImports": true, // source.organizeImports を実行するのにruffを使用するか否か。
  "ruff.fixAll": true, // source.fixAll を実行するのにruffを使用するか否か。
  "ruff.codeAction.fixViolation": { // Quick Fix を表示するか否か。
    "enable": true
  },
  "ruff.codeAction.disableRuleComment": { // # nopa でQuick Fixを無視するか否か。
    "enable": true
  },
  "ruff.showNotifications": "always", // ruffの通知を表示するか否か。 "off", "onError", "onWarning", "always"
  "ruff.format.args": [], // ruff formatに渡す追加のコマンドライン引数。 設定ファイル(ruff.tomlなど)より優先される
  "ruff.trace.server": "off" // "off", "message", "verbose"
}

使い勝手を考えると以下の設定も関連するので記載する。

setting.json
{
  // global 設定
  "editor.formatOnSave": true, // 保存時にフォーマットするか。
  "editor.formatOnPaste": false, // 貼り付け時にフォーマットするか。
  "editor.formatOnType": false, // 入力時にフォーマットするか。
  "editor.formatOnSaveMode": "file", // "file": 常にファイル全体をフォーマット、 "modifications": 修正された所のみフォーマット。SourceControlが必要。 "modificationsIfAvailable": 修正された所のみフォーマットを試みる。SourceControlが無い場合、ファイル全体をフォーマット。
  // "editor.defaultFormatter": "charliermarsh.ruff" // デフォルトのformatterにruffを指定。
  "editor.codeActionsOnSave": {
    "source.fixAll": true, // (デフォルトに設定されているもので)fixAllを実行。
    // "source.fixAll.ruff": true, // ruffのfixAllを明示的に使用。
    "source.organizeImports": true, // (デフォルトに設定されているもので)organizeImportsを実行。
    // "source.organizeImports.ruff": true //ruffのorganizeImportsを明示的に使用。
  },

  // python file
  "[python]": {
    "editor.formatOnSave": true,
    "editor.formatOnPaste": false,
    "editor.formatOnType": false,
    "editor.formatOnSaveMode": "file",
    "editor.defaultFormatter": "charliermarsh.ruff", // 別のものを指定するとフォーマットは指定したものになる
    "editor.codeActionsOnSave": { // 保存時に実行する
      "source.fixAll": true, // (登録した)fixAllを実行。
      // "source.fixAll.ruff": true, // ruffのfixAllを明示的に使用。
      "source.organizeImports": true, // (登録した)organizeImportsを実行。
      // "source.organizeImports.ruff": true //ruffのorganizeImportsを明示的に使用。
    }
  },
}

これで VSCode からRuffが呼ばれるようになる。

Ruff の設定

Ruffのリントやフォーマットの挙動は、

  1. CLI オプション(コマンドライン引数)
  2. 設定ファイル

の順で設定できる。

CLI オプションは、VSCode を使用するとほとんど使わないと思うが、settings.json

settings.json
{
  "ruff.lint.args": [],
  "ruff.format.args": []
}

で設定できる。

以下のように、キーワード=値のように渡さないといけない事に注意。

settings.json
{
 "ruff.lint.args": [
    "--config=<PATH>",
    "--ignore=['F401']"
  ],
}

設定ファイル

設定ファイルの名前は、

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

で指定する。

pyproject.tomlと、ruff.toml.ruff.tomlは、テーブル名の記述が若干違うので注意。

toml ファイルの探索順は、以下の通り。

  1. --config=<Path>で指定したファイル。
    settings.jsonruff.lint.argsruff.format.argsに指定する。
  2. py ファイルと同じフォルダ
  3. 親のフォルダ
  4. プロジェクトルートフォルダ
  5. $config_dir\ruff

グローバル設定を指定したい場合は、$config_dir\ruffに置く。

$config_dirがどこかと言うと以下のようになる。

OS Path example
Linux $XDG_CONFIG_HOME or $HOME/.config /home/UserName/.config
macOS $HOME/Library/Application Support /Users/UserName/Library/Application Support
Windows {FOLDERID_RoamingAppData} C:\Users\UserName\AppData\Roaming

UserName は、実際のユーザ名に置き換える。
{FOLDERID_RoamingAppData}は、$env:APPDATAのようだ。

つまり、Windows の場合は、
$env:APPDATA\ruff(C:\Users\UserName\AppData\Roaming\ruff)
に置く

デフォルト設定

ruff.tomlのデフォルト設定は以下の通り。

ruff.toml
# Exclude a variety of commonly ignored directories.
exclude = [
    ".bzr",
    ".direnv",
    ".eggs",
    ".git",
    ".git-rewrite",
    ".hg",
    ".mypy_cache",
    ".nox",
    ".pants.d",
    ".pytype",
    ".ruff_cache",
    ".svn",
    ".tox",
    ".venv",
    "__pypackages__",
    "_build",
    "buck-out",
    "build",
    "dist",
    "node_modules",
    "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"

詳しくは、

を参照。

1行の文字数とインデントの長さの設定

ruff.tomlに、以下のように記載する事で指定出来る。

ruff.toml
line-length = 88
indent-width = 4

リントのルール

設定ファイルでリントのルールを設定する場合、selectで指定する。
追加で指定したい場合は、extended-selectを使用する。
extended-selectで指定したものが上書きされるのか、selectに競合しない場合にのみ適用されるのか、どちらになるか具体的な記載が無いので分からない。
また、ignoreで特定のルールを無視させる事も出来る。

ruff.toml
[lint]
select = []
extend-select =[]
ignore = []

指定できるルールとしては、以下のようなものがある。

  • E: pycodestyleのルール
  • F: Pyflakesのルール
  • UP: pyupgradeのルール
  • B: flake8-bugbearのルール
  • SIM: flake8-simplifyのルール
  • ANN: flake8-annotationsのルール
  • I: isortのルール
  • ALL: 全てのルールを適用する。ただし、競合するものは、無効になる。

また、F401のようにすると対象のルールのみを指定できる。

AutoFix のルール

fixable に指定したルールは、Ruff に修正される。
unfixable に指定したルールは、修正されない。

ruff.toml
[lint]
fixable = []
extend-fixable =[]
unfixable = []
extend-unfixable=[]

Ruff のフォーマッターと競合するために、設定しない方が良いリンタールール。

  • tab-indentation (W191)
  • indentation-with-invalid-multiple (E111)
  • indentation-with-invalid-multiple-comment (E114)
  • over-indented (E117)
  • indent-with-spaces (D206)
  • triple-single-quotes (D300)
  • bad-quotes-inline-string (Q000)
  • bad-quotes-multiline-string (Q001)
  • bad-quotes-docstring (Q002)
  • avoidable-escaped-quote (Q003)
  • missing-trailing-comma (COM812)
  • prohibited-trailing-comma (COM819)
  • single-line-implicit-string-concatenation (ISC001)
  • multi-line-implicit-string-concatenation (ISC002)

同じく競合するために設定しない方が良いisortルール

  • force-single-line
  • force-wrap-aliases
  • lines-after-imports
  • lines-between-types
  • split-on-trailing-comma

Python コメントでの Ruff の制御

リントの制御

# noqaをインラインに入れると、その行では警告を出さない。
# noqa: {code}をインラインに入れると、その行では{code}に対して警告を出さない。
# ruff: noqaをファイルに記述すると、そのファイルでは警告を出さない。
# ruff: noqa: {code}をファイルに記述すると、そのファイルでは{code}に対して警告を出さない。
RUF100を lint に設定すると不必要な# noqaに対して警告を出してくれる。

# Ignore F841.
x = 1  # noqa: F841

# Ignore E741 and F841.
i = 1  # noqa: E741, F841

# Ignore _all_ violations.
x = 1  # noqa

フォーマットの制御

# fmt: off# fmt: onで囲むことで文単位(statement level)でフォーマットを抑制できる。
式単位(expression level)では効かない

# fmt: off
[
    '1',
    '2',
]
# fmt: on

preceding statement, case header, decorator, function definition, or class definition が対象の場合は、# fmt: skipを使う。

# fmt: skip comments suppress formatting for a preceding statement, case header, decorator, function definition, or class definition:
if True:
    pass
elif False: # fmt: skip
    pass

@Test
@Test2 # fmt: skip
def test(): ...

a = [1, 2, 3, 4, 5] # fmt: skip

def test(a, b, c, d, e, f) -> int: # fmt: skip
    pass

エラーメッセージの確認

output panelを開き、OutputChannelRuffに合わせるとRuffからのメッセージが表示される。
動作がおかしいと思ったらここを見る。

image.png

追加されるコマンドと関連コマンド

  • Ruff: Fix all auto-fixable problems
{
  "key": "",
  "command": "ruff.executeAutofix"
}
  • Ruff: Fix all auto-fixable problems
{
  "key": "",
  "command": "ruff.executeAutofix"
}
  • Ruff: Format document
{
  "key": "",
  "command": "ruff.executeFormat"
}
  • Ruff: Format imports
{
  "key": "",
  "command": "ruff.executeOrganizeImports"
}
  • Ruff: Restart Server
{
  "key": "",
  "command": "ruff.restart"
}
  • Auto Fix...
{
  "key": "shift+alt+oem_period",
  "command": "editor.action.autoFix",
  "when": "textInputFocus && !editorReadonly && supportedCodeAction =~ /(\\s|^)quickfix\\b/"
}
  • Quick Fix...
{
  "key": "ctrl+oem_period",
  "command": "editor.action.quickFix",
  "when": "editorHasCodeActionsProvider && textInputFocus && !editorReadonly"
}
  • Fix All
{
  "key": "",
  "command": "editor.action.fixAll"
}
  • Format Document
{
  "key": "shift+alt+f",
  "command": "editor.action.formatDocument",
  "when": "editorHasDocumentFormattingProvider && editorTextFocus && !editorReadonly && !inCompositeEditor"
}
  • Organize Imports
{
  "key": "shift+alt+o",
  "command": "editor.action.organizeImports",
  "when": "textInputFocus && !editorReadonly && supportedCodeAction =~ /(\\s|^)source\\.organizeImports\\b/"
}

自分の設定

メモとして、とりあえず設定した内容を記載して置く。
select = ["ALL"]にして、ignoreで調整するのが良さそう。

ruff.toml
exclude = [
  ".bzr",
  ".direnv",
  ".eggs",
  ".git",
  ".git-rewrite",
  ".hg",
  ".mypy_cache",
  ".nox",
  ".pants.d",
  ".pytype",
  ".ruff_cache",
  ".svn",
  ".tox",
  ".venv",
  "__pypackages__",
  "_build",
  "buck-out",
  "build",
  "dist",
  "node_modules",
  "venv",
]

indent-width = 2
line-length = 120

target-version = "py311"

[lint]
ignore = ["D", "ANN", "ERA001", "T201", "FBT003", "G004", "PLR0913", "RUF100", "E741"]
select = ["ALL"]

# print (T201): printがあると警告を出す
# commented-out-code (ERA001)
# flake8-annotations (ANN): アノテーション全般
# pydocstyle (D): docstring 全般
# boolean-positional-value-in-call (FBT003)
# logging-f-string (G004)
# too-many-arguments (PLR0913)
# unused-noqa (RUF100)
# ambiguous-variable-name (E741)

fixable = ["ALL"]
unfixable = ["F401"]

dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[format]
indent-style = "space"
quote-style = "double"

skip-magic-trailing-comma = false # list等の最後の要素の後のコンマを削除しない。

line-ending = "lf" # "auto" | "lf" | "cr-lf" | "native"
17
13
1

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
17
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?