pylance-release/docs/tsp/type-server-protocol.md at important · microsoft/pylance-release · GitHub


The Type Server Protocol (TSP) is a JSON-RPC protocol for asking a kind server for Python evaluation information. A kind server maintains the type-analysis state for a workspace and solutions requests for the protocol model, snapshots, Python search paths, import decision, and kind queries (computed, declared, and anticipated varieties).

The protocol makes use of Language Server Protocol (LSP) information shapes and conventions the place they’re helpful, akin to Position and Range, and it represents URIs as strings the identical method LSP does. TSP strategies use the kindServer/ prefix.

The protocol artifacts on this folder are the authoritative definitions:

TSP makes use of semantic model strings for shopper/server compatibility checks. While the protocol is within the 0.x line, minor model adjustments could also be breaking. Patch model adjustments stay backward suitable inside the identical minor line.

Version Changes
0.1.0 Initial protocol model.
0.2.0 Added request varieties and fields.
0.3.0 Switched to extra advanced kind shapes.
0.4.0 Switched to the Type union and stub-based kind payloads.
0.4.1 Added multi-connection negotiation and the kindServer/connection management request.

A shopper begins a kind server and communicates with it over the primary JSON-RPC connection utilizing a transport the server helps, akin to stdio or Node IPC. When utilizing stdio, stdout have to be reserved for JSON-RPC protocol messages.

A kind server is anticipated to obtain sufficient workspace and doc state to reply the TSP requests it helps. Clients generally use regular LSP initialization and doc synchronization for this state, then ship kindServer/* requests on the identical JSON-RPC connection.

TSP additionally helps non-obligatory additional read-only connections. The authentic connection stays the primary connection and owns initialization, workspace state, doc synchronization, state-changing notifications, and connection management. Extra connections are opened solely after shopper and server negotiate help throughout initialization.

A typical session follows this order:

  1. The shopper begins or connects to the sort server.
  2. The shopper and server initialize any shared workspace state, generally via the LSP initialize and initialized messages.
  3. The shopper calls kindServer/getSupportedProtocolVersion and verifies that the returned semver string is suitable with the protocol model it expects.
  4. The shopper calls kindServer/getSnapshot to acquire the primary snapshot identifier.
  5. The shopper sends type-query, import-resolution, or search-path requests that embrace the present snapshot when required by the request form.
  6. The server sends kindServer/snapshotChanged when prior kind outcomes are now not legitimate.

Multi-connection mode is an non-obligatory efficiency function. It lets a shopper open extra native channels to the identical kind server for read-only TSP requests, whereas the primary connection continues to personal the mutable workspace state.

Clients ought to use multi-connection mode solely after they can profit from concurrent read-only work, akin to high-volume kind queries or background staff that ought to not block the primary JSON-RPC connection. A server should nonetheless work accurately in single-connection mode. Multi-connection help should not be required for protocol correctness.

Multi-connection help is negotiated via the traditional LSP initialize request and response. A shopper that may open additional TSP channels advertises the supported transport varieties beneath capabilities.experimental.kindServerMultiConnection:

{
    "capabilities": {
        "experimental": {
            "kindServerMultiConnection": {
                "supportedTransports": ["ipc"]
            }
        }
    }
}

A server that may serve additional TSP channels returns the identical functionality form within the initialize consequence:

{
    "capabilities": {
        "experimental": {
            "kindServerMultiConnection": {
                "supportedTransports": ["ipc"]
            }
        }
    }
}

Multi-connection mode is enabled solely when either side promote kindServerMultiConnection and the 2 supportedTransports lists have not less than one transport in widespread. If both aspect omits the potential, or if there isn’t a widespread transport, the session stays single-connection and the shopper should not ship kindServer/connection.

The presently supported built-in transport form for additional connections is ipc. This negotiation is separate from the primary connection, which may use stdio or Node IPC.

Opening An Extra Connection

After initialization and transport negotiation, the shopper opens an additional channel by sending kindServer/connection on the primary connection:

{
    "kind": "open",
    "form": "ipc",
    "args": [""]
}

For ipc, the args array identifies the endpoint or endpoints that the server ought to connect with. The server ought to validate the request, connect with the equipped endpoint promptly, and return a consequence with success: true when it accepts the request. If the server can’t open the channel, it ought to return success: false and embrace a brief message when helpful for logs.

An ipc endpoint is anticipated to supply a full-duplex JSON-RPC stream when the platform IPC mechanism helps it. In that case, args accommodates one endpoint string:

{
    "kind": "open",
    "form": "ipc",
    "args": [""]
}

If the platform IPC mechanism exposes solely one-way endpoints, args accommodates two endpoint strings. The endpoint names are from the sort server’s perspective: the primary endpoint is the server enter stream, and the second endpoint is the server output stream.

{
    "kind": "open",
    "form": "ipc",
    "args": ["", ""]
}

Closing An Extra Connection

The shopper closes an additional channel by sending kindServer/connection on the primary reference to the identical transport form and endpoint identification:

{
    "kind": "shut",
    "form": "ipc",
    "args": [""]
}

The server ought to cease serving the matching additional channel and shut the transport promptly. A shopper may additionally tear down its native transport if the server doesn’t full the shut inside the shopper’s timeout finances.

The shut request ought to use the identical args form that opened the channel: one endpoint for a full-duplex IPC stream, or the identical enter/output endpoint pair for a cut up IPC stream.

The important connection owns all state-changing site visitors. The following should stay main-connection-only:

  • LSP initialization and lifecycle messages.
  • Workspace, configuration, file-watcher, and doc synchronization notifications.
  • Server-to-client snapshot notifications.
  • The kindServer/connection management request.

Extra connections are TSP-only and read-only. They could also be used for requests that don’t mutate server state and whose outcomes are legitimate for the snapshot equipped by the shopper.

The allowed TSP messages on an additional connection are sure to the negotiated TSP model. If a server studies help for a TSP model and advertises multi-connection help for that session, it should help each extra-connection TSP message outlined for that model.

The desk beneath lists the TSP model that first permits every message on an additional connection:

TSP model Extra-connection message
0.4.1 kindServer/getSupportedProtocolVersion
0.4.1 kindServer/getSnapshot
0.4.1 kindServer/getPythonSearchPaths
0.4.1 kindServer/resolveImport
0.4.1 kindServer/getComputedType
0.4.1 kindServer/getDeclaredType
0.4.1 kindServer/getExpectedType

Servers ought to reject LSP site visitors, state-changing notifications, kindServer/connection, and any TSP message not allowed for the negotiated TSP model when obtained on an additional connection.

A snapshot is a non-negative integer that identifies a point-in-time view of the sort server’s evaluation state. Type handles, declarations, symbols, and different returned objects are legitimate just for the snapshot wherein they had been returned until a request explicitly says in any other case.

The kind server should advance the snapshot at any time when a beforehand returned type-analysis consequence could also be invalid. Typical invalidating occasions embrace opened-file adjustments, closed recordsdata, configuration adjustments, watched-file adjustments, dependency adjustments, or any cache reset that adjustments evaluation outcomes.

Snapshot guidelines:

  • kindServer/getSnapshot returns the present snapshot identifier.
  • Snapshot identifiers should not lower throughout a session.
  • kindServer/snapshotChanged studies the earlier and new snapshot identifiers.
  • Requests that embrace a stale snapshot ought to fail with a JSON-RPC error that lets the shopper retry with a contemporary snapshot. LSP’s ServerCancelled error code (-32802) is the popular error for this case.

TSP follows LSP place conventions:

  • Lines are zero-based.
  • Character offsets are zero-based UTF-16 code models.
  • Ranges establish supply spans utilizing a begin place and finish place.

If a kind server shops supply areas in one other encoding, it should convert areas on the protocol boundary. Incorrect conversion may cause the shopper to request info for the improper syntax node.

Nodes, Declarations, And Handles

The type-query requests (kindServer/getComputedType, kindServer/getDeclaredType, kindServer/getExpectedType) establish a supply assemble with an arg that’s both a node or a declaration. A node is a URI plus a supply vary. A declaration describes the place and the way a logo is outlined and is both a daily declaration, which is backed by a supply AST node, or a synthesized declaration, which is created by the sort checker and has no supply node.

InvalidDeal with is -1 and represents an invalid or unavailable deal with. Clients and servers ought to deal with it as a sentinel worth, not as a legitimate object identifier.

Type outcomes are JSON-serializable tagged objects. Each kind features a discriminator that tells the shopper methods to interpret the remainder of the thing. The protocol helps built-in varieties, declared varieties, features, courses, unions, modules, kind variables, overload units, synthesized varieties, and kind references.

Every kind object carries a numeric form discriminator, a numeric id, and a bitfield of flags:

form Type Description
0 ConstructedIn unknown, any, unbound, ellipsis, by no means, and related
1 Declared Base for source-declared varieties (not often used straight)
2 Function Functions and strategies from def statements
3 Class Classes and their situations
4 Union Union varieties (int | str | None)
5 Module Module objects (import os produces a Module kind for os)
6 TypeVar Type variables (T, P, Ts)
7 Overloaded Functions with a number of @overload signatures
8 Synthesized Types synthesized by the sort checker
9 TypeReference Reference to a different kind by id, used for deduplication and cycles

Type objects are snapshot-bound, and kind IDs are response-local:

  • A returned kind object is legitimate just for the snapshot utilized by the request that produced it.
  • Type IDs are used to attach TypeReference objects to earlier kind objects in the identical serialized response graph.
  • Type IDs usually are not a secure international identification for a snapshot and shouldn’t be in contrast throughout separate responses.
  • Type references needs to be used to keep away from duplicating giant or recursive kind graphs inside one response.

The present protocol is deliberately small. The precise parameters and consequence shapes are outlined within the protocol artifacts; the desk beneath lists each TSP message with its route and payload form.

Message Direction Params Result
kindServer/getSupportedProtocolVersion shopper → server none string (semver)
kindServer/getSnapshot shopper → server none quantity
kindServer/snapshotChanged server → shopper { outdated: quantity, new: quantity } notification
kindServer/connection shopper → server "shut", form, args? { success, message? }
kindServer/getPythonSearchPaths shopper → server { fromUri, snapshot } string[] | undefined
kindServer/resolveImport shopper → server { sourceUri, moduleDescriptor, snapshot } string | undefined
kindServer/getComputedType shopper → server Node, snapshot Type | undefined
kindServer/getDeclaredType shopper → server Node, snapshot Type | undefined
kindServer/getExpectedType shopper → server Node, snapshot Type | undefined

A kind server ought to implement the messages required by the shopper it integrates with and return undefined solely the place the protocol’s consequence kind permits it.

The three type-query requests differ by which kind they report for a similar node or declaration:

  • kindServer/getComputedType returns the sort inferred from code circulation. After narrowing a to int, the computed kind of b in b = a + 1 is int.
  • kindServer/getDeclaredType returns the sort explicitly written within the supply. For def foo(a: int | str), the declared kind of a is int | str.
  • kindServer/getExpectedType returns the sort the encircling context expects. For the decision foo(4), the anticipated kind of the argument is int | str.

Use normal JSON-RPC error responses.

Situation Error code Guidance
Stale snapshot -32802 (ServerCancelled) The shopper can request a contemporary snapshot and retry.
Invalid parameters -32602 (InvalidParams) Required fields are lacking or malformed.
Internal failure -32603 (InternalError) The server failed unexpectedly whereas dealing with a legitimate request.

Errors ought to embrace sufficient message element for a shopper log to establish the failed request, however they need to not expose native secrets and techniques or implementation-only state.

A suitable kind server ought to confirm these behaviors:

  1. kindServer/getSupportedProtocolVersion returns a semver string supported by the shopper.
  2. All request and notification payloads serialize and deserialize in keeping with the protocol artifacts.
  3. kindServer/getSnapshot returns a non-negative snapshot and snapshots don’t go backward.
  4. Document, configuration, and watched-file adjustments invalidate snapshots after they can change returned evaluation information.
  5. Requests with stale snapshots fail with a retryable cancellation error.
  6. Position and vary conversions use LSP zero-based UTF-16 conventions.
  7. Import-resolution requests return doc URIs or no consequence in keeping with the protocol consequence kind.
  8. Type queries (computed, declared, and anticipated) return well-formed Type objects, or undefined, for the snapshot equipped by the shopper.
  9. Multi-connection help is marketed solely when the server can serve the negotiated additional transport.
  10. Extra connections settle for each TSP request allowed for the negotiated TSP model and reject LSP site visitors, state-changing notifications, kindServer/connection, and TSP requests not allowed for that model.

Last content material replace aligned with Pylance 2026.4.1.



Source link