TSP:为 Python 类型分析定义标准协议的新选择
编辑器、IDE 与类型检查工具之间的接口长期缺少统一标准。微软在 Pylance 仓库的文档中描述了一套名为 Type Server Protocol(TSP)的协议,试图为 Python 类型分析定义明确的通信边界。这套协议不是新的语言特性,而是工具与类型服务器之间的契约,值得关注 Python 工具链的开发者了解。
背景:类型服务器的协作需求
根据来源文档,TSP 是一个基于 JSON-RPC 的协议,用于向类型服务器请求 Python 分析数据。类型服务器维护某个工作区的类型分析状态,并回答协议版本、快照、Python 搜索路径、导入解析以及三类类型查询(computed、declared、expected)等请求。
协议在数据形状和 URI 表示上有意沿用 Language Server Protocol(LSP)的习惯,例如 Position 和 Range,URI 也以字符串表示。TSP 的方法统一使用 typeServer/ 前缀。协议定义文件包括 typeServerProtocol.ts、tsp.json 和 tsp.schema.json,来源将其称为权威定义。
从版本历史看,协议仍处于 0.x 阶段:0.1.0 为初始版本,0.2.0 增加请求类型和字段,0.3.0 改用更复杂的类型形状,0.4.0 切换到 Type 联合与 stub 式类型载荷,0.4.1 增加多连接协商和 typeServer/connection 控制请求。文档说明,在 0.x 期间次版本号变化可能是破坏性的,补丁版本保持向后兼容。
核心变化:快照与多连接
TSP 最值得注意的设计有两个:快照模型和多连接模式。
快照是一个非负整数,标识类型服务器分析状态的某个时间点视图。返回的类型句柄、声明、符号等对象只在产生它们的快照内有效。服务器在已返回的分析结果可能失效时必须推进快照,典型触发事件包括打开文件变更、关闭文件、配置变更、被监视文件变化、依赖变化或缓存重置。快照标识在一次会话中不得减小,typeServer/snapshotChanged 会报告旧快照与新快照。携带过期快照的请求应以可重试的错误失败,文档推荐使用 LSP 的 ServerCancelled 错误码 -32802。
多连接模式是可选性能特性。主连接始终负责初始化、工作区状态、文档同步、改变状态的变更通知以及连接控制;额外连接只用于只读 TSP 请求。双方通过 LSP 初始化请求中的 capabilities.experimental.typeServerMultiConnection 进行协商,只有当两侧都声明该能力且 supportedTransports 至少有一个共同项时才启用。文档说明当前额外连接支持的内建传输类型是 ipc。启用后,客户端在主导接上发送 typeServer/connection 打开或关闭额外通道,使用相同传输类型和端点标识进行关闭。
关于消息面,文档列出的协议表面很小,包括版本查询、快照获取、快照变更通知、连接控制、Python 搜索路径、导入解析以及三类类型查询。三类类型查询的区别在于回答同一节点或声明的不同语义:computed 返回代码流推断出的类型,declared 返回源码中显式写出的类型,expected 返回上下文期望的类型。
错误处理沿用标准 JSON-RPC:过期快照用 -32802,参数非法用 -32602,内部失败用 -32603;错误消息应足够用于客户端日志定位,但不应暴露本地机密或实现内部状态。
影响分析:工具链的标准化信号
需要说明的是,以上事实均来自来源文档;以下影响分析属于编辑判断。
第一,TSP 把“类型查询”从编辑器实现细节中抽出来,为不同客户端和不同类型服务器之间建立可替换边界提供了可能。对开发者而言,这意味着未来可能出现不绑定特定 IDE 的类型分析服务,编辑器插件可以复用同一套查询语义。
第二,快照模型直接回应了类型分析结果易失效的问题。类型服务器频繁因文件变化而更新状态,客户端如果缓存结果,必须把结果与快照绑定,而不是把类型 ID 当作全局稳定标识。文档明确指出类型 ID 是响应局部的,不应跨响应比较。这一约束对编写缓存的开发者尤其重要。
第三,多连接模式把“只读并发”与“状态变更”分离,理论上可以避免高量的后台类型查询阻塞主连接上的文档同步。但文档也强调,服务器必须仍能在单连接模式下正确工作,多连接支持不是协议正确性的必要条件。因此短期内单连接仍是兼容基线,多连接属于优化项。
第四,协议仍处于 0.x 阶段,次版本可能破坏兼容。任何计划依赖 TSP 的产品都应在版本协商和降级策略上留出余地,而不是假设接口稳定。
行动建议:开发者与运维人员
对客户端开发者:在初始化后先调用 typeServer/getSupportedProtocolVersion 校验返回的 semver 是否兼容,再获取首个快照;所有类型查询都附带当前快照;收到 typeServer/snapshotChanged 后使旧结果失效并重新获取快照;把 -32802 当作可重试信号,而不是硬错误。位置与范围的转换要遵守 LSP 的零基行号和 UTF-16 代码单元约定,来源特别提醒编码转换错误会导致请求错误的语法节点。
对类型服务器实现者:严格区分主连接与额外连接允许的流量;额外连接应拒绝 LSP 消息、改变状态的通知、typeServer/connection 以及未在协商版本中允许的 TSP 消息;仅在确实能服务协商出的额外传输时才声明多连接能力;快照不得回退,且任何可能改变分析结果的事件都应推进快照;错误消息避免泄露本地机密或实现内部状态。
对运维与平台团队:如果考虑在生产环境部署类型服务器,应优先验证单连接模式的行为,再把多连接作为性能调优手段;关注 stdout 在 stdio 传输下必须保留给 JSON-RPC 协议消息这一约束,避免日志输出污染协议流;在升级 Pylance 或类型服务器时,把协议版本纳入变更管理,因为 0.x 的次版本升级可能带来不兼容。
对工具链选型者:可以把 TSP 视为观察方向,而不是立即押注的稳定标准。来源显示协议文档最近更新与 Pylance 2026.4.1 对齐,但未说明生态中已有多少独立实现,也未说明协议是否会被其他语言服务器采纳,这些都需要进一步观察。
资料来源
本文由自动化系统筛选公开技术信息,并经 AI 辅助整理。
本文转载自 github.com,版权归原作者所有。
原文链接:https://github.com/microsoft/pylance-release/blob/main/docs/tsp/type-server-protocol.md
抓取时间:2026年10月27日
本文采用 original 索引策略。