Skip to content

Commit 66d9b90

Browse files
committed
Fix wrong configuration being used with multiple workspace folders
When a workspace has multiple folders then the approach of using one global variable to store the config breaks down as each workspace folders can have separate configuration and the last one that gets initialized overwrites the previous one. Store configuration in a map looked up by workspace folder path.
1 parent 0b80495 commit 66d9b90

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

mypy_ls/plugin.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323

2424
log = logging.getLogger(__name__)
2525

26-
mypyConfigFile: Optional[str] = None
26+
# A mapping from workspace path to config file path
27+
mypyConfigFileMap: Dict[str, Optional[str]] = dict()
2728

2829
tmpFile: Optional[IO[str]] = None
2930

@@ -157,6 +158,7 @@ def pylsp_lint(
157158
)
158159
return last_diagnostics[document.path]
159160

161+
mypyConfigFile = mypyConfigFileMap.get(workspace.root_path)
160162
if mypyConfigFile:
161163
args.append("--config-file")
162164
args.append(mypyConfigFile)
@@ -250,10 +252,10 @@ def init(workspace: str) -> Dict[str, str]:
250252
with open(path) as file:
251253
configuration = eval(file.read())
252254

253-
global mypyConfigFile
254255
mypyConfigFile = findConfigFile(workspace, "mypy.ini")
255256
if not mypyConfigFile:
256257
mypyConfigFile = findConfigFile(workspace, ".mypy.ini")
258+
mypyConfigFileMap[workspace] = mypyConfigFile
257259

258260
if ("enabled" not in configuration or configuration["enabled"]) and (
259261
"live_mode" not in configuration or configuration["live_mode"]

test/test_plugin.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ def test_settings():
4141
def test_plugin(workspace):
4242
config = FakeConfig()
4343
doc = Document(DOC_URI, workspace, DOC_TYPE_ERR)
44-
workspace = None
4544
plugin.pylsp_settings(config)
4645
diags = plugin.pylsp_lint(config, workspace, doc, is_saved=False)
4746

@@ -84,3 +83,40 @@ def test_parse_line_with_context(monkeypatch, word, bounds, workspace):
8483
assert diag["message"] == '"Request" has no attribute "id"'
8584
assert diag["range"]["start"] == {"line": 278, "character": bounds[0]}
8685
assert diag["range"]["end"] == {"line": 278, "character": bounds[1]}
86+
87+
88+
def test_multiple_workspaces(tmpdir):
89+
DOC_SOURCE = """
90+
def foo():
91+
return
92+
unreachable = 1
93+
"""
94+
DOC_ERR_MSG = 'Statement is unreachable'
95+
96+
# Initialize two workspace folders.
97+
folder1 = tmpdir.mkdir('folder1')
98+
ws1 = Workspace(uris.from_fs_path(str(folder1)), Mock())
99+
ws1._config = Config(ws1.root_uri, {}, 0, {})
100+
folder2 = tmpdir.mkdir('folder2')
101+
ws2 = Workspace(uris.from_fs_path(str(folder2)), Mock())
102+
ws2._config = Config(ws2.root_uri, {}, 0, {})
103+
104+
# Create configuration file for workspace folder 1.
105+
mypy_config = folder1.join('mypy.ini')
106+
mypy_config.write('[mypy]\nwarn_unreachable = True')
107+
108+
# Initialize settings for both folders.
109+
plugin.pylsp_settings(ws1._config)
110+
plugin.pylsp_settings(ws2._config)
111+
112+
# Test document in workspace 1 (uses mypy.ini configuration).
113+
doc1 = Document(DOC_URI, ws1, DOC_SOURCE)
114+
diags = plugin.pylsp_lint(ws1._config, ws1, doc1, is_saved=False)
115+
assert len(diags) == 1
116+
diag = diags[0]
117+
assert diag["message"] == DOC_ERR_MSG
118+
119+
# Test document in workspace 2 (without mypy.ini configuration)
120+
doc2 = Document(DOC_URI, ws2, DOC_SOURCE)
121+
diags = plugin.pylsp_lint(ws2._config, ws2, doc2, is_saved=False)
122+
assert len(diags) == 0

0 commit comments

Comments
 (0)