Meta的 Pyrefly 在未告知你的情况下破坏竞争的 Python 扩展
Source: Hacker News
受影响的扩展
detachhead.basedpyrightcodeium.windsurfpyrightanysphere.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 中被调用。
相关提交:69985d1d、c0ab0d76、72458900、2fb5205a(2025年12月8‑9日)。
为什么这是个问题
-
静默全局修改
ConfigurationTarget.Global会写入用户的全局settings.json,影响所有工作区。不会显示任何通知或提示。 -
停用或卸载时未清理
没有deactivate()逻辑来恢复已修改的设置。卸载 Pyrefly 后,受影响的扩展仍然损坏。 -
硬编码的扩展 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.pythonms-python.debugpyms-python.vscode-python-envs
-
卸载上述任意三个扩展也会卸载 Pyrefly。
ms-python.python 唯一提供的功能是查询活动的 Python 解释器以显示可选的 CodeLens 按钮。核心 LSP 功能(类型检查、补全、悬停、转到定义)完全通过 pyrefly 二进制运行,且不依赖 ms-python.python。对于使用 VSCodium 或其他避免 Microsoft 扩展的 FOSS VS Code 发行版的用户来说,这一隐藏的依赖是一个重要的副作用。
重现步骤
- 安装
detachhead.basedpyright并确认其功能正常(代码补全、悬停提示等)。 - 安装
meta.pyrefly。 - 打开一个 Python 文件(触发 Pyrefly 激活)。
- 检查全局
settings.json;此时basedpyright.disableLanguageServices为true。 - 卸载
meta.pyrefly。 - 观察到
basedpyright.disableLanguageServices仍保持为true,导致 basedpyright 损坏且没有任何提示说明原因。