Skip to content

Commit

Permalink
Update 'unsafe' code actions (#55)
Browse files Browse the repository at this point in the history
 - Update unsafe code actions to contain `(unsafe)` at the end of the
   message
 - Prevent the `Fix All` code action from applying unsafe codeactions
 - Update the README to mention this behaviour
  • Loading branch information
jhossbach committed Nov 25, 2023
1 parent 9ba6e51 commit 2744452
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 9 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ lspconfig.pylsp.setup {
}
```

## Code actions

`python-lsp-ruff` supports code actions as given by possible fixes by `ruff`. `python-lsp-ruff` also supports [unsafe fixes](https://docs.astral.sh/ruff/linter/#fix-safety).
Fixes considered unsafe by `ruff` are marked `(unsafe)` in the code action.
The `Fix all` code action *only* consideres safe fixes.

## Configuration

Configuration options can be passed to the python-language-server. If a `pyproject.toml`
Expand Down
10 changes: 7 additions & 3 deletions pylsp_ruff/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,10 @@ def pylsp_code_actions(
if diagnostic.data: # Has fix
fix = converter.structure(diagnostic.data, RuffFix)

# Ignore fix if marked as unsafe and unsafe_fixes are disabled
if fix.applicability != "safe" and not settings.unsafe_fixes:
continue
if fix.applicability == "unsafe":
if not settings.unsafe_fixes:
continue
fix.message += " (unsafe)"

if diagnostic.code == "I001":
code_actions.append(
Expand Down Expand Up @@ -359,6 +360,9 @@ def create_fix_all_code_action(
title = "Ruff: Fix All"
kind = CodeActionKind.SourceFixAll

# No unsafe fixes for 'Fix all', see https://github.com/python-lsp/python-lsp-ruff/issues/55
settings.unsafe_fixes = False

new_text = run_ruff_fix(document=document, settings=settings)
range = Range(
start=Position(line=0, character=0),
Expand Down
14 changes: 8 additions & 6 deletions tests/test_code_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def f():
codeactions = [
"Ruff (F401): Remove unused import: `os`",
"Ruff (F401): Disable for this line",
"Ruff (F841): Remove assignment to unused variable `a`",
"Ruff (F841): Remove assignment to unused variable `a` (unsafe)",
"Ruff (F841): Disable for this line",
"Ruff: Fix All",
]
Expand All @@ -70,7 +70,9 @@ def temp_document(doc_text, workspace):
def test_ruff_code_actions(workspace):
_, doc = temp_document(codeaction_str, workspace)

workspace._config.update({"plugins": {"ruff": {"select": ["F"]}}})
workspace._config.update(
{"plugins": {"ruff": {"select": ["F"], "unsafeFixes": True}}}
)
diags = ruff_lint.pylsp_lint(workspace, doc)
range_ = cattrs.unstructure(
Range(start=Position(line=0, character=0), end=Position(line=0, character=0))
Expand All @@ -79,8 +81,8 @@ def test_ruff_code_actions(workspace):
workspace._config, workspace, doc, range=range_, context={"diagnostics": diags}
)
actions = converter.structure(actions, List[CodeAction])
for action in actions:
assert action.title in codeactions
action_titles = list(map(lambda action: action.title, actions))
assert sorted(codeactions) == sorted(action_titles)


def test_import_action(workspace):
Expand All @@ -104,8 +106,8 @@ def test_import_action(workspace):
workspace._config, workspace, doc, range=range_, context={"diagnostics": diags}
)
actions = converter.structure(actions, List[CodeAction])
for action in actions:
assert action.title in codeactions_import
action_titles = list(map(lambda action: action.title, actions))
assert sorted(codeactions_import) == sorted(action_titles)


def test_fix_all(workspace):
Expand Down

0 comments on commit 2744452

Please sign in to comment.