Meta의 Pyrefly가 당신에게 알리지 않고 경쟁 Python extensions를 방해한다

발행: (2026년 5월 3일 AM 01:34 GMT+9)
5 분 소요

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에서 활성화 시 무조건 호출됩니다.

관련 커밋: 69985d1d, c0ab0d76, 72458900, 2fb5205a (2025년 12월 8‑9일).

왜 이것이 문제인가

  1. Silent global modification
    ConfigurationTarget.Global은 사용자의 전역 settings.json에 기록하여 모든 워크스페이스에 영향을 줍니다. 알림이나 프롬프트가 표시되지 않습니다.

  2. No cleanup on deactivation or uninstall
    수정된 설정을 복원하는 deactivate() 로직이 없습니다. Pyrefly를 제거한 후에도 대상 확장 프로그램이 계속 손상된 상태로 남습니다.

  3. 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.python
    • ms-python.debugpy
    • ms-python.vscode-python-envs
  • 위 세 가지 중 하나를 제거하면 Pyrefly도 함께 제거됩니다.

ms-python.python이 제공하는 유일한 기능은 선택적 CodeLens 버튼을 위해 현재 Python 인터프리터를 조회하는 것입니다. 핵심 LSP 기능(타입 검사, 자동 완성, 호버, 정의로 이동)은 전적으로 pyrefly 바이너리를 통해 실행되며 ms-python.python에 대한 의존성이 없습니다. Microsoft 확장을 피하는 VSCodium 또는 기타 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

관련 글

더 보기 »