vscode-common-python-lsp 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/PKG-INFO +1 -1
  2. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/pyproject.toml +1 -1
  3. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_server.py +72 -0
  4. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/__init__.py +2 -0
  5. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/server.py +29 -7
  6. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp.egg-info/PKG-INFO +1 -1
  7. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/README.md +0 -0
  8. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/setup.cfg +0 -0
  9. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_code_actions.py +0 -0
  10. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_context.py +0 -0
  11. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_debug.py +0 -0
  12. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_diagnostics.py +0 -0
  13. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_formatting.py +0 -0
  14. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_jsonrpc.py +0 -0
  15. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_linting.py +0 -0
  16. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_notebook.py +0 -0
  17. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_package.py +0 -0
  18. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_paths.py +0 -0
  19. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_process_runner.py +0 -0
  20. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_runner.py +0 -0
  21. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/tests/test_version.py +0 -0
  22. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/code_actions.py +0 -0
  23. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/context.py +0 -0
  24. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/debug.py +0 -0
  25. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/diagnostics.py +0 -0
  26. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/formatting.py +0 -0
  27. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/jsonrpc.py +0 -0
  28. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/linting.py +0 -0
  29. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/notebook.py +0 -0
  30. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/paths.py +0 -0
  31. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/process_runner.py +0 -0
  32. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/runner.py +0 -0
  33. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp/version.py +0 -0
  34. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp.egg-info/SOURCES.txt +0 -0
  35. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp.egg-info/dependency_links.txt +0 -0
  36. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp.egg-info/requires.txt +0 -0
  37. {vscode_common_python_lsp-0.2.0 → vscode_common_python_lsp-0.3.0}/vscode_common_python_lsp.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vscode-common-python-lsp
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Shared Python utilities for VS Code Python tool extensions
5
5
  Author: Microsoft Corporation
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "vscode-common-python-lsp"
7
- version = "0.2.0"
7
+ version = "0.3.0"
8
8
  description = "Shared Python utilities for VS Code Python tool extensions"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -51,6 +51,7 @@ class TestToolServerConfig:
51
51
  assert cfg.tool_args == []
52
52
  assert cfg.min_version == ""
53
53
  assert cfg.runner_script == ""
54
+ assert cfg.resolve_symlinks is False
54
55
  assert cfg.default_notification_level == "off"
55
56
  assert cfg.default_settings == {}
56
57
 
@@ -330,6 +331,77 @@ class TestGetDocumentKey:
330
331
  assert ts.get_document_key(doc) is None
331
332
 
332
333
 
334
+ class TestResolveSymlinks:
335
+ """Tests for the resolve_symlinks config propagation to normalize_path."""
336
+
337
+ def test_default_config_has_resolve_symlinks_false(self):
338
+ cfg = ToolServerConfig(tool_module="mod", tool_display="Mod")
339
+ assert cfg.resolve_symlinks is False
340
+
341
+ @patch("vscode_common_python_lsp.server.normalize_path")
342
+ @patch("vscode_common_python_lsp.server.uris")
343
+ def test_update_workspace_settings_passes_resolve_symlinks_false(
344
+ self, mock_uris, mock_normalize
345
+ ):
346
+ mock_uris.from_fs_path.return_value = "file:///cwd"
347
+ mock_normalize.return_value = "/normalized/cwd"
348
+ ts = _make_server()
349
+ ts.update_workspace_settings(None)
350
+ mock_normalize.assert_called_with(os.getcwd(), resolve_symlinks=False)
351
+
352
+ @patch("vscode_common_python_lsp.server.normalize_path")
353
+ @patch("vscode_common_python_lsp.server.uris")
354
+ def test_update_workspace_settings_passes_resolve_symlinks_true(
355
+ self, mock_uris, mock_normalize
356
+ ):
357
+ mock_uris.from_fs_path.return_value = "file:///cwd"
358
+ mock_normalize.return_value = "/normalized/cwd"
359
+ cfg = ToolServerConfig(
360
+ tool_module="mod", tool_display="Mod", resolve_symlinks=True
361
+ )
362
+ ts = _make_server(cfg)
363
+ ts.update_workspace_settings(None)
364
+ mock_normalize.assert_called_with(os.getcwd(), resolve_symlinks=True)
365
+
366
+ @patch("vscode_common_python_lsp.server.normalize_path")
367
+ @patch("vscode_common_python_lsp.server.uris")
368
+ def test_update_workspace_settings_list_passes_resolve_symlinks(
369
+ self, mock_uris, mock_normalize
370
+ ):
371
+ mock_uris.to_fs_path.side_effect = lambda u: u.replace("file://", "")
372
+ mock_normalize.return_value = "/ws1"
373
+ ts = _make_server()
374
+ ts.update_workspace_settings([{"workspace": "file:///ws1"}])
375
+ mock_normalize.assert_called_with("/ws1", resolve_symlinks=False)
376
+
377
+ @patch("vscode_common_python_lsp.server.normalize_path")
378
+ @patch("vscode_common_python_lsp.server.uris")
379
+ def test_get_settings_by_document_passes_resolve_symlinks(
380
+ self, mock_uris, mock_normalize
381
+ ):
382
+ mock_uris.from_fs_path.return_value = "file:///parent"
383
+ mock_normalize.return_value = "/parent"
384
+ ts = _make_server()
385
+ doc = _make_document("/parent/file.py")
386
+ # No workspace settings, document outside all → fallback path
387
+ ts.get_settings_by_document(doc)
388
+ mock_normalize.assert_called_with(
389
+ str(pathlib.Path("/parent/file.py").parent),
390
+ resolve_symlinks=False,
391
+ )
392
+
393
+ @patch("vscode_common_python_lsp.server.normalize_path")
394
+ @patch("vscode_common_python_lsp.server.uris")
395
+ def test_get_settings_by_path_empty_passes_resolve_symlinks(
396
+ self, mock_uris, mock_normalize
397
+ ):
398
+ mock_uris.from_fs_path.return_value = "file:///cwd"
399
+ mock_normalize.return_value = "/normalized/cwd"
400
+ ts = _make_server()
401
+ ts.get_settings_by_path(pathlib.Path("/some/file.py"))
402
+ mock_normalize.assert_called_with(os.getcwd(), resolve_symlinks=False)
403
+
404
+
333
405
  # ---------------------------------------------------------------------------
334
406
  # CWD resolution
335
407
  # ---------------------------------------------------------------------------
@@ -39,6 +39,7 @@ from .notebook import (
39
39
  CellLike,
40
40
  CellOffset,
41
41
  SyntheticDocument,
42
+ TextDocumentLike,
42
43
  build_notebook_source,
43
44
  get_cell_for_line,
44
45
  remap_diagnostics_to_cells,
@@ -125,6 +126,7 @@ __all__ = [
125
126
  # notebook
126
127
  "CellLike",
127
128
  "SyntheticDocument",
129
+ "TextDocumentLike",
128
130
  "CellOffset",
129
131
  "MAGIC_LINE_RE",
130
132
  "NOTEBOOK_SYNC_OPTIONS",
@@ -45,6 +45,10 @@ class ToolServerConfig:
45
45
  Minimum supported version string.
46
46
  runner_script:
47
47
  Path to the bundled JSON-RPC runner script.
48
+ resolve_symlinks:
49
+ Whether to resolve symlinks when normalizing workspace paths.
50
+ All current extension repos use ``False`` to keep workspace
51
+ keys relative to the (possibly symlinked) workspace root.
48
52
  default_notification_level:
49
53
  Default value for the ``showNotifications`` setting.
50
54
  default_settings:
@@ -58,6 +62,7 @@ class ToolServerConfig:
58
62
  tool_args: list[str] = field(default_factory=list)
59
63
  min_version: str = ""
60
64
  runner_script: str = ""
65
+ resolve_symlinks: bool = False
61
66
  default_notification_level: Literal["off", "onError", "onWarning", "always"] = "off"
62
67
  default_settings: dict[str, Any] = field(default_factory=dict)
63
68
 
@@ -122,7 +127,9 @@ class ToolServer:
122
127
  def update_workspace_settings(self, settings: list[dict[str, Any]] | None) -> None:
123
128
  """Populate :attr:`workspace_settings` from the client payload."""
124
129
  if not settings:
125
- key = normalize_path(os.getcwd())
130
+ key = normalize_path(
131
+ os.getcwd(), resolve_symlinks=self.config.resolve_symlinks
132
+ )
126
133
  self.workspace_settings[key] = {
127
134
  "cwd": key,
128
135
  "workspaceFS": key,
@@ -132,7 +139,10 @@ class ToolServer:
132
139
  return
133
140
 
134
141
  for setting in settings:
135
- key = normalize_path(uris.to_fs_path(setting["workspace"]))
142
+ key = normalize_path(
143
+ uris.to_fs_path(setting["workspace"]),
144
+ resolve_symlinks=self.config.resolve_symlinks,
145
+ )
136
146
  self.workspace_settings[key] = {
137
147
  **self.get_global_defaults(),
138
148
  **setting,
@@ -142,7 +152,9 @@ class ToolServer:
142
152
  def get_settings_by_path(self, file_path: pathlib.Path) -> dict[str, Any]:
143
153
  """Return workspace settings for the given file path."""
144
154
  if not self.workspace_settings:
145
- cwd = normalize_path(os.getcwd())
155
+ cwd = normalize_path(
156
+ os.getcwd(), resolve_symlinks=self.config.resolve_symlinks
157
+ )
146
158
  return {
147
159
  "cwd": cwd,
148
160
  "workspaceFS": cwd,
@@ -153,7 +165,9 @@ class ToolServer:
153
165
  workspaces = {s["workspaceFS"] for s in self.workspace_settings.values()}
154
166
 
155
167
  while file_path != file_path.parent:
156
- str_file_path = normalize_path(str(file_path))
168
+ str_file_path = normalize_path(
169
+ str(file_path), resolve_symlinks=self.config.resolve_symlinks
170
+ )
157
171
  if str_file_path in workspaces:
158
172
  return self.workspace_settings[str_file_path]
159
173
  file_path = file_path.parent
@@ -167,7 +181,10 @@ class ToolServer:
167
181
  workspaces = {s["workspaceFS"] for s in self.workspace_settings.values()}
168
182
 
169
183
  while document_workspace != document_workspace.parent:
170
- norm_path = normalize_path(str(document_workspace))
184
+ norm_path = normalize_path(
185
+ str(document_workspace),
186
+ resolve_symlinks=self.config.resolve_symlinks,
187
+ )
171
188
  if norm_path in workspaces:
172
189
  return norm_path
173
190
  document_workspace = document_workspace.parent
@@ -178,7 +195,9 @@ class ToolServer:
178
195
  """Return workspace settings for the given document."""
179
196
  if document is None or document.path is None:
180
197
  if not self.workspace_settings:
181
- cwd = normalize_path(os.getcwd())
198
+ cwd = normalize_path(
199
+ os.getcwd(), resolve_symlinks=self.config.resolve_symlinks
200
+ )
182
201
  return {
183
202
  "cwd": cwd,
184
203
  "workspaceFS": cwd,
@@ -191,7 +210,10 @@ class ToolServer:
191
210
  if key is not None:
192
211
  return self.workspace_settings[key]
193
212
 
194
- key = normalize_path(str(pathlib.Path(document.path).parent))
213
+ key = normalize_path(
214
+ str(pathlib.Path(document.path).parent),
215
+ resolve_symlinks=self.config.resolve_symlinks,
216
+ )
195
217
  return {
196
218
  "cwd": key,
197
219
  "workspaceFS": key,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vscode-common-python-lsp
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Shared Python utilities for VS Code Python tool extensions
5
5
  Author: Microsoft Corporation
6
6
  License-Expression: MIT