Skip to content

Commit 70e6114

Browse files
authored
Fix #2
Set ruff config to empty dict if pyproject.toml is present
2 parents 69dd6a3 + c8dae9d commit 70e6114

File tree

2 files changed

+45
-94
lines changed

2 files changed

+45
-94
lines changed

pylsp_ruff/ruff_lint.py

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,12 @@
11
import json
22
import logging
3-
import sys
43
from pathlib import PurePath
54
from subprocess import PIPE, Popen, SubprocessError
65

76
from pylsp import hookimpl, lsp
87
from pylsp._utils import find_parents
98
from pylsp.workspace import Document, Workspace
109

11-
# Use built-in tomllib for python>=3.11
12-
if sys.version_info >= (3, 11):
13-
try:
14-
import tomllib
15-
except ImportError:
16-
import tomli as tomllib
17-
else:
18-
import tomli as tomllib
19-
2010
log = logging.getLogger(__name__)
2111

2212
UNNECESSITY_CODES = {
@@ -187,6 +177,8 @@ def build_args(document: Document, options: dict) -> list:
187177
args = ["--quiet"]
188178
# Use the json formatting for easier evaluation
189179
args.extend(["--format=json"])
180+
# Do not attempt to fix -> returns file instead of diagnostics
181+
args.extend(["--no-fix"])
190182

191183
# Convert per-file-ignores dict to right format
192184
per_file_ignores = options.pop("per-file-ignores")
@@ -230,36 +222,38 @@ def load_config(workspace: Workspace, document: Document) -> dict:
230222
config = workspace._config
231223
_settings = config.plugin_settings("ruff", document_path=document.path)
232224

233-
# Default values are given by ruff
234-
settings = {
235-
"config": _settings.get("config", None),
236-
"exclude": _settings.get("exclude", None),
237-
"executable": _settings.get("executable", "ruff"),
238-
"ignore": _settings.get("ignore", None),
239-
"line-length": _settings.get("lineLength", None),
240-
"per-file-ignores": _settings.get("perFileIgnores", None),
241-
"select": _settings.get("select", None),
242-
}
243-
244225
pyproject_file = find_parents(
245226
workspace.root_path, document.path, ["pyproject.toml"]
246227
)
247228

248-
# Load config from pyproject file if it exists
229+
# Check if pyproject is present, ignore user settings if toml exists
249230
if pyproject_file:
250-
try:
251-
log.debug(f"Found pyproject file: {str(pyproject_file[0])}")
252-
253-
with open(str(pyproject_file[0]), "rb") as pyproject_toml:
254-
toml_dict = tomllib.load(pyproject_toml)
255-
256-
toml_config = toml_dict.get("tool", {}).get("ruff", {})
257-
258-
# Update settings with local project settings
259-
for key, value in toml_config.items():
260-
settings[key] = value
231+
log.debug(
232+
f"Found pyproject file: {str(pyproject_file[0])}, "
233+
+ "skipping pylsp config."
234+
)
235+
236+
# Leave config to pyproject.toml
237+
settings = {
238+
"config": None,
239+
"exclude": None,
240+
"executable": _settings.get("executable", "ruff"),
241+
"ignore": None,
242+
"line-length": None,
243+
"per-file-ignores": None,
244+
"select": None,
245+
}
261246

262-
except (tomllib.TOMLDecodeError, OSError) as e:
263-
log.warning(f"Failed loading {str(pyproject_file)}: {e}")
247+
else:
248+
# Default values are given by ruff
249+
settings = {
250+
"config": _settings.get("config", None),
251+
"exclude": _settings.get("exclude", None),
252+
"executable": _settings.get("executable", "ruff"),
253+
"ignore": _settings.get("ignore", None),
254+
"line-length": _settings.get("lineLength", None),
255+
"per-file-ignores": _settings.get("perFileIgnores", None),
256+
"select": _settings.get("select", None),
257+
}
264258

265259
return settings

tests/test_ruff_lint.py

Lines changed: 16 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -116,25 +116,34 @@ def get_ruff_cfg_settings(workspace, doc, config_str):
116116
return ruff_lint.load_config(workspace, doc)
117117

118118

119-
def test_ruff_multiline(workspace):
119+
def test_ruff_config(workspace):
120120
config_str = r"""[tool.ruff]
121+
ignore = ["F481"]
121122
exclude = [
122123
"blah",
123124
"file_2.py"
124125
]
126+
[tool.ruff.per-file-ignores]
127+
"__init__.py" = ["F401", "E402"]
128+
"test_something.py" = ["E402"]
125129
"""
126130

127131
doc_str = "print('hi')\nimport os\n"
128132

129133
doc_uri = uris.from_fs_path(os.path.join(workspace.root_path, "blah/__init__.py"))
130134
workspace.put_document(doc_uri, doc_str)
135+
workspace._config.update({"plugins": {"ruff": {"select": ["E", "F"]}}})
131136

132137
ruff_settings = get_ruff_cfg_settings(
133138
workspace, workspace.get_document(doc_uri), config_str
134139
)
135140

136-
assert "exclude" in ruff_settings
137-
assert len(ruff_settings["exclude"]) == 2
141+
# Check that user config is ignored
142+
for key, value in ruff_settings.items():
143+
if key == "executable":
144+
assert value == "ruff"
145+
continue
146+
assert value is None
138147

139148
with patch("pylsp_ruff.ruff_lint.Popen") as popen_mock:
140149
mock_instance = popen_mock.return_value
@@ -148,66 +157,14 @@ def test_ruff_multiline(workspace):
148157
"ruff",
149158
"--quiet",
150159
"--format=json",
151-
"--exclude=blah,file_2.py",
160+
"--no-fix",
152161
"--",
153162
"-",
154163
]
155164

156-
os.unlink(os.path.join(workspace.root_path, "pyproject.toml"))
157-
158-
159-
def test_ruff_per_file_ignores(workspace):
160-
config_str = r"""[tool.ruff]
161-
ignore = ["F403"]
162-
exclude = [
163-
"file_1.py",
164-
"file_2.py",
165-
]
166-
[tool.ruff.per-file-ignores]
167-
"__init__.py" = ["F401", "E402"]
168-
"test_something.py" = ["E402"]
169-
"""
170-
171-
doc_str = "print('hi')\nimport os\n"
172-
173-
doc_uri = uris.from_fs_path(os.path.join(workspace.root_path, "blah/__init__.py"))
174-
workspace.put_document(doc_uri, doc_str)
175-
176-
ruff_settings = get_ruff_cfg_settings(
177-
workspace, workspace.get_document(doc_uri), config_str
178-
)
179-
180-
assert "per-file-ignores" in ruff_settings
181-
assert len(ruff_settings["per-file-ignores"]) == 2
182-
assert "exclude" in ruff_settings
183-
assert len(ruff_settings["exclude"]) == 2
184-
185-
doc = workspace.get_document(doc_uri)
186-
res = ruff_lint.pylsp_lint(workspace, doc)
187-
assert not res
188-
189-
os.unlink(os.path.join(workspace.root_path, "pyproject.toml"))
190-
191-
192-
def test_per_file_ignores_alternative_syntax(workspace):
193-
config_str = r"""[tool.ruff.per-file-ignores]
194-
"__init__.py" = ["F401", "E402"]
195-
"""
196-
197-
doc_str = "print('hi')\nimport os\n"
198-
199-
doc_uri = uris.from_fs_path(os.path.join(workspace.root_path, "blah/__init__.py"))
200-
workspace.put_document(doc_uri, doc_str)
201-
202-
ruff_settings = get_ruff_cfg_settings(
203-
workspace, workspace.get_document(doc_uri), config_str
204-
)
205-
206-
assert "per-file-ignores" in ruff_settings
207-
assert ruff_settings["per-file-ignores"] == {"__init__.py": ["F401", "E402"]}
165+
diags = ruff_lint.pylsp_lint(workspace, doc)
208166

209-
doc = workspace.get_document(doc_uri)
210-
res = ruff_lint.pylsp_lint(workspace, doc)
211-
assert not res
167+
for diag in diags:
168+
assert diag["code"] != "F841"
212169

213170
os.unlink(os.path.join(workspace.root_path, "pyproject.toml"))

0 commit comments

Comments
 (0)