はじめに
VSCode 用の Ruff extension for Visual Studio Code の設定
環境
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
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
に以下のように記載する。
{
"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"
}
使い勝手を考えると以下の設定も関連するので記載する。
{
// 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
のリントやフォーマットの挙動は、
- CLI オプション(コマンドライン引数)
- 設定ファイル
の順で設定できる。
CLI オプションは、VSCode を使用するとほとんど使わないと思うが、settings.json
の
{
"ruff.lint.args": [],
"ruff.format.args": []
}
で設定できる。
以下のように、キーワード=値
のように渡さないといけない事に注意。
{
"ruff.lint.args": [
"--config=<PATH>",
"--ignore=['F401']"
],
}
設定ファイル
設定ファイルの名前は、
pyproject.toml
ruff.toml
.ruff.toml
で指定する。
pyproject.toml
と、ruff.toml
・.ruff.toml
は、テーブル名の記述が若干違うので注意。
toml ファイルの探索順は、以下の通り。
-
--config=<Path>
で指定したファイル。
settings.json
のruff.lint.args
かruff.format.args
に指定する。 - py ファイルと同じフォルダ
- 親のフォルダ
- プロジェクトルートフォルダ
$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
のデフォルト設定は以下の通り。
# 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
に、以下のように記載する事で指定出来る。
line-length = 88
indent-width = 4
リントのルール
設定ファイルでリントのルールを設定する場合、select
で指定する。
追加で指定したい場合は、extended-select
を使用する。
extended-select
で指定したものが上書きされるのか、select
に競合しない場合にのみ適用されるのか、どちらになるか具体的な記載が無いので分からない。
また、ignore
で特定のルールを無視させる事も出来る。
[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
に指定したルールは、修正されない。
[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を開き、OutputChannel
をRuff
に合わせるとRuff
からのメッセージが表示される。
動作がおかしいと思ったらここを見る。
追加されるコマンドと関連コマンド
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
で調整するのが良さそう。
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"