Meta의 Pyrefly가 당신에게 알리지 않고 경쟁 Python extensions를 방해한다
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일).
왜 이것이 문제인가
-
Silent global modification
ConfigurationTarget.Global은 사용자의 전역settings.json에 기록하여 모든 워크스페이스에 영향을 줍니다. 알림이나 프롬프트가 표시되지 않습니다. -
No cleanup on deactivation or uninstall
수정된 설정을 복원하는deactivate()로직이 없습니다. Pyrefly를 제거한 후에도 대상 확장 프로그램이 계속 손상된 상태로 남습니다. -
Hard‑coded extension IDs
코드는 일반적인 충돌 해결 메커니즘을 제공하는 대신 퍼블리셔 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()에서 해당 설정을 복원합니다. - 최소한 변경 사항을 로그에 기록하여 사용자가 되돌릴 수 있도록 합니다.
Source: …
추가적인 우려 사항: 강제 Microsoft 확장 의존성
package.json에 "extensionDependencies": ["ms-python.python"]이 선언되어 있습니다. 이는 양방향 잠금을 강제합니다:
-
Pyrefly를 설치하면 자동으로 다음이 설치됩니다:
ms-python.pythonms-python.debugpyms-python.vscode-python-envs
-
위 세 가지 중 하나를 제거하면 Pyrefly도 함께 제거됩니다.
ms-python.python이 제공하는 유일한 기능은 선택적 CodeLens 버튼을 위해 현재 Python 인터프리터를 조회하는 것입니다. 핵심 LSP 기능(타입 검사, 자동 완성, 호버, 정의로 이동)은 전적으로 pyrefly 바이너리를 통해 실행되며 ms-python.python에 대한 의존성이 없습니다. Microsoft 확장을 피하는 VSCodium 또는 기타 FOSS VS Code 배포판 사용자에게 이 숨겨진 의존성은 중요한 부작용이 됩니다.
재현 단계
detachhead.basedpyright를 설치하고 작동을 확인합니다(완성, 호버 등).meta.pyrefly를 설치합니다.- Python 파일을 엽니다(Pyrefly가 활성화됩니다).
- 전역
settings.json을 확인합니다;basedpyright.disableLanguageServices가true가 됩니다. meta.pyrefly를 제거합니다.basedpyright.disableLanguageServices가 여전히true로 남아 있어, basedpyright가 깨지고 이유에 대한 표시가 없음을 확인합니다.