vscode-common-python-lsp 0.5.1__tar.gz → 0.5.2__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.
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/PKG-INFO +1 -1
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/pyproject.toml +1 -1
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_paths.py +151 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/__init__.py +2 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/paths.py +133 -1
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp.egg-info/PKG-INFO +1 -1
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/README.md +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/setup.cfg +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_code_actions.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_context.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_debug.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_diagnostics.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_formatting.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_jsonrpc.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_linting.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_notebook.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_package.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_process_runner.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_runner.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_server.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_version.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/code_actions.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/context.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/debug.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/diagnostics.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/formatting.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/jsonrpc.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/linting.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/notebook.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/process_runner.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/runner.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/server.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/version.py +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp.egg-info/SOURCES.txt +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp.egg-info/dependency_links.txt +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp.egg-info/requires.txt +0 -0
- {vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp.egg-info/top_level.txt +0 -0
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"""Tests for paths module."""
|
|
4
4
|
|
|
5
5
|
import os
|
|
6
|
+
import pathlib
|
|
6
7
|
import site
|
|
7
8
|
import sys
|
|
8
9
|
import sysconfig
|
|
@@ -20,6 +21,7 @@ from vscode_common_python_lsp.paths import (
|
|
|
20
21
|
is_match,
|
|
21
22
|
is_same_path,
|
|
22
23
|
normalize_path,
|
|
24
|
+
sanitize_path_for_name_max,
|
|
23
25
|
)
|
|
24
26
|
|
|
25
27
|
|
|
@@ -266,3 +268,152 @@ class TestIsMatch:
|
|
|
266
268
|
def test_with_workspace_root(self, tmp_path):
|
|
267
269
|
fp = str(tmp_path / "src" / "test.py")
|
|
268
270
|
assert is_match(["src/*.py"], fp, str(tmp_path))
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
# ---------------------------------------------------------------------------
|
|
274
|
+
# sanitize_path_for_name_max tests
|
|
275
|
+
# ---------------------------------------------------------------------------
|
|
276
|
+
|
|
277
|
+
# A realistic dev-container/tunnel netloc component (>255 chars).
|
|
278
|
+
_LONG_NETLOC = (
|
|
279
|
+
"dev-container+7b22686f737450617468223a222f686f6d652f646f6e6e79"
|
|
280
|
+
"2f50726f6a656374732f776f72647365617263682d637370222c226c6f63"
|
|
281
|
+
"616c446f636b6572223a66616c73652c22636f6e66696746696c65223a7b"
|
|
282
|
+
"22246d6964223a312c2270617468223a222f686f6d652f646f6e6e792f50"
|
|
283
|
+
"726f6a656374732f776f72647365617263682d6373702f2e646576636f6e"
|
|
284
|
+
"7461696e65722f646576636f6e7461696e65722e6a736f6e222c22736368"
|
|
285
|
+
"656d65223a227673636f64652d66696c65486f7374227d7d"
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
class TestSanitizePathForNameMax:
|
|
290
|
+
"""Tests for sanitize_path_for_name_max() — path sanitisation."""
|
|
291
|
+
|
|
292
|
+
def test_short_path_unchanged(self):
|
|
293
|
+
"""Normal paths should pass through untouched."""
|
|
294
|
+
p = os.path.join(os.sep, "home", "user", "project", "src", "main.py")
|
|
295
|
+
assert sanitize_path_for_name_max(p) == p
|
|
296
|
+
|
|
297
|
+
def test_overlong_component_detected(self):
|
|
298
|
+
"""The fixture netloc must actually exceed NAME_MAX."""
|
|
299
|
+
assert len(_LONG_NETLOC.encode()) > 255
|
|
300
|
+
|
|
301
|
+
def test_overlong_without_workspace(self):
|
|
302
|
+
"""Overlong component is replaced with '_', basename preserved."""
|
|
303
|
+
p = os.path.join(os.sep, _LONG_NETLOC, "workspace", "src", "main.py")
|
|
304
|
+
result = sanitize_path_for_name_max(p)
|
|
305
|
+
for part in pathlib.PurePath(result).parts:
|
|
306
|
+
assert len(part.encode()) <= 255
|
|
307
|
+
assert result.endswith("main.py")
|
|
308
|
+
|
|
309
|
+
def test_overlong_with_workspace(self):
|
|
310
|
+
"""With a workspace, result preserves sub-path below overlong component."""
|
|
311
|
+
p = os.path.join(os.sep, _LONG_NETLOC, "workspace", "src", "main.py")
|
|
312
|
+
workspace = os.path.join(os.sep, "workspace")
|
|
313
|
+
result = sanitize_path_for_name_max(p, workspace=workspace)
|
|
314
|
+
assert result == os.path.join(workspace, "workspace", "src", "main.py")
|
|
315
|
+
|
|
316
|
+
def test_overlong_with_workspace_preserves_subpath(self):
|
|
317
|
+
"""Sub-path below overlong component is preserved when re-rooting."""
|
|
318
|
+
p = os.path.join(os.sep, _LONG_NETLOC, "deep", "nested", "path", "app.py")
|
|
319
|
+
workspace = os.path.join(os.sep, "home", "user", "project")
|
|
320
|
+
result = sanitize_path_for_name_max(p, workspace=workspace)
|
|
321
|
+
assert result == os.path.join(workspace, "deep", "nested", "path", "app.py")
|
|
322
|
+
|
|
323
|
+
def test_multiple_overlong_components(self):
|
|
324
|
+
"""Multiple overlong components are all sanitised."""
|
|
325
|
+
long1 = "a" * 300
|
|
326
|
+
long2 = "b" * 400
|
|
327
|
+
p = os.path.join(os.sep, long1, long2, "file.py")
|
|
328
|
+
result = sanitize_path_for_name_max(p)
|
|
329
|
+
for part in pathlib.PurePath(result).parts:
|
|
330
|
+
assert len(part.encode()) <= 255
|
|
331
|
+
|
|
332
|
+
def test_empty_workspace_falls_back(self):
|
|
333
|
+
"""Empty workspace string triggers component-replacement fallback."""
|
|
334
|
+
p = os.path.join(os.sep, _LONG_NETLOC, "src", "file.py")
|
|
335
|
+
result = sanitize_path_for_name_max(p, workspace="")
|
|
336
|
+
assert result.endswith("file.py")
|
|
337
|
+
for part in pathlib.PurePath(result).parts:
|
|
338
|
+
assert len(part.encode()) <= 255
|
|
339
|
+
|
|
340
|
+
def test_unicode_path_component(self):
|
|
341
|
+
"""Multi-byte UTF-8 components exceeding 255 bytes are sanitised."""
|
|
342
|
+
# Each emoji is 4 bytes in UTF-8; 64 emojis = 256 bytes > 255
|
|
343
|
+
long_unicode = "\U0001f600" * 64
|
|
344
|
+
p = os.path.join(os.sep, long_unicode, "file.py")
|
|
345
|
+
result = sanitize_path_for_name_max(p)
|
|
346
|
+
for part in pathlib.PurePath(result).parts:
|
|
347
|
+
assert len(part.encode("utf-8")) <= 255
|
|
348
|
+
|
|
349
|
+
def test_overlong_basename_without_workspace(self):
|
|
350
|
+
"""Overlong basename without workspace is sanitized, preserving suffix."""
|
|
351
|
+
long_name = "x" * 300 + ".py"
|
|
352
|
+
p = os.path.join(os.sep, "dev", long_name)
|
|
353
|
+
result = sanitize_path_for_name_max(p)
|
|
354
|
+
assert pathlib.PurePath(result).name == "_.py"
|
|
355
|
+
for part in pathlib.PurePath(result).parts:
|
|
356
|
+
assert len(part.encode()) <= 255
|
|
357
|
+
|
|
358
|
+
def test_overlong_basename_with_workspace(self):
|
|
359
|
+
"""Overlong basename with workspace is sanitized, preserving suffix."""
|
|
360
|
+
long_name = "a" * 300 + ".py"
|
|
361
|
+
p = os.path.join(os.sep, _LONG_NETLOC, "src", long_name)
|
|
362
|
+
workspace = os.path.join(os.sep, "workspace")
|
|
363
|
+
result = sanitize_path_for_name_max(p, workspace=workspace)
|
|
364
|
+
assert pathlib.PurePath(result).name == "_.py"
|
|
365
|
+
for part in pathlib.PurePath(result).parts:
|
|
366
|
+
assert len(part.encode()) <= 255
|
|
367
|
+
|
|
368
|
+
def test_overlong_basename_replaced_preserving_suffix(self):
|
|
369
|
+
"""If basename itself is too long, it gets replaced preserving suffix."""
|
|
370
|
+
long_name = "x" * 300 + ".py"
|
|
371
|
+
p = os.path.join(os.sep, "workspace", "src", long_name)
|
|
372
|
+
workspace = os.path.join(os.sep, "workspace")
|
|
373
|
+
result = sanitize_path_for_name_max(p, workspace=workspace)
|
|
374
|
+
# Should replace with "_.py" not reroute under workspace
|
|
375
|
+
assert pathlib.PurePath(result).name == "_.py"
|
|
376
|
+
|
|
377
|
+
def test_workspace_preserves_subpath(self):
|
|
378
|
+
"""Intermediate directories below overlong component are preserved."""
|
|
379
|
+
p = os.path.join(os.sep, _LONG_NETLOC, "src", "pkg", "main.py")
|
|
380
|
+
workspace = os.path.join(os.sep, "ws")
|
|
381
|
+
result = sanitize_path_for_name_max(p, workspace=workspace)
|
|
382
|
+
assert result == os.path.join(os.sep, "ws", "src", "pkg", "main.py")
|
|
383
|
+
|
|
384
|
+
def test_workspace_with_overlong_basename_in_tail(self):
|
|
385
|
+
"""Workspace branch sanitizes an overlong basename in the tail."""
|
|
386
|
+
long_name = "a" * 300 + ".py"
|
|
387
|
+
p = os.path.join(os.sep, _LONG_NETLOC, "workspace", long_name)
|
|
388
|
+
workspace = os.path.join(os.sep, "ws")
|
|
389
|
+
result = sanitize_path_for_name_max(p, workspace=workspace)
|
|
390
|
+
assert pathlib.PurePath(result).name == "_.py"
|
|
391
|
+
assert result.startswith(workspace)
|
|
392
|
+
|
|
393
|
+
def test_windows_limit_kind(self):
|
|
394
|
+
"""Windows mode uses character count, not byte count."""
|
|
395
|
+
# 200 emoji chars = 200 characters but 800 UTF-8 bytes
|
|
396
|
+
# Should NOT exceed on windows (200 < 255) but WOULD exceed on posix (800 > 255)
|
|
397
|
+
component = "\U0001f600" * 200
|
|
398
|
+
p = os.path.join(os.sep, component, "file.py")
|
|
399
|
+
result_win = sanitize_path_for_name_max(p, limit_kind="windows")
|
|
400
|
+
result_posix = sanitize_path_for_name_max(p, limit_kind="posix")
|
|
401
|
+
# Windows: unchanged (200 chars < 255)
|
|
402
|
+
assert result_win == p
|
|
403
|
+
# POSIX: sanitized (800 bytes > 255)
|
|
404
|
+
assert result_posix != p
|
|
405
|
+
assert result_posix.endswith("file.py")
|
|
406
|
+
|
|
407
|
+
def test_root_components_ignored(self):
|
|
408
|
+
"""Root/anchor parts like '/' are not flagged as overlong."""
|
|
409
|
+
p = os.path.join(os.sep, "normal", "path.py")
|
|
410
|
+
assert sanitize_path_for_name_max(p) == p
|
|
411
|
+
|
|
412
|
+
def test_unicode_posix_ascii_fast_path(self):
|
|
413
|
+
"""ASCII-only strings that are short skip the byte-counting loop."""
|
|
414
|
+
p = os.path.join(os.sep, "a" * 255, "file.py")
|
|
415
|
+
# Exactly 255 is fine
|
|
416
|
+
assert sanitize_path_for_name_max(p) == p
|
|
417
|
+
# 256 exceeds
|
|
418
|
+
p2 = os.path.join(os.sep, "a" * 256, "file.py")
|
|
419
|
+
assert sanitize_path_for_name_max(p2) != p2
|
|
@@ -58,6 +58,7 @@ from .paths import (
|
|
|
58
58
|
is_same_path,
|
|
59
59
|
normalize_path,
|
|
60
60
|
reset_caches,
|
|
61
|
+
sanitize_path_for_name_max,
|
|
61
62
|
)
|
|
62
63
|
from .process_runner import (
|
|
63
64
|
resolve_bundle_path,
|
|
@@ -84,6 +85,7 @@ __all__ = [
|
|
|
84
85
|
"PythonFileKind",
|
|
85
86
|
"is_match",
|
|
86
87
|
"reset_caches",
|
|
88
|
+
"sanitize_path_for_name_max",
|
|
87
89
|
# context
|
|
88
90
|
"substitute_attr",
|
|
89
91
|
"redirect_io",
|
{vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/paths.py
RENAMED
|
@@ -13,7 +13,7 @@ import sys
|
|
|
13
13
|
import sysconfig
|
|
14
14
|
import threading
|
|
15
15
|
from enum import Enum
|
|
16
|
-
from typing import Any
|
|
16
|
+
from typing import Any, Literal
|
|
17
17
|
|
|
18
18
|
# Save the working directory used when loading this module
|
|
19
19
|
SERVER_CWD = os.getcwd()
|
|
@@ -239,6 +239,138 @@ def normalize_path(file_path: str, resolve_symlinks: bool = True) -> str:
|
|
|
239
239
|
return str(path)
|
|
240
240
|
|
|
241
241
|
|
|
242
|
+
# Conservative maximum length of a single path component. POSIX NAME_MAX is
|
|
243
|
+
# 255 *bytes* (ext4, APFS, …). NTFS actually limits to 255 UTF-16 code units,
|
|
244
|
+
# so this byte-oriented heuristic is stricter than necessary on Windows — but
|
|
245
|
+
# that is safe and keeps the logic simple across platforms.
|
|
246
|
+
_NAME_MAX = 255
|
|
247
|
+
|
|
248
|
+
PathComponentLimitKind = Literal["windows", "posix"]
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def _utf8_len_exceeds(s: str, limit: int) -> bool:
|
|
252
|
+
"""Check if UTF-8 byte length of s exceeds limit, without allocating."""
|
|
253
|
+
total = 0
|
|
254
|
+
|
|
255
|
+
for ch in s:
|
|
256
|
+
code = ord(ch)
|
|
257
|
+
|
|
258
|
+
if code < 0x80:
|
|
259
|
+
total += 1
|
|
260
|
+
elif code < 0x800:
|
|
261
|
+
total += 2
|
|
262
|
+
elif code < 0x10000:
|
|
263
|
+
total += 3
|
|
264
|
+
else:
|
|
265
|
+
total += 4
|
|
266
|
+
|
|
267
|
+
if total > limit:
|
|
268
|
+
return True
|
|
269
|
+
|
|
270
|
+
return False
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def _component_exceeds_name_max(
|
|
274
|
+
component: str,
|
|
275
|
+
*,
|
|
276
|
+
limit_kind: PathComponentLimitKind,
|
|
277
|
+
) -> bool:
|
|
278
|
+
# Ignore root/anchor-ish path parts.
|
|
279
|
+
if component in ("", "/", "\\") or component.endswith(":"):
|
|
280
|
+
return False
|
|
281
|
+
|
|
282
|
+
if limit_kind == "windows":
|
|
283
|
+
# Windows component limits are character-oriented for normal paths.
|
|
284
|
+
return len(component) > _NAME_MAX
|
|
285
|
+
|
|
286
|
+
# POSIX NAME_MAX is byte-oriented.
|
|
287
|
+
if len(component) > _NAME_MAX:
|
|
288
|
+
return True
|
|
289
|
+
|
|
290
|
+
if component.isascii():
|
|
291
|
+
return False
|
|
292
|
+
|
|
293
|
+
return _utf8_len_exceeds(component, _NAME_MAX)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def sanitize_path_for_name_max(
|
|
297
|
+
fs_path: str,
|
|
298
|
+
workspace: str | None = None,
|
|
299
|
+
*,
|
|
300
|
+
limit_kind: PathComponentLimitKind = "posix",
|
|
301
|
+
) -> str:
|
|
302
|
+
"""Return *fs_path* with any overlong path components shortened.
|
|
303
|
+
|
|
304
|
+
Dev-container / tunnel URIs can embed a ``netloc`` component that far
|
|
305
|
+
exceeds the conservative 255-byte ``NAME_MAX`` heuristic used here
|
|
306
|
+
(ext4 and APFS use 255 bytes; NTFS uses 255 UTF-16 code units, so
|
|
307
|
+
this byte-oriented check is stricter than necessary on Windows). When that
|
|
308
|
+
value is used as ``--stdin-filename`` or similar, the downstream tool
|
|
309
|
+
raises ``OSError: [Errno 36] File name too long``.
|
|
310
|
+
|
|
311
|
+
This helper replaces every overlong path component with ``_`` plus the
|
|
312
|
+
original file extension (e.g. ``_.py``), preserving the suffix that
|
|
313
|
+
downstream tools use for file-type dispatch.
|
|
314
|
+
|
|
315
|
+
If *workspace* is supplied and the overlong component is *not* the
|
|
316
|
+
basename, the path is re-rooted under the workspace while preserving
|
|
317
|
+
the full sub-path below the overlong component. For example::
|
|
318
|
+
|
|
319
|
+
sanitize_path_for_name_max(
|
|
320
|
+
"/dev-container+<long>/workspace/src/pkg/main.py",
|
|
321
|
+
workspace="/workspace",
|
|
322
|
+
)
|
|
323
|
+
# → "/workspace/workspace/src/pkg/main.py"
|
|
324
|
+
|
|
325
|
+
If *fs_path* contains no overlong component, it is returned unchanged.
|
|
326
|
+
|
|
327
|
+
Parameters
|
|
328
|
+
----------
|
|
329
|
+
fs_path:
|
|
330
|
+
Filesystem path derived from a document URI (e.g. via
|
|
331
|
+
``pygls.uris.to_fs_path`` or VS Code's ``Uri.fsPath``).
|
|
332
|
+
workspace:
|
|
333
|
+
Optional workspace root path. When provided and the overlong
|
|
334
|
+
component is not the basename, the result is
|
|
335
|
+
``<workspace>/<sub-path>`` — the portion of the path below
|
|
336
|
+
the overlong component is preserved so that downstream tools
|
|
337
|
+
can still resolve config files and derive module names.
|
|
338
|
+
limit_kind:
|
|
339
|
+
Whether to apply Windows (character-count) or POSIX (byte-count)
|
|
340
|
+
limits. Defaults to ``"posix"``. Note: the POSIX byte-count
|
|
341
|
+
heuristic is conservative on NTFS, which actually limits to 255
|
|
342
|
+
UTF-16 code units.
|
|
343
|
+
"""
|
|
344
|
+
path = pathlib.PurePath(fs_path)
|
|
345
|
+
parts = path.parts
|
|
346
|
+
|
|
347
|
+
safe_parts: list[str] | None = None
|
|
348
|
+
|
|
349
|
+
for i, part in enumerate(parts):
|
|
350
|
+
if not _component_exceeds_name_max(part, limit_kind=limit_kind):
|
|
351
|
+
continue
|
|
352
|
+
|
|
353
|
+
if workspace and i != len(parts) - 1:
|
|
354
|
+
# Preserve the sub-path below the overlong component so that
|
|
355
|
+
# intermediate directories (used by tools to locate config files
|
|
356
|
+
# and derive module names) are retained.
|
|
357
|
+
tail_parts = list(parts[i + 1 :])
|
|
358
|
+
for j, tp in enumerate(tail_parts):
|
|
359
|
+
if _component_exceeds_name_max(tp, limit_kind=limit_kind):
|
|
360
|
+
tail_parts[j] = "_" + pathlib.PurePath(tp).suffix
|
|
361
|
+
return str(pathlib.PurePath(workspace, *tail_parts))
|
|
362
|
+
|
|
363
|
+
if safe_parts is None:
|
|
364
|
+
safe_parts = list(parts)
|
|
365
|
+
|
|
366
|
+
safe_parts[i] = "_" + pathlib.PurePath(part).suffix
|
|
367
|
+
|
|
368
|
+
if safe_parts is None:
|
|
369
|
+
return fs_path
|
|
370
|
+
|
|
371
|
+
return str(pathlib.PurePath(*safe_parts))
|
|
372
|
+
|
|
373
|
+
|
|
242
374
|
def is_current_interpreter(executable: str) -> bool:
|
|
243
375
|
"""Returns true if the executable path is same as the current interpreter."""
|
|
244
376
|
return is_same_path(executable, sys.executable)
|
|
File without changes
|
|
File without changes
|
{vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_code_actions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/tests/test_process_runner.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/debug.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/runner.py
RENAMED
|
File without changes
|
{vscode_common_python_lsp-0.5.1 → vscode_common_python_lsp-0.5.2}/vscode_common_python_lsp/server.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|