Restore Pylance document synchronization on Dev18 - #8601
Open
StellaHuang95 wants to merge 2 commits into
Open
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5679231-48fb-4e6f-ba92-12102f084440
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
Author
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR restores correct document synchronization with Pylance on Dev18 by normalizing Pylance’s numeric textDocumentSync initialize capability into the equivalent options object, working around a Dev18 VSLanguageServerClient capability-union regression without changing post-initialize LSP traffic.
Changes:
- Add a Dev18-only stdout stream wrapper that parses LSP frames and rewrites the initialize response capability when
textDocumentSyncis sent as a number. - Wire the wrapper into the Pylance
LanguageServerconnection creation (Dev18 only). - Include the new stream implementation in the PythonTools project build.
Show a summary per file
| File | Description |
|---|---|
| Python/Product/PythonTools/PythonTools/LanguageServerClient/StreamHacking/PylanceInitializeResponseStream.cs | New stream wrapper that buffers/parses LSP frames and expands numeric textDocumentSync in the initialize response. |
| Python/Product/PythonTools/PythonTools/LanguageServerClient/LanguageServer.cs | Dev18-only wrapping of Pylance stdout with the initialize-response normalizing stream. |
| Python/Product/PythonTools/PythonTools.csproj | Adds the new stream wrapper source file to the project compilation list. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 2
- Review effort level: Lite
| @@ -96,8 +96,13 @@ public async Task<Connection> ActivateAsync() { | |||
|
|
|||
| if (!process.HasExited) { | |||
| // Create a connection where we wrap the stdin stream so that we can intercept all messages | |||
Comment on lines
+153
to
+161
| if (message["id"] == null || (message["result"] == null && message["error"] == null)) { | ||
| return frame; | ||
| } | ||
|
|
||
| _initializeResponseProcessed = true; | ||
| var textDocumentSync = message["result"]?["capabilities"]?["textDocumentSync"]; | ||
| if (textDocumentSync?.Type != JTokenType.Integer) { | ||
| return frame; | ||
| } |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5679231-48fb-4e6f-ba92-12102f084440
|
Contributor
There was a problem hiding this comment.
Review details
Suppressed comments (1)
Python/Product/PythonTools/PythonTools/LanguageServerClient/StreamHacking/PylanceInitializeResponseStream.cs:237
- PylanceInitializeResponseStream owns a SemaphoreSlim (_readLock) but never disposes it. SemaphoreSlim is IDisposable and can hold unmanaged resources (via its wait handle), so leaving it undisposed can leak resources over the lifetime of VS sessions where the language client is restarted.
protected override void Dispose(bool disposing) {
if (disposing && Interlocked.Exchange(ref _disposed, 1) == 0) {
_baseStream.Dispose();
}
base.Dispose(disposing);
- Files reviewed: 3/3 changed files
- Comments generated: 0 new
- Review effort level: Lite
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Root cause
Pylance returns the valid LSP shorthand
"textDocumentSync": 2, meaning incremental synchronization.The regression was introduced by the VSLanguageServerClient generated-capability migration in commit d97ea9c64 (PR 760545). The generated union retains the numeric value as
TextDocumentSyncKind.Incremental. ThedidChangepath accepts either the enum orTextDocumentSyncOptions, but thedidOpen,didClose, anddidSavepaths only inspectTextDocumentSyncOptions.Consequently, VSL does not register
didOpenfor Pylance. Because the document is never marked open, subsequentdidChangenotifications are discarded as well. Pylance then has no current editor contents:import sysomits thesysmodule;VSL has an equivalent normalization in commit ac604b1b8, but at the time of investigation that commit was only on
feature/dynamic-registration-redesign, notmainorrelease/18.10.PTVS workaround
VSL performs the initialize exchange directly, before PTVS language-client middle layers can intercept the response. This change therefore wraps only the Pylance stdout stream on Dev18 and, for the initialize response only, expands:
into the semantically equivalent form:
The stream handles normal LSP framing, preserves any notifications preceding the initialize response, recalculates the UTF-8
Content-Length, and switches to direct pass-through immediately after initialization. It does not inspect or alter completions, diagnostics, document updates, or any later server traffic.Validation
Validated in the Dev18 Experimental Instance with Pylance
2026.2.109:import sysofferssysin completion results;import xxxxproduces an editor squiggle and an Error List diagnostic;didOpen,didChange, andpublishDiagnosticstraffic.No tests were added or modified.
Fixes #8592
Fixes #8596