Meta的 Pyrefly 在未告知你的情况下破坏竞争的 Python 扩展

发布: (2026年5月3日 GMT+8 00:34)
4 分钟阅读

Source: Hacker News

受影响的扩展

  • detachhead.basedpyright
  • codeium.windsurfpyright
  • anysphere.cursorpyright

Source

lsp/src/extension-interop.ts:

export async function disableWindsurfPyrightIfInstalled() {
  const windsurfPyrightExtension = vscode.extensions.getExtension('codeium.windsurfpyright');
  if (windsurfPyrightExtension) {
    const config = vscode.workspace.getConfiguration('windsurfPyright');
    await config.update('disableLanguageServices', true, vscode.ConfigurationTarget.Global);
  }
}

export async function disableBasedPyrightIfInstalled() {
  const basedPyrightExtension = vscode.extensions.getExtension('detachhead.basedpyright');
  if (basedPyrightExtension) {
    const config = vscode.workspace.getConfiguration('basedpyright');
    await config.update('disableLanguageServices', true, vscode.ConfigurationTarget.Global);
  }
}

export async function disableCursorPyrightIfInstalled() {
  const cursorPyrightExtension = vscode.extensions.getExtension('anysphere.cursorpyright');
  if (cursorPyrightExtension) {
    const config = vscode.workspace.getConfiguration('cursorpyright');
    await config.update('disableLanguageServices', true, vscode.ConfigurationTarget.Global);
  }
}

这些函数会在激活时无条件地在 lsp/src/extension.ts 中被调用。

相关提交:69985d1dc0ab0d76724589002fb5205a(2025年12月8‑9日)。

为什么这是个问题

  1. 静默全局修改
    ConfigurationTarget.Global 会写入用户的全局 settings.json,影响所有工作区。不会显示任何通知或提示。

  2. 停用或卸载时未清理
    没有 deactivate() 逻辑来恢复已修改的设置。卸载 Pyrefly 后,受影响的扩展仍然损坏。

  3. 硬编码的扩展 ID
    代码通过发布者 ID 禁用特定竞争对手的扩展,而不是提供通用的冲突解决机制。用户无法选择退出。

实时复现

测试 1 — VSCodium

  • 安装 Pyrefly 前 (~/.config/VSCodium/User/settings.json):
{
  "python.languageServer": "Default"
}
  • 安装 Pyrefly 并打开 Python 文件后:
{
  "python.languageServer": "Default",
  "basedpyright.disableLanguageServices": true
}
  • 卸载 Pyrefly 后(键仍然存在):
{
  "python.languageServer": "Default",
  "basedpyright.disableLanguageServices": true
}

测试 2 — VS Code 1.118.1(干净的隔离配置文件)

  • 安装 Pyrefly 前settings.json 不存在(空配置文件)。

  • 安装 detachhead.basedpyright,随后 meta.pyrefly,并打开 Python 文件后:

{
  "python.languageServer": "None",
  "basedpyright.disableLanguageServices": true
}

写入发生在第一次打开 Python 文件时,无论之前的配置如何。

预期行为

如果 Pyrefly 需要对 Python 语言服务进行独占访问,它应当:

  • 在修改其他扩展拥有的设置之前提示用户。
  • 当 Pyrefly 被禁用或卸载时,在 deactivate() 中恢复这些设置。
  • 至少记录这些更改,以便用户能够逆转它们。

附加关注:强制的 Microsoft 扩展依赖

package.json 声明了 "extensionDependencies": ["ms-python.python"]。这会产生一个硬性的双向锁定:

  • 安装 Pyrefly 会自动安装:

    • ms-python.python
    • ms-python.debugpy
    • ms-python.vscode-python-envs
  • 卸载上述任意三个扩展也会卸载 Pyrefly。

ms-python.python 唯一提供的功能是查询活动的 Python 解释器以显示可选的 CodeLens 按钮。核心 LSP 功能(类型检查、补全、悬停、转到定义)完全通过 pyrefly 二进制运行,且不依赖 ms-python.python。对于使用 VSCodium 或其他避免 Microsoft 扩展的 FOSS VS Code 发行版的用户来说,这一隐藏的依赖是一个重要的副作用。

重现步骤

  1. 安装 detachhead.basedpyright 并确认其功能正常(代码补全、悬停提示等)。
  2. 安装 meta.pyrefly
  3. 打开一个 Python 文件(触发 Pyrefly 激活)。
  4. 检查全局 settings.json;此时 basedpyright.disableLanguageServicestrue
  5. 卸载 meta.pyrefly
  6. 观察到 basedpyright.disableLanguageServices 仍保持为 true,导致 basedpyright 损坏且没有任何提示说明原因。
0 浏览
Back to Blog

相关文章

阅读更多 »