Skip to content

Update 'unsafe' code actions (#55) #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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