Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 773 – Windows용 Python 설치 관리자

Author:
Steve Dower
Discussions-To:
Discourse thread
Status:
Final
Type:
Standards Track
Topic:
Release
Created:
21-Jan-2025
Post-History:
18-Dec-2024, 21-Jan-2025
Replaces:
397, 486
Resolution:
25-Apr-2025

Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

Important

This PEP is a historical document. The up-to-date, canonical documentation can now be found at Python Releases for Windows.

×

See PEP 1 for how to propose changes.

초록

Windows에서 python.org Python 배포판을 설치하는 작업은 복잡합니다. 대략 동등한 수준의 사용자 경험을 제공하는 세 가지 주요 접근 방식이 있지만, 현대적인 사용 시나리오를 충족하지 못하는 것을 비롯해 이들 모두 서로 다른 제한 사항을 겪습니다. 이 PEP는 해당 플랫폼의 기존 설치 관리자가 필요로 하는 모든 사항을 충족하면서 대부분의 제한 사항을 피하고, 핵심 팀이 앞으로 수년간 릴리스를 관리할 수 있도록 하는 단일 Windows 설치 워크플로 도구의 설계를 제안합니다.

새 설치 관리자에서는 Windows에서 기본 Python을 실행하는 권장 명령이 python이 되며, 여러 버전을 관리하는 명령(특정 버전 실행 포함)은 py가 됩니다. 사용자는 PATH 환경 변수에 항목을 하나 더 추가하여 전역 python3.x 명령을 사용할 수도 있습니다. 기능에 대한 가장 간결한 고수준 개요를 보려면 “How to teach this” 섹션부터 시작할 것을 권장합니다.

기존 .exe 설치 관리자와 py 런처는 이 PEP가 승인된 후 2년이 지나면 더 이상 사용되지 않게 되고 릴리스되지 않습니다. 기존 임베더블 배포판은 더 이상 다운로드 항목으로 나열되지 않지만 설치 관리자를 통해 이용할 수 있습니다. Windows Store 앱은 즉시 설치 관리자로 대체됩니다.

독자를 위한 주의사항

이 문서는 Windows에서 Python의 기존 설치 형식을 새로운 형식으로 교체할지에 대한 “승인” 또는 “거부” 결정을 돕기 위한 상세한 제안을 담고 있습니다. 이 문서는 구속력 있는 사양, 사용자 문서 또는 상호 운용성 사양을 목적으로 하지 않습니다. 실제 구현은 요구 사항이 변경됨에 따라 시간이 지나면서 달라질 수 있으며, 이는 이 PEP의 “위반”으로 간주되지 않습니다. 공용으로 사용하도록 의도된 모든 인터페이스와 프로토콜은 표준 지원 중단 일정에 따라 독립적으로 문서화되고 유지 관리됩니다.

Windows에 Python을 설치하는 문서는 docs.python.org/using/windows.html에서 확인할 수 있습니다.

배경

사용자에게는 Python 런타임을 설치하고 싶게 만드는 매우 다양한 요구가 있을 수 있습니다. 많은 사용자, 아마도 대부분의 사용자는 간단한 작업을 수행하거나 누군가에게 개념을 가르치는 데 도움을 주는 등의 짧은 스크립트를 실행(어쩌면 작성)하는 데 관심이 있습니다. 일부 사용자는 기존 코드 또는 다른 애플리케이션과 통합하기 위해 특정 버전을 찾습니다. 일부 사용자는 테스트를 수행하기 위해 서로 다른 인터프리터 버전의 전체 모음을 원합니다.

이 절에서는 사용자가 “Python 설치”에 대해 기대하는 바를 논의하고, Windows용 기존 설치 관리자에 대한 개요를 제공하며, 이러한 제공 방식에 내재된 일부 공백과 과제를 식별합니다.

기대 사항

상당한 일화적 경험과 이용 가능한 정량적 데이터(반드시 공개된 것은 아님)에 대한 분석을 바탕으로, Windows의 대다수 Python 사용자에 대해 다음과 같이 주장합니다:

  • 대부분의 사용자는 최신 안정 버전만 원합니다.
  • 대부분의 사용자는 “한 번의 클릭”(또는 그 이하)으로 설치하기를 원합니다.
  • 대부분의 사용자는 관리자 권한을 사용하기를 원하지 않습니다.
  • 대부분의 사용자는 유지 관리 업데이트를 설치하면 혜택을 얻습니다.
  • 대부분의 사용자는 설치 후 python 명령이 작동하기를 기대합니다.

이러한 주장을 뒷받침하는 주요 근거는 사용자가 적극적으로 선택하는 가장 인기 있는 설치 관리자가 python.org의 최신 안정 릴리스와 Windows Store의 최신 안정 릴리스이며, 이 둘 모두 이러한 요구 사항을 충족한다는 점입니다.

다음과 같이 다른 주요 사용자 집합에 대해 가정합니다. 이러한 집합은 서로 일부 겹칠 수 있으며, 일부 사용자는 이러한 조건을 모두 기대합니다.

  • 일부 사용자는 프로그래밍 방식으로 Python을 설치하려고 합니다.
  • 일부 사용자는 특정 버전을 설치하려고 합니다.
  • 일부 사용자는 여러 버전을 설치하려고 합니다.
  • 일부 사용자는 자신의 컴퓨터를 사용하는 모든 사용자를 위해 설치하려고 합니다.
  • 일부 사용자는 시작 메뉴 바로 가기를 원하지 않습니다.
  • 일부 사용자는 프로젝트의 빌드 프로세스의 일부로 설치하려고 합니다.
  • 일부 사용자는 프로젝트의 설치 프로세스의 일부로 설치하려고 합니다.
  • 일부 사용자는 설치된 버전을 절대 업데이트하지 않을 예정입니다.
  • 일부 사용자는 설치 후 py 명령이 작동하기를 기대합니다.

이러한 가정은 상대적인 중요도가 정량화되지는 않았지만, 시간이 지나면서 모두 실제로 존재하는 것으로 입증되었습니다. 이러한 요구 사항의 대부분은 NuGet packagesembeddable distro로 충족할 수 있습니다.

기존 설치 관리자

기존 설치 관리자는 python.org에서 직접 다운로드할 수 있으며 Python의 전체 개발 키트를 설치하는 실행 파일입니다. 여기에는 CPython 인터프리터, 표준 라이브러리, Python 헤더와 임포트 라이브러리, Tcl 및 Tk 빌드, HTML 파일 형식의 문서, 런타임 및 표준 라이브러리 테스트 모음, Python 및 IDLE의 시작 메뉴 바로 가기, 바이너리의 디버깅 기호와 디버그 빌드, py.exe 런처와 해당 파일 연결, 사용자의 PATH 환경 변수를 수정하는 기능, 시스템에서 긴 경로 지원을 활성화하는 기능, 표준 라이브러리의 .pyc 파일을 미리 생성하는 기능, pip를 설치하는 기능이 포함됩니다. 3.13부터는 실험적인 자유 스레드 바이너리 집합도 포함됩니다. 이러한 구성 요소 중 다수는 선택 사항입니다.

실행 파일을 다운로드한 후 사용자에게 대부분의 옵션이 활성화된 상태로 사용자 디렉터리에 설치하는 “빠른 설치” 옵션이 표시됩니다. 대부분의 사용자가 이 옵션을 선택한다고 생각합니다.

빠른 설치와 함께 제공되는 두 번째 옵션을 선택하면 두 페이지 분량의 옵션이 표시되며, 여기에는 설치할 필요가 없는 구성 요소와 설치 디렉터리, 모든 사용자를 위해 설치할지 여부 등의 기타 옵션이 나열됩니다.

이러한 모든 옵션은 명령줄에서 지정할 수 있으며, UI를 표시하지 않고 설치를 진행하는 옵션도 있습니다. 피드백과 버그 보고에 따르면, 적어도 일부 사용자는 이러한 모든 옵션을 사용합니다. 그러나 설치 원격 측정 데이터를 추적하지 않으므로 어떤 옵션이 다른 옵션보다 중요한지 알 방법이 없습니다.

내부적으로 기존 설치 관리자는 Wix Toolset 설치 프레임워크를 사용하여 생성된 Burn 번들이며, 각 기능에 대해 하나 이상의 MSI 파일을 포함합니다. 이 프레임워크는 Microsoft 자체에서도 광범위하게 사용되며, Windows Installer를 사용하는 가장 직접적인 방법을 제공합니다. 이 번들은 해당 프레임워크의 템플릿을 기반으로 한 사용자 지정 C++ 애플리케이션으로, 설치 관리자의 전체 동작을 사용자 지정하여 실제로 설치해야 하는 MSI 파일을 정확히 결정할 수 있게 합니다. 파일 복사, 레지스트리 업데이트, 바로 가기 생성 과정은 전적으로 Windows Installer가 처리합니다.

의도된 용도 외에도, 많은 사용자가 등록되지 않은 설치와 자동화된 CI 시스템 설치 등 다른 시나리오에 기존 설치 관리자를 사용하려고 (시도할) 것이라고 이해하고 있습니다. 더 나은 대안이 있지만 그 대안은 그만큼 명확하지 않으며, 향후 설계에서 이러한 시나리오를 더 쉽게 만들 수 있기를 바랍니다.

Windows Store

CPython용 Windows Store 패키지는 다른 패키지와 거의 동일한 바이너리를 사용하여 일반 릴리스 프로세스의 일부로 생성됩니다. 앱 스토어 패키지라는 특성상 기본 python.exe는 자신의 위치를 올바르게 확인할 수 있도록 개선되며, PATH 환경 변수 설정이 없다는 점을 보완하기 위해 대체 pip.exe 및 기타 바로 가기가 포함됩니다. 이러한 기능은 저장소의 PC\python_uwp.cpp에 구현되어 있습니다.

이러한 패키지는 Microsoft Store 앱에서 Python을 검색하여 설치하며, 검색 결과에는 3.8 이후 각 주요 버전이 표시됩니다. 그런 다음 사용자는 버전을 선택하여 설치해야 합니다. 이러한 패키지에는 CPython 인터프리터, 표준 라이브러리, Tcl/Tk, IDLE 및 pip가 포함되며, python.exe, python3.exe, python3.X.exe, pip[3[.X]].exeidle[3[.X]].exe에 대한 파일 연결, 시작 메뉴 바로 가기 및 전역 명령이 생성됩니다. PATH 수정은 가능하지도 필요하지도 않지만, 사용자는 “Manage App Execution Alias” 설정 페이지에서 전역 바로 가기를 관리해야 할 수 있습니다.

또한 Microsoft는 새로 설치한 Windows에 기본 python.exe 명령을 추가했습니다. 이 명령은 아직 Python이 설치되지 않은 컴퓨터에서 사용자가 Python을 실행하려는 시도를 포착합니다. 명령을 직접 실행하면 Microsoft Store 앱에서 일반적으로 최신 버전인 권장 Python 앱이 포함된 페이지가 열립니다. 이 앱은 전적으로 Microsoft가 제어합니다. Python 앱과 관련된 텔레메트리(업스트림 Python 프로젝트가 통제하는 앱)를 기반으로 하면, 매월 약 300,000건의 설치가 이 리디렉터를 통해 이루어지며 해당 버전 전체 설치의 약 90%를 차지합니다.

이면에서 Store 패키지는 APPX 또는 MSIX로 알려진 Microsoft의 새로운 앱 설치 기술을 기반으로 합니다. 이는 소량의 메타데이터가 포함된 일반 ZIP 파일과 본질적으로 같지만, 설치는 운영 체제가 처리합니다. 이러한 파일은 항상 고정된 위치에 압축 해제되며, 모든 사용자가 액세스할 수 있지만 누구도 수정할 수 없고 최신 릴리스로 자동 업데이트됩니다. 사용자의 자체 데이터는 사용자 프로필 내 OS 관리 위치에 저장되며, 일반적인 OS 기능을 사용하여 초기화, 백업 및 복원할 수 있습니다.

NuGet 패키지

CPython용 NuGet 패키지는 일반 릴리스 프로세스의 일부로 생성 및 게시됩니다. 내용은 기존 설치 관리자와 동일합니다. NuGet 패키지는 .NET 언어와 일반적으로 연관되지만 Visual Studio가 지원하는 모든 프로젝트와 긴밀하게 통합된 패키지 관리자인 nuget.org에 게시됩니다. 따라서 일반적인 빌드 프로세스의 일부로 Python을 가볍게 설치하려는 사용자에게 적합한 형식이며, 임베딩 시나리오를 간소화할 수 있습니다.

패키지는 NuGet API를 사용할 수 있는 모든 도구를 사용하여 설치하거나, 패키지 URL을 알고 있다면 직접 다운로드할 수 있습니다. 패키지는 일부 메타데이터가 포함된 일반 ZIP 파일입니다. 여기에는 CPython 인터프리터, 표준 라이브러리, 개발 헤더와 임포트 라이브러리 및 pip가 포함됩니다. 설치 시 코드를 실행하지 않으며, 사용자는 패키지 내부에 포함된 python.exe를 실행하려면 패키지를 직접 찾아야 합니다.

임베더블 패키지

CPython용 임베더블 패키지는 일반 릴리스 프로세스의 일부로 생성 및 게시됩니다. 기존 설치 관리자와 함께 python.org에 게시됩니다. 내용은 동일하지만, 모든 바이너리를 최상위 수준에 저장하고 표준 라이브러리를 ZIP 파일에 패키징하도록 레이아웃이 변경되었습니다. 배포판에 포함된 파일만 사용하도록 sys.path를 재정의하는 ._pth 파일이 포함되며, 환경 변수와 레지스트리 항목은 무시됩니다.

이 패키지는 더 큰 애플리케이션에 임베드하는 것을 목적으로 하므로 pip를 포함하지 않습니다. 다른 라이브러리는 빌드 시 설치해야 합니다. 배포 후 런타임은 해당 앱의 내부 구현 세부 사항으로 사용되기 때문입니다.

의도된 용도뿐만 아니라, 일부 사용자는 이 패키지를 런타임 패키지라기보다 개발 키트로 사용하려고 합니다. 이는 해당 사용자들이 “heavyweight” 설치 관리자를 피하는 것을 선호하고, 이 패키지가 “portable” 설치(압축을 풀고 실행하는 방식) 용도라고 생각하기 때문으로 여겨지며, 아마도 python.org 다운로드 페이지에 나열된 유일한 ZIP 파일 옵션이기 때문일 것입니다(이는 해당 페이지에서 명확성을 확보하고 선택지를 제한하는 것이 중요함을 보여 줍니다). 향후 설치 관리자 설계에서는 이러한 혼란을 피하거나 제한할 수 있기를 바랍니다.

대체 배포판

핵심 팀의 소관을 벗어나는 내용이지만, Windows용 Python 대체 배포판은 런타임 설치에 프로젝트, 워크플로 또는 환경 중심 모델을 사용하는 경우가 많습니다. 이는 도구를 먼저 설치한 다음, 런타임과 기타 의존성을 포함하는 작업 공간을 만드는 데 사용한다는 의미입니다. 이러한 도구의 예로는 conda와 uv가 있습니다.

이러한 도구에 관해서는 두 가지 관찰을 해 볼 만합니다. 첫째, 일반적으로 런타임을 위한 추가 진입점이나 파일을 설치하지 않으므로 설치가 빠르고 단일 프로젝트로도 격리된다는 점에서, 이러한 도구는 영향이 적다고 높이 평가받는 경우가 많습니다. 둘째, 이러한 도구의 사용자는 런타임의 특정 버전을 쉽게 선택할 수 있다는 점을 자주 높이 평가하며, 또는 기존 사양(또는 제약 조건)이 대신 선택할 수 있으므로 아예 선택할 필요가 없다는 점을 높이 평가합니다.

이러한 도구는 위에서 설명한 두 번째 기대 사항 집합의 많은 부분을 충족하는 경향이 있으며, 여러 명령을 사용하고 조합하는 방법을 배우는 데 따르는 인지적 부담을 줄이기 위해 여러 작업을 하나의 명령으로 결합하는 경우가 많습니다.

또한 핵심 팀은 이러한 대체 배포판을 어떤 상위 배포판의 경쟁자로도 보지 않는다는 점을 지적할 필요가 있습니다. 이러한 배포판은 오픈 소스 생태계가 의도된 방식으로 작동하는 데 있어 근본적인 부분입니다. 모든 시나리오가 워크플로 도구나 사전 빌드 패키지로 충분히 지원되는 것은 아니므로, 자체 배포판은 이를 사용하기로 선택한 사람들에게 편의를 제공합니다.

과제

현재 설치 관리자 집합에는 수많은 과제가 있으며, 이는 대체로 맞지 않거나 달성할 수 없는 사용자 기대와 전반적인 불안정성이라는 두 가지 범주로 나뉩니다.

기존 설치 관리자는 불안정성이 가장 높습니다. Windows Installer 기술은 매우 오래되었으며 사실상 더 이상 개발되지 않습니다. 기본 기능은 괜찮지만, 바이러스 검사기, 다른 설치 관리자, 시스템 구성, 관리자 정책, 심지어 설치 관리자와 같은 디렉터리에 있는 다른 파일 등 여러 원인에서 간섭이 발생할 수 있습니다. 게다가 업데이트 패치, 증분 업데이트, 자동 롤백과 같은 고급 기능이자 유용한 기능의 대부분은 Python 사용자에게 중요하지 않습니다.

대부분의 사용자 기대 사항은 기존 설치 관리자에 의해 정의되며, 따라서 정의상 기존 설치 관리자는 이러한 기대를 충족합니다. 주요 간극 중 하나는 “unmanaged” 설치, 즉 등록 없이 사용자의 시스템에 파일만 복사하는 것과 동등한 설치를 만들 수 없다는 점입니다. 한 번 설치한 후 다시 설치하려고 하면, 기존 설치를 관리(또는 업그레이드)하는 것만 가능하게 됩니다. 이로 인해 업데이트 시 설치 위치가 이동할 수 있으며, 이는 사용자를 곤란하게 만듭니다.

또한 PATH환경 변수는 지능적으로 수정할 수 없으며, 기껏해야 설치 경로를 앞에 추가하거나 뒤에 추가할 수 있습니다. 이로 인해 대개 가장 최근에 설치된 Python이 가장 높은 우선순위를 갖게 됩니다. 예를 들어 사용자가 Python 3.14를 설치한 후 3.13을 설치(또는 업데이트)하면 python명령이 나중 버전에서 이전 버전으로 전환됩니다.

py.exe 실행기는 PEP 397에 정의되어 있고 PEP 514에 의해 암묵적으로 업데이트되며, 이 특정 문제를 피하려는 시도입니다. 이는 PATH에 의존하지 않고 설치된 버전을 찾기 위해 자체 로직을 사용합니다. 그러나 PEP 514 로직은 프리릴리스 또는 실험적 빌드를 특별히 처리하는 것을 허용하지 않으므로, py.exe는 사용자가 예상하는 비실험적 버전보다 이러한 빌드를 기본적으로 선호하는 경우가 많습니다.

Windows 스토어 패키지는 전역 바로 가기를 제외하면 매우 안정적입니다. 자체 디렉터리를 추가하도록 PATH를 수정하는 대신, 이러한 바로 가기는 모든 앱에서 정의한 바로 가기가 포함된 단일 OS 관리 디렉터리에 생성됩니다. 사용자는 이 디렉터리를 제외하거나 우선순위를 낮추도록 PATH를 수정할 수 있으며, 이로 인해 동작이 불안정하거나 일관되지 않게 됩니다. 역사적으로는 설치 프로그램 때문에 이러한 문제가 발생하기도 했습니다. 예를 들어, 스토어에서 Python을 설치한 다음 PATH수정이 활성화된 기존 설치 프로그램으로 Python을 설치하면, 나중에 설치한 버전이 스토어 패키지의 Python을 거의 항상 가리게 됩니다.

스토어 패키지가 충족하지 못하는 사용자 기대는 대체로 성능 및 기술적 측면과 관련됩니다. 앱을 실행하는 데 따르는 오버헤드로 인해 Python의 시작 속도가 느립니다. 앱은 서로 격리되도록 설계되므로, 각 버전이 자체 공간을 가지는 탓에 서로 다른 Python 버전 간 통신에 AppDataTEMP같은 숨겨진 디렉터리를 사용하기가 더 어렵습니다. 앱에는 레거시 애플리케이션에서 일반적으로 비활성화되어 있는 DLL 하이재킹 방지와 같은 더 엄격한 보안 요구 사항이 적용되며, 이로 인해 일부 라이브러리가 작동하지 않습니다. python3python 바로 가기는 시스템 설정을 통해 관리되며, 사용자 인터페이스는 그다지 좋지 않습니다(그리고 Microsoft에 따르면 개선될 예정도 없습니다). 이를 관리하지 않으면 원하지 않는 버전이 실행되기 쉽지만, 일반적으로 대상은 사용자만 수동으로 변경할 수 있으며 다른 앱을 설치하는 것만으로 변경되지는 않습니다.

NuGet 패키지와 임베더블 배포판은 모두 아카이브 파일을 추출하는 것만큼 간단하고 안정적으로 설치할 수 있지만, 많은 Python 사용자에게 이는 일반적인 작업이 아니라는 점에 유의할 필요가 있습니다. 이들은 설치 관리를 전혀 제공하지 않으며, 삭제한 후 다시 추출하는 방법 외에는 안정적으로 업데이트할 수 없습니다. 충족되지 않는 사용자 기대는 거의 항상 사용자가 잘못된 설치 프로그램을 선택했기 때문에 발생합니다. 이 두 패키지는 모두 특수한 용도를 위한 것이며, 그러한 용도로 문서화되어 있지만 단순한 ZIP 파일이라는 매력 때문에 일부 사용자는 실패하게 됩니다.

PyManager 개요

PyManager는 제안된 대체 설치 도구의 내부 이름입니다. 이 도구는 Windows 스토어와 python.org 양쪽에서 MSIX 패키지로 배포됩니다. 어느 출처에서 다운로드하든 동일한 패키지를 받게 되며, 두 출처 모두 새 릴리스에 대한 자동 업데이트(스토어를 통해)를 지원합니다.

사용자가 보게 될 이름은 Python Software Foundation에서 게시하는 “Python Install Manager”입니다. 게시 후 Microsoft에 해당 python.exe 스텁이 이 새 앱을 열도록 조정해 달라고 요청할 예정입니다.

이 앱은 Python 버전을 직접 제공하지 않지만, 사용자가 작동할 것으로 기대하는 전역 명령과 파일 연결 및 시작 메뉴 바로 가기를 제공합니다. 설치 후 OS가 사용자에게 앱을 실행하라는 메시지를 표시하며, 그러면 현재 CPython 릴리스가 자동으로 설치된 후 앱이 실행됩니다. 사용자 관점에서는 첫 실행 시 진행률 표시줄이 하나 추가되는 것을 제외하면 현재와 동일한 초기 경험을 하게 됩니다.

앱이 제공하는 전역 명령은 정적이어야 하며 앱 자체에 번들로 포함되어야 합니다. 이러한 명령은 런타임에 동작만 변경할 수 있으며, 사용자가 직접 변경하는 경우를 제외하면 다른 실행 파일로 리디렉션할 수 없습니다(그 경우에도 설치된 다른 앱으로만 리디렉션할 수 있습니다). 따라서 PyManager가 제공할 명령은 python.exe, python3.exe, py.exe, pymanager.exe입니다. 이러한 명령은 각각 사용자의 시스템을 검사하고 실행할 올바른 런타임을 선택할 수 있어야 합니다. 또한 pypymanager에는 런타임을 추가하고 제거할 수 있는 관리 하위 명령이 포함됩니다.

관련 PEP 394 및 Windows의 기본 동작에 따라 Python을 실행하는 데 권장되는 명령은 python.exe입니다. PyManager가 제공하는 이 명령은 PyManager가 관리하는 설치 중에서 또는 PEP 514를 사용하여 기존 설치를 찾으며, 그렇지 않으면 사용 가능한 최신 CPython 버전을 설치하고 이를 선택합니다. python3.exe 명령도 유사하게 동작하지만 python.org에서 설치된 3.x 버전만 찾을 수 있습니다.

PyManager가 제공하는 py.exe 명령은 간결하므로 대부분의 관리 용도에 권장됩니다. py install ..., py list ... 등입니다. 제안된 명령은 뒤에서 자세히 설명합니다. 그러나 PEP 397런처의 기존 동작은 유지되며, py를 통해 시작해도 런타임이 자동으로 설치되지는 않습니다(기본적으로). 런타임을 요청했지만 설치되어 있지 않으면 사용자에게 오류만 표시됩니다. 그러나 py exec ... 하위 명령은 자동으로 설치하며, 단독으로 사용하는 py와 동일한 옵션을 지원합니다.

운영 체제는 이러한 명령을 사용자의 PATH에 매우 낮은 우선순위로 추가합니다. 사용자의 컴퓨터에 이미 생성했을 수 있는 모든 구성은 이러한 명령보다 우선하므로, 이러한 명령은 오류 메시지를 대신하는 최후의 수단입니다. 따라서 일반적으로 사용자가 더 강한 선호 설정을 구성하지 않았기 때문에 이러한 명령을 실행한다고 간주할 수 있습니다. (예를 들어 환경을 활성화한 사용자는 활성화 과정에서 다른 실행 파일을 앞에 배치하므로 당사의 python.exe를 절대 실행하지 않으며, 기존 py.exe와 정확히 동일한 동작을 원하는 사용자는 이를 설치하기만 하면 되므로 당사의 새 실행 파일을 절대 실행하지 않습니다.)

pymanager.exe 명령은 모호한 상황을 처리할 수 있도록 제공됩니다. 기존 Python 설치 및 실행기가 python.exepy.exe를 가릴 수 있지만, 자동화된 환경에서는 이로 인해 관리 스크립트를 신뢰할 수 없게 될 수 있으므로 pymanager 명령은 PyManager가 아닌 다른 것을 가리킬 가능성이 낮습니다. 이 명령에는 모든 하위 명령이 포함되어 있으며, 명령을 지정하지 않고 실행하면 사용자에게 도움말을 출력합니다.

다른 설치 프로그램 교체

Windows Store에 개별 버전의 게시를 즉시 중단하고 Python 3.16까지 기존 설치 프로그램을 더 이상 사용하지 않도록 하며 단계적으로 폐지하는 것이 우리의 의도입니다. 임베더블 배포판은 유지되지만, python.org 다운로드 페이지의 목록에서는 단계적으로 제외되며 PyManager를 통해서만 제공됩니다. NuGet 패키지에는 변경 사항을 적용하지 않습니다.

PyManager는 python.org에서 수동으로 다운로드할 수 있는 앱 패키지로 제공되며, 일반적으로 두 번 클릭을 통한 설치 환경은 원활합니다. 이는 현재 당사 사이트에서 다운로드하는 방식과 동등한 방법을 제공합니다. 인터넷에 연결되지 않은 컴퓨터로 다운로드 파일을 옮긴 후에도 설치를 완료하면 Python 런타임을 제공할 수 있도록 최신의 (구체적으로 지정되지 않은) CPython 버전을 포함합니다.

일부 자동 배포 시나리오는 최신 MSIX 형식에서 작동하지 않으므로 python.org에 간단한 MSI도 제공합니다. 이 설치 프로그램에는 옵션이나 사용자 인터페이스가 없으며 관리자 권한이 필요합니다. 이러한 종류의 시나리오에서는 일반적으로 관리자 권한을 사용할 수 있습니다. 또한 Wine과 같이 MSIX 형식을 지원하지 않는 비표준 시스템의 사용자에게는 MSI가 필요합니다. MSI는 공식적으로 지원되지는 않지만, 이러한 플랫폼에서 CPython의 업스트림 배포판을 계속 사용할 수 있도록 합니다. 대부분의 다른 사용자에게는 MSI 사용을 권장하지 않으며, MSIX를 기본값으로 간주합니다.

MSI 설치를 MSIX와 완전히 호환되도록 만들 방법이 없으므로, 두 가지를 모두 사용하는 사용자는 혼란이나 문제를 겪을 가능성이 높다는 점에 유의할 필요가 있습니다. Store 앱을 지원하지 않는 사용자만 MSI를 사용할 것으로 예상됩니다.

우리의 릴리스 프로세스에서는 python.org에 일반 ZIP 패키지를 게시하기 시작합니다. 이러한 패키지는 FTP 페이지에서 제공되지만 일반 다운로드 페이지에 직접 나열되지는 않습니다.

현재 자체 CPython 빌드를 배포하는 서드파티 도구는 당사의 빌드를 사용해도 되지만, 지원이 필요한 사용자를 위한 최초 문의 창구 역할은 해당 도구가 맡을 것으로 예상합니다.

프로젝트 소유권 및 개발

PyManager는 CPython 저장소와 인접한 자체 저장소에서 동일한 조건으로 개발 및 유지 관리됩니다. CPython CLA가 적용되며, 핵심 개발자만 모두 커밋 권한을 가집니다.

PyManager의 릴리스는 CPython의 릴리스와 독립적입니다. 버전이 일치하거나 릴리스가 동시에 이루어질 필요는 없습니다. 달리 정하지 않는 한 PyManager 릴리스 관리자는 Windows 빌드 관리자입니다.

사양

Note

이 문서에서는 모든 명령줄 옵션을 하이픈 하나 또는 두 개와 함께 표시합니다. 구현에서는 Windows와 UNIX 규칙을 모두 허용하기 위해 모든 옵션에서 하이픈 하나 또는 두 개 또는 슬래시를 지원합니다.

Exec 서브명령

py [-V:<TAG>] [interpreter opts] [script.py|-m module|-c code] [script args]
py [-3.*] [interpreter opts] [script.py|-m module|-c code] [script args]
python ...
python3 ...
pymanager exec -V:tag ...
pymanager exec -3.* ...

이 서브명령은 런타임을 선택하고 실행하는 데 사용됩니다. 이 명령은 py 명령의 기본 동작이며, pythonpython3 명령에서 지원되는 유일한 동작입니다. 기존의 이러한 명령 사용 방식과 일관성을 유지하기 위해 기본 옵션은 각 경우에 따라 미묘하게 다릅니다.

이 서브명령은 pypymanager 모두에서 사용할 수 있습니다. 그러나 py에서는 기본적으로 제공되므로 사용자가 이를 사용할 것으로 예상하지는 않습니다. py, pythonpython3 명령은 런타임을 실행하는 기본 방법이고, pymanager exec는 고급 시나리오를 위한 것이라는 취지입니다.

-V:tag 명령은 명령줄에서 특정 런타임을 요청하는 데 사용됩니다. 태그는 Company\\Tag 쌍이거나, 슬래시가 포함되지 않은 경우에는 Tag만이며, PEP 514에 정의된 방식으로 사용됩니다. -3.*옵션은 -V:PythonCore\\3.*로 해석됩니다. 이 옵션은 pypy exec 변형에서만 사용할 수 있습니다.

명령줄에 태그가 지정되지 않았고 스크립트 파일이 지정된 경우, 스크립트에서 셰뱅을 검사합니다. 인식된 패턴과 일치하는 셰뱅이 발견되면 검색에 사용할 태그를 제공하거나, 다른 모든 처리를 무시하고 지정된 실행 파일을 추가적인 시도 없이 실행합니다. 이는 이식성을 위한 기능으로 의도되었지만 임의의 Windows 전용 경로가 허용되었던 (불행한) 레거시 지원을 처리하기 위한 것입니다. 일반적으로 /usr/bin/python3.13와 같은 단순한 패턴을 포함하는 셰뱅을 대상으로 하지만, /usr/bin/env python을 사용하는 셰뱅은 환경이 당사의 검색보다 신뢰성이 낮은 경향이 있으므로 도움이 되지 않을 가능성이 큽니다.

아직 태그가 요청되지 않았다면 VIRTUAL_ENV 환경 변수를 확인하여 환경이 활성화되었는지 확인합니다. 활성화되어 있다면 해당 환경이 요청으로 사용됩니다.

이 단계에서 태그가 요청된 경우 python3 명령은 해당 태그가 PythonCore\\3.*와 일치하는지 확인하고, 일치하지 않으면 오류와 함께 종료합니다. 이를 통해 다른 플랫폼과 일관되게 활성 환경에서 python3 명령을 사용할 수 있지만, 해당 환경에 이 명령이 포함되지 않았을 경우에는 사용할 수 없습니다. 이는 Windows에서 현재 존재하는 대부분의 Python 버전에 적용됩니다. (이 동작의 대안은 환경이 활성화되어 있을 때 python3이 항상 오류를 발생시키도록 하는 것이지만, 그 외의 동작은 사용자에게 일관되지 않게 동작합니다.)

태그가 요청되지 않았다면 기본값을 확인합니다. python3에서는 기본값이 PythonCore\\3이지만, 다른 모든 명령에서는 구성에서 읽습니다(환경 변수가 포함될 수도 있습니다). 그래도 비어 있다면 모든 태그를 허용합니다.

그런 다음 태그와 일치하는 설치된 런타임 중 가장 적합한 것을 선택하여 나머지 명령줄과 함께 실행합니다.

일치하는 런타임을 찾을 수 없는 경우, py execpymanager exec 명령은 사용자 설정이 허용하면 런타임 하나를 자동으로 설치하고 실행합니다. py, pythonpython3 명령은 오류를 보고하고 종료합니다. 그러나 다른 설치 프로그램에서 감지된 런타임이 없는 경우를 포함하여 런타임을 전혀 사용할 수 없는 경우에는 첫 번째 런타임이 자동으로 설치됩니다. 이를 통해 PyManager를 방금 설치한 신규 사용자가 최신 버전(또는 요청한 버전)의 CPython을 곧바로 실행할 수 있는 유용한 최초 실행 환경이 제공됩니다. 이 최초 실행 이후에는 요청한 런타임을 찾을 수 없을 때 오류가 다시 보고됩니다.

설치 서브명령

py install [-s|--source <URL>] [-f|--force] [-u|--upgrade] tag [...]
py install [-s|--source <URL>] [-t|--target <DIR>] tag
py install [-s|--source <URL>] [-d|--download <DIR>] tag [...]
py install --refresh

Note

이 서브명령과 이후의 모든 서브명령은 pymanager에서도 사용할 수 있습니다. 그러나 py를 일반적으로 사용하는 명령으로 삼으려 하므로 해당 명령만 표시합니다.

이 서브명령은 현재 컴퓨터에 하나 이상의 런타임을 설치합니다. 태그는 Company\\Tag 쌍(슬래시가 포함되지 않은 경우에는 Tag만)이며, 색인 파일을 검색하는 데 사용됩니다. 회사 이름은 대소문자를 구분하지 않는 접두사로 일치하며 접두사 일치보다 완전 일치를 우선합니다. 태그는 대소문자를 구분하지 않고 숫자를 인식하는 방식으로 일치하며, 점으로 구분된 숫자는 버전으로 처리됩니다. 태그는 나열된 “install for” 태그 중 하나와 일치해야 하며, 축약된 요청을 처리할 수 있도록 항목에는 이러한 태그가 여러 개 나열됩니다. 특수 태그 default는 사용자가 구성한 기본값으로 확인됩니다(일반적으로 3; 설정 구성에 대한 자세한 내용은 이후의 Configuration을 참조하십시오).

태그는 >, >=, <, <= 또는 !=를 사용한 제약 조건으로 지정할 수도 있으며, 그 뒤에 Company\\Tag 또는 Tag 값이 옵니다. 제약 조건을 일치시킬 때는 비교를 위해 기본 태그 메타데이터만 사용됩니다. 비교에서 버전을 인식하므로 >3.10과 같은 제약 조건은 최소 버전으로 3.11을 선택하는 반면, >3.10.0은 3.10.1을 선택할 수 있습니다.

임의의 태그에 대한 제약 조건의 동작은 일부 상황에서 직관에 맞지 않을 가능성이 큽니다. 제약 조건은 주로 일반적으로 버전 형태의 태그를 사용하는 업스트림 릴리스와 함께 사용되며, 특히 Requires-Python같은 기타 메타데이터가 처리되는 경우에 사용될 것으로 예상됩니다. 사용자는 범위보다는 편의를 위해 더 짧은 태그를 사용할 것으로 예상됩니다.

기본 색인 파일은 python.org에서 호스팅되며, 설치 가능한 모든 버전의 패키지 URL과 해시를 비롯한 설치 정보를 포함합니다. 사용자는 구성 파일 또는 --source 명령줄 옵션을 사용하여 대체 색인을 지정할 수 있으며, 관리자는 구성 파일을 통해 대체 색인을 지정할 수 있습니다. 요청한 태그는 색인 파일과 대조되며, 정확히 일치하는 항목이 있으면 해당 패키지가 선택됩니다. 정확히 일치하는 항목이 없는 경우에는 접두사 일치가 사용됩니다. 두 경우 모두 태그의 숫자는 논리적으로 처리됩니다. 즉, 3.13.1.2의 접두사이지만 3.10의 접두사는 아닙니다. 색인 파일에서 설치 태그를 정확히 지정하는 방법에 대한 자세한 내용은 아래의 색인 스키마를 참조하십시오.

태그가 기존 설치로 이미 충족되면 아무것도 설치되지 않습니다. 기존 설치를 교체하려면 사용자가 --upgrade 또는 --force 옵션을 전달해야 합니다. 전자는 더 최신 버전으로만 교체하는 반면, 후자는 동일한 버전인 경우에도 기존 설치를 제거하고 교체합니다.

태그를 제공하지 않고 명령을 호출하면 아무것도 설치되지 않지만, 도움말 텍스트와 오류가 표시됩니다(잘못된 옵션의 경우와 같습니다). 그러나 태그 없이 --upgrade를 전달하면 모든 설치를 업그레이드하려고 시도합니다.

--refresh를 전달하면 모든 설치의 메타데이터와 바로 가기가 재생성됩니다. 바로 가기의 우선순위 지정은 모든 설치가 일관된 상태인지에 따라 달라지므로, 이는 의도적으로 모든 설치에 한 번에 적용됩니다(예를 들어 최신 3.x 버전에는 python3.exe 바로 가기가 지정되어야 하는데, 사용자가 이전 설치만 새로 고치도록 선택할 수 있다면 처리가 복잡해집니다).

단일 태그만 함께 전달된 --target <DIR> 옵션은 해당 런타임을 설치로 등록하거나 별칭 및 바로 가기를 생성하지 않고 지정된 디렉터리로 추출합니다. 이는 임베딩 사례를 처리하거나 호환되지 않는 플랫폼용 파일을 다운로드하기 위한 것입니다. --target에 여러 태그를 전달하면 오류가 발생합니다.

--download <DIR> 옵션이 전달되면 런타임 패키지는 다운로드되지만 설치되지는 않습니다. 런타임 패키지는 지정된 디렉터리에 소스 패키지로 저장되며, 이러한 파일을 참조하는 index.json이 생성됩니다. 나중에 이 색인을 사용하여 python install --source <index.json> [tag ...]으로 오프라인 설치를 수행할 수 있습니다.

제거 하위 명령

py uninstall [-y|--yes] [--purge] [tag ...]

이 하위 명령은 현재 머신에서 하나 이상의 런타임을 제거합니다. 태그는 접두사 매칭을 포함하여 install 명령과 정확히 동일하지만, 기존 설치만 검사합니다. --yes 옵션이 전달되지 않으면 각 런타임을 제거하기 전에 사용자에게 확인을 요청합니다.

태그 없이 --purge옵션을 전달하면 확인 후 모든 런타임이 바로 가기 및 캐시된 파일과 함께 제거됩니다. --purge에 태그를 전달하면 오류가 발생합니다.

PyManager를 제거해도 설치된 런타임은 제거되지 않습니다. 기술적인 이유로 이는 안정적으로 수행할 수 없습니다(제거 시 임의의 코드를 실행할 수 없습니다). 따라서 대신 설치된 모든 항목이 계속 작동하도록 의도적으로 보장합니다. PyManager를 다시 설치하면 이러한 설치의 관리를 재개할 수 있습니다. PyManager를 제거하기 전에 py uninstall --purge를 실행하면 완전히 제거됩니다.

나열 하위 명령

py list [-f|--format <FMT>] [-1|--one] [--only-managed] [tag ...]
py list [-f|--format <FMT>] [-1|--one] [--online] [--source <URL>] [tag ...]
py [--list|--list-paths|-0|-0p]

이 하위 명령은 지정된 태그 또는 범위와 일치하는 설치를 모두 또는 일부 나열합니다. 태그가 제공되지 않으면 모든 설치를 나열합니다. PyManager가 관리하지 않는 런타임(활성 가상 환경 포함)도 별도로 나열될 수 있습니다.

기본 형식은 사용자 친화적입니다. 다른 형식에는 기계 판독 가능 형식과 단일 문자열 형식이 포함됩니다(예를 들어 --format=prefixsys.prefix를 한 줄에 단독으로 출력합니다). 정확한 형식 목록은 구현에 맡깁니다.

--one이 제공되면 최적의 결과 하나만 나열합니다. 이는 해당 런타임을 실행하지 않고 기본(또는 적절한) 런타임을 찾으려는 셸 스크립트를 지원하기 위한 것입니다. (여기서 “best”는 느슨하게 정의되지만, 결과에 사용자가 선호하는 기본 환경이 포함되어 있다면 항상 이를 의미합니다.)

--only-managed 옵션은 발견되었지만 PyManager가 관리하지 않는 런타임을 제외합니다. 예를 들어 일반적인 PEP 514 조회를 통해 발견된 런타임이 이에 해당합니다.

--source를 전달하면(또는 기본 소스를 암묵적으로 전달하도록 --online을 전달하면) 현재 설치된 런타임이 아니라 온라인 색인을 검색합니다. 이 옵션이 install하위 명령이 아니라 여기에 있는 이유는 필터링 및 형식 지정 옵션을 이미 list에서 사용할 수 있기 때문입니다.

py.exe 실행기의 레거시 --list, --list-paths, -0-0p 인자도 제공됩니다. 그러나 이러한 인자는 여기에 나열된 새 옵션을 지원하지 않으며, 기존 실행기의 출력을 재현하는 것으로 제한됩니다. 이 목록에서는 관리되지 않는 설치를 구분할 수 없습니다.

도움말 하위 명령

py help <COMMAND>

이 하위 명령은 지정된 각 명령의 도움말 텍스트를 표시하며, 아무것도 지정하지 않으면 명령 목록을 표시합니다. 명령 하나를 지정하는 것은 py <COMMAND> --help와 같습니다. 하위 명령 목록을 표시하는 것이 pymanager명령의 기본 동작입니다.

이 명령은 주로 사용자에게 더 많은 정보를 찾는 방법을 간단히 알려 주기 위해 추가되었습니다. 사용자에게 py help를 실행하라고 안내할 수 있습니다. 이렇게 하면 python -? 출력 내용을 재정의하거나 확장할 필요가 없습니다. 그렇지 않으면 해당 출력은 선택된 런타임으로 전달되며 이미 최소 한 화면 분량의 텍스트를 출력합니다.

자동 설치 후(예를 들어 아무것도 설치되지 않은 상태에서 python을 실행한 경우), 설치를 관리하는 방법에 관한 자세한 정보를 보려면 py help를 실행할 수 있다는 메시지가 표시됩니다.

환경 변수

스토어 앱을 설치할 때 환경 변수를 자동으로 업데이트할 수 없으므로 업데이트가 자동으로 수행되지 않습니다. 정상적으로 작동하는 컴퓨터에서는 핵심 명령을 이미 사용할 수 있어야 합니다.

사용자의 PyManager 데이터 디렉터리 내 디렉터리 하나는 생성된 별칭을 위해 따로 마련됩니다. 원하는 경우 사용자가 직접 이 디렉터리를 PATH에 추가할 수 있습니다. 이 디렉터리의 내용은 PyManager가 관리하며, 설치된 런타임을 직접 실행하는 실행 파일이 포함됩니다(예를 들어 Python 3.13을 설치하면 python3.exepython3.13.exe가 포함됩니다). 이 디렉터리에 별칭이 추가될 때마다 PATH를 확인하며, 해당 경로가 없으면 추가할 경로가 포함된 메시지를 사용자에게 표시합니다.

런타임에 설치된 패키지가 설치하는 스크립트는 또 다른 디렉터리에 위치합니다. 현재 설계상 이러한 스크립트를 모두 하나의 디렉터리 또는 여러 런타임이 공유하는 디렉터리에 설치하는 것은 안전하지 않다고 판단합니다. 그러나 향후에는 설치된 패키지의 메타데이터를 기반으로 PyManager가 자체 엔트리 포인트를 생성하는 명령이 추가될 수 있습니다.

시작 메뉴 바로 가기

사용자의 기본 웹 브라우저에서 PyManager 문서를 실행하는 시작 메뉴 바로 가기가 추가됩니다. 시작 메뉴에는 애플리케이션이 추가되지 않습니다.

Python 런타임을 설치할 때 설치 정의에서 해당 설치를 위해 생성할 시작 메뉴 바로 가기를 지정할 수 있습니다.

파일 연결

PyManager를 설치할 때 표준 파일 연결이 생성되며, 스크립트와 패키징된 앱을 PyManager의 전역 python.exe 별칭으로 실행합니다. 이를 통해 스크립트나 .pyz 파일을 두 번 클릭하는 사용자에게 합리적인 동작을 제공합니다.

창 모드 실행 파일

앞에서 설명한 각 전역 별칭에 대해 *w.exe도 존재합니다. 이러한 실행 파일은 콘솔 창을 생성하거나 연결하지 않고 실행되므로, 일반적으로 스크립트가 생성한 UI만 표시합니다. 예를 들어 IDLE은 항상 pythonw.exe를 사용하여 실행되며, 이렇게 하면 불필요한 네이티브 콘솔을 피할 수 있습니다.

그 밖의 경우 이러한 명령은 콘솔 대응 명령과 동일하게 동작합니다.

구성

PyManager는 JSON 기반 구성 파일의 계층 구조를 사용하여 구성됩니다. 명령줄 옵션은 항상 구성 파일 옵션보다 우선합니다. 사용자가 편집할 수 있는 위치의 구성 파일은 구성 옵션이나 명령줄 옵션으로 비활성화할 수 있습니다.

우선순위가 낮은 순서로 다음 위치에서 찾습니다:

  • 앱 패키지 내부에서
  • 관리자 전용 구성에서 지정된 항목
  • base_config 설정에서 (기본값: 없음)
  • user_config 설정에서 (기본값: %AppData%\\Python\\PyManager.json)
  • additional_config 설정에서 (기본값: %PYTHON_MANAGER_CONFIG%)
  • -c 명령줄 옵션으로 지정된 항목

각 구성 옵션의 구체적인 동작은 구현에 맡깁니다. 그러나 의도된 여러 옵션은 다른 절에서 논의합니다.

앱 패키지 구성은 PyManager를 다른 애플리케이션이나 패키지에 포함할 수 있도록 제공됩니다. 예를 들어, 다른 배포판에서 PyManager를 포함하되 자체 패키지 색인에서 설치 항목을 찾도록 할 수 있습니다. 앱 패키지 구성을 사용하면 당사의 빌드를 재사용하고 기본 설정을 재정의할 수 있습니다.

user_configadditional_config 설정은 이전 구성 파일에서 미리 구성되므로, 관리자 전용 구성이나 대체 루트 구성으로 재정의할 수 있습니다. 구성 파일이 해당 파일을 로드하게 만든 설정을 덮어쓰면 무시됩니다. base_config 설정도 이와 유사하지만 비어 있는 상태로 시작하며 관리자 구성으로 쉽게 재정의할 수 있도록 설계되었습니다.

관리자 전용 구성은 관리자가 그룹 정책이나 레지스트리 업데이트와 같은 기존 도구를 사용하여 자신이 관리하는 시스템을 관리할 수 있도록 제공됩니다. 이러한 제어는 설계상 재정의할 수 없으므로, 관리자가 PyManager의 사용을 방지하거나 제한하는 정책을 배포할 수 있습니다. 이러한 제어는 특정 환경에 PyManager를 안전하게 배포하는 데 필수적이며, 이러한 제어가 없다면 PyManager의 사용 자체가 금지되어 해당 사용자는 Python에 접근할 수 없게 됩니다.

주 관리자 전용 구성은 관리자가 자신이 관리하는 모든 위치에 배포할 수 있는 새로운 base_config 구성 파일의 경로가 되도록 의도되었습니다. 이를 통해 네트워크 관리자는 사용자를 강제로 제한하지 않고 사용자의 기본 Python 런타임의 출처를 제어하거나, 명령줄 옵션을 제외한 구성 파일의 다른 출처를 재정의할 수 있습니다.

색인 스키마

색인 파일은 온라인이나 로컬에서 제공되며, PyManager가 모든 Python 런타임을 찾고, 선택하고, 설치하고, 관리하는 데 필요한 모든 정보를 제공합니다.

색인은 JSON으로 저장됩니다. 주요 최상위 키는 versions이며, 객체 목록을 포함합니다. 각 버전 객체에는 자체 스키마 버전이 있으며, 파일 전체에 적용되는 스키마 버전은 없습니다. 향후 변경 사항에서는 기존 스키마에 안전하게 통합할 수 없는 기능을 제공하기 위해 최상위 키를 추가할 수 있습니다.

버전 객체는 색인 파일과 각 패키지 아카이브의 루트에 저장되는 __install__.json 사이에 분할될 수 있습니다. 번들 파일의 항목은 색인 파일의 누락된 정보를 보완합니다. 이는 일반적으로 큰 shortcuts 키를 색인 파일에서 제거할 수 있도록 하기 위한 것이지만, alias, executableexecutable_args까지 확장될 수도 있습니다. 색인에서 다른 키를 생략하면 패키지 설치에 문제가 발생할 수 있습니다. 올바른 동작을 보장하는 것은 구현에 맡깁니다. 이는 상호 운용성의 대상이 아니므로, 여기서는 적용되는 일반적인 호환성 요구 사항을 제외하고 세부 사항을 지정할 의도가 없습니다.

두 번째 최상위 키 next에는 다른 색인으로 연결되는 선택적 URL이 포함됩니다. PyManager가 포함된 버전에서 적합한 패키지를 찾지 못하는 경우에 이를 사용할 수 있습니다. 이는 이전 색인을 보관하고 필요할 때만 액세스하여, 이전 버전의 사용자와의 연결을 끊지 않으면서 초기 다운로드 크기를 줄이기 위한 것입니다. 적합한 설치를 검색할 때 실행 가능한 후보를 찾으면 이후 색인은 검색하지 않습니다(즉, 처음 조회하는 색인에 최신 버전이 포함되어 있어야 합니다).

초기 스키마는 다음과 같습니다.

SCHEMA = {
    "versions": [
        {
            # Should be 1.
            "schema": int,

            # Unique ID used for install detection/side-by-side.
            # Must be valid as a filename.
            "id": str,

            # Name to display in the UI
            "display-name": str,

            # Version used to sort packages. Also determines prerelease status.
            # Should follow Python's format, but is only compared among releases
            # with the same Company.
            "sort-version": Version,

            # Specifies platforms to consider this package for.
            # Initially, 'win32' is the only supported value. Others may be
            # defined in the future. This condition is evaluated silently, and
            # is not intended to replace platform requests in "install-for".
            "platform": [str],

            # Company field, used for filtering and displayed as the publisher.
            "company": str,

            # Default tag, mainly for UI purposes.
            # It should also be specified in 'install-for' and 'run-for'.
            "tag": str,

            # List of tags to install this package for. This does not have to be
            # unique across all installs; the first match will be selected.
            # For example, the 3.10.5 package may list '3', '3.10' and
            # '3.10.5' so that any of those may be specified to install it.
            # Matches are number aware, so that 3.1 is not a prefix of 3.10.
            "install-for": [str],

            # List of tags to run this package for. Does not have to be unique
            # across all installs; the first match will be selected. The target
            # is the executable path relative to the root of the archive.
            # Explicit args (optional) are inserted before user args.
            "run-for": [{"tag": str, "target": str, "args": [str], "windowed": int}, ...],

            # List of global CLI aliases to create for this package. Does not
            # have to be unique across all installs; the first match will be
            # created.
            "alias": [{"name": str, "target": str, "windowed": int}, ...],

            # List of shortcuts to create for this package. Additional keys on
            # each instance are allowed based on the value of 'kind'.
            # Initially, 'kind' supports the following values:
            # * 'pep514' - other keys define registry values to set
            # * 'start' - generate shortcuts in the user's Start Menu
            # * 'uninstall' - generate an Add/Remove Programs entry
            "shortcuts": [{"kind": str, ...}, ...]

            # Default executable path, relative to the root of the archive.
            # Usually the values from 'run-for' will be used instead, and this
            # is mainly for display purposes.
            "executable": str,
            # Default executable args
            "executable_args": [str],

            # URL to download the package archive from
            "url": str,

            # Optional set of hashes to validate the download. Hashes are stored
            # as hex digests. Any hash supported by hashlib without OpenSSL is
            # permitted.
            "hash": {
                "<hash_name>": str,
            }
        }
    ],

    # URL (or relative path) to the next index file
    "next": str,
}

셸뱅 처리

sh와 유사한 셸용으로 설계된 스크립트와의 제한적인 호환성을 위해 PyManager는 스크립트에서 셸뱅 줄을 확인합니다. Python 명령을 지정하는 셸뱅 줄은 명령줄에서 재정의되지 않은 경우 스크립트에 적합한 런타임을 선택하는 데 사용됩니다.

현재 py.exe 런처에서 지원하는 것과 달리, 이 기능을 설치 항목에 나열된 전역 별칭과 명령이 일치하는 Python 명령만 지원하도록 축소하고, 일치하지 않는 항목은 임의의 실행 파일 경로로 취급할 것을 제안합니다. 실제로 이는 인위적이지 않은 경우에 동일하거나 더 나은 결과를 낼 것으로 예상되지만, 기존 런처의 명시되지 않은 예외적 동작에 의존하는 사용자의 경우 미묘한 변경이 발생할 수 있습니다.

감지할 구체적인 패턴은 구현에 맡기지만, 기존 런처와 대체로 호환되어야 합니다.

근거

python.exe 명령 “변경”

PyManager가 제공하는 전역 python.exe 별칭은 “진짜 Python이 아니므로” 다른 이름을 사용해야 한다고 주장할 수 있습니다. 이것이 엄밀히는 사실이지만, 이를 사용해야 한다고 주장하는 이유는 세 가지입니다.

첫째, 수천 명의 사용자가 깨끗한 컴퓨터의 터미널에 python을 입력한 후 Store 페이지로 안내되어 매일 이를 통해 설치합니다. 이 리디렉션이 구현된 방식 때문에 설치한 앱이 python 명령을 제공하지 않으면 리디렉션이 계속 유지됩니다. 사용자가 항상 Store로 되돌아가는 상황에 갇히지 않도록 하려면 이 명령을 제공해야 합니다. (python3에도 동일하게 적용됩니다.)

둘째, “진짜가 아닌” 별칭의 대안은 “진짜” 별칭이 아닙니다. 아무것도 아닙니다. 사용자의 기본 설정이나 설치를 따르는 별칭으로 전역 정적 별칭을 대체할 수 없으므로, 대안은 아무것도 제공하지 않고 모든 경우에 python이 오류가 되도록 하는 것입니다. 이는 더 나쁜 결과이며, 저희의 견해로는 Python의 평판에 적극적으로 해롭습니다.

셋째, python 별칭의 기반 구현은 기본 Programs/python.c보다 복잡하지만, 이를 사용하는 경험은 동일합니다. 이 별칭은 다른 명시적인 선호가 없을 때(즉, PATH에 다른 항목이 없을 때)에만 실행되고, 구성이나 셸뱅을 통한 간접적인 선호를 존중하며, 사용자의 컴퓨터에서 사용할 수 있는 가장 적합한 Python 버전을 실행합니다. 이는 다른 어떤 대안보다 전역 python 명령에 기대되는 동작에 훨씬 가깝습니다.

Gentoo도 단순한 심볼릭 링크보다 사용자에게 더 나은 서비스를 제공하기 위해 지능적인 python 명령을 배포한다는 점이 알려져 있습니다.

py.exe 대체

py.exe 런처는 PyManager가 복제할 일부 기능, 구체적으로는 이미 설치된 런타임을 실행하는 기능을 제공하기 위해 존재합니다. 오랜 역사를 지녔음에도 이 런처는 대부분의 사용자에게 선호되는 방법이 된 것 같지 않으며, 많은 사용자는 전역적으로 PATH 환경 변수를 수정하는 방식을 선호합니다. 그러나 명령 자체는 의존 대상이 되었으므로 가능한 한 오랫동안 보존해야 합니다. 이는 두 가지 방식으로 달성됩니다.

동일한 기능과 PyManager 고유 기능을 제공하는 자체 py.exe 별칭을 PyManager로 먼저 설치합니다. 이는 시간이 지나면서 py.exe의 기본 및 선호 설치가 되도록 설계되었습니다.

둘째, 요청된 경우 각 설치에 대해 PEP 514 메타데이터를 생성하며, 이를 통해 레거시 py.exe가 PyManager로 관리되는 설치에서 계속 정상적으로 작동할 수 있습니다.

기존 py.exe 런처가 자체적으로 구성되는 방식과 PyManager의 MSIX 패키지에 적용되는 제약으로 인해 PyManager의 py 별칭이 런처를 재정의할 수 없습니다. 그 결과 런처를 설치한 사용자는 항상 py가 런처로 해석되는 것을 확인하게 됩니다. 궁극적으로 PyManager를 우선하도록 이 문제를 해결하는 유일한 방법은 런처를 제거하는 것이며, 이는 표준 설치된 앱 제어판을 통해 수행할 수 있습니다.

기존 런처는 기존 설치 프로그램과 함께 계속 릴리스되도록 유지하되, 새로운 하위 명령의 사용 시도를 감지하고 현재의 오류 대신 사용자에게 유용한 메시지를 제공하도록 업데이트할 것을 제안합니다. 이러한 경고는 사용자가 해당 이름의 확장자 없는 파일을 의도적으로 실행하는 가능성은 낮지만 존재하는 경우도 감지하고 그 동작을 유지할 수 있으므로, 설정을 다른 방식으로 변경할 수 없는 사용자에게 실행 가능한 대안을 제공합니다.

venv와의 상호 작용

표준 라이브러리 venv 모듈로 구현되는 활성화된 가상 환경은 venv 런처가 다른 실행 파일보다 우선하도록 사용자의 PATH 환경 변수를 수정합니다. 그 결과 venv가 활성화되면 PyManager는 python 이외의 별칭으로만 실행할 수 있습니다. 활성 가상 환경이 감지되면 해당 환경은 사용자의 기본 런타임으로 취급되며(제거의 경우 제외), 다른 명령도 예상대로 작동하도록 합니다.

이는 정상적으로 작동하는 가상 환경이 PyManager의 추가 지원 없이도 현재와 동일하게 동작한다는 의미입니다.

하위 호환성

일반적으로 마이너 버전(3.x에서 3.y로) 간 설치 프로세스에 대한 호환성 보장은 없으므로, “다른 설치 프로그램을 사용해야 하는 것”은 호환성 중단으로 간주되지 않습니다. 설치된 Python 버전은 설치 방법이 해당 버전의 동작을 변경한 범위에서만 이 변경의 영향을 받습니다. 일반적으로 대부분의 설치는 사용자가 직접 소스에서 빌드했을 때의 동작에 더 가까워질 것입니다.

다만 새로운 설치 프로세스로 전환할 때 일부 사용자에게 영향을 미치는 변경 사항이 여러 가지 있습니다. 이 절에서는 알려진 변경 사항을 특별한 순서 없이 최대한 많이 설명하며, 향후 마이그레이션 가이드의 기반이 될 가능성이 높습니다.

스크립트를 사용한 다운로드

기존 설치 프로그램의 다운로드 파일 이름을 생성하는 스크립트를 작성한 사용자는 해당 스크립트가 작동하지 않는 것을 확인하게 됩니다. 이러한 URL은 안정적이거나 예측 가능하다고 보장된 적이 없으므로, 사과하고 사용자가 다운로드에 자체 도구를 사용하도록 제안하는 것 외에는 다른 조치를 취할 수 없습니다.

기존 설치 프로그램의 사용 중단 기간은 이러한 사용자가 예정된 변경 사항을 학습할 시간을 제공합니다. 가능한 경우 기존 설치 프로그램에 사용 중단 경고를 추가할 것입니다.

스크립트를 사용한 설치

특정 옵션을 사용하여 설치 프로그램을 실행하는 스크립트를 작성한 사용자는 해당 스크립트를 변경해야 합니다. 우선 대부분의 옵션이 제거되었으며, 남아 있는 옵션은 표기가 새로워졌습니다. 수동 개입 없이 이전 설치 프로그램의 옵션이 새 설치 프로그램으로 전달되는 상태에 도달할 수 없으므로(즉, 누군가 이미 명령을 변경해야 하므로), 이는 허용 가능한 변경으로 간주됩니다.

기존 설치 프로그램의 사용 중단 기간은 이러한 사용자가 예정된 변경 사항을 학습할 시간을 제공합니다. 가능한 경우 기존 설치 프로그램에 사용 중단 경고를 추가할 것입니다.

이전 런타임 설치됨

기존 런타임이 설치되어 있는 사용자는 등록이 손상되지 않은 경우 PyManager와 그 별칭이 해당 런타임을 선택하는 것을 확인하게 됩니다.

설치된 런타임 간 우선순위 순서가 특별히 요청된 경우에만 릴리스 전 버전을 포함하도록 변경되었습니다(예를 들어, -V:3은 3.15.0a1이 아니라 3.14.0과 일치하지만, -V:3.15는 3.15.0a1과 일치합니다). 또한 태그의 텍스트 접미사를 올바르게 정렬하도록 변경되었습니다(예를 들어, 3.14t는 이제 3.14보다 낮은 우선순위를 가집니다).

이러한 변경이 사용자에게 영향을 미칠 수 있는 경우 경고를 제공할 수는 있지만, 그러한 경고는 지나치게 빈번한 것으로 간주될 수 있으며(예: 선택되지 않은 릴리스 전 버전이 설치되어 있다는 이유로 python을 실행할 때마다 메시지가 표시됨), 선택 로직을 불필요하게 복잡하게 만들어야 합니다. 이 변경 사항은 문서화만 합니다.

이전 py.exe 실행기가 설치된 경우

이전 py.exe 실행기를 수동으로 제거하지 않은 사용자는 기존 Python 설치와 새 Python 설치가 모두 검색되지만, 버전이 일치하는 경우에는 새 설치보다 기존 설치가 우선순위를 갖는 것을 확인하게 됩니다(반면 새 py는 새 설치를 선택합니다).

또한 py list와 같은 명령이 작동하지 않는 것을 확인하게 됩니다. 이 경우의 해결 방법은 Windows 설정을 사용하여 실행기를 제거하는 것입니다.

사용자가 실수로 이전 py를 설치된 상태로 두었는지 감지하거나 이를 대신 제거할 방법은 없습니다. 이 변경 사항은 문서화만 합니다.

잘못 구성된 venv가 활성화된 경우

손상되었거나 잘못 구성된 가상 환경을 활성화한 사용자는 해당 환경에 python.exe가 없거나 PATH에 포함되어 있지 않은 경우 이전과 다른 오류를 받을 수 있습니다.

대신 PyManager의 전역 python별칭이 검색되어 실행되므로 시스템의 “찾을 수 없음” 오류가 표시되지 않습니다. 환경의 실제 런타임을 찾지 못하므로 이후 실패하지만, 코드와 메시지는 다를 수 있습니다.

이 시나리오에는 이미 손상된 시스템이 필요하므로 이 변경 사항은 문서화만 합니다.

이전 버전의 사용 가능성

PyManager의 첫 번째 릴리스 이전 Python 버전은 새로 다시 패키징한 아카이브를 기반으로 하거나 NuGet의 거의 동등한 패키지를 사용하여 python.org 색인에 보충할 수 있습니다(후자의 경우 Tcl/Tk가 포함되지 않아 일부 사용자에게는 호환성이 크게 떨어지지만, 특히 오래된 버전에서는 문제가 없을 가능성이 높습니다).

이 PEP가 승인되는 시점부터 Python 3.10.0 이후의 모든 버전(패치 릴리스 포함, 릴리스 전 버전 제외)에 대한 패키지를 생성하여 모든 비-EOL 릴리스를 PyManager를 사용해 완전히 설치할 수 있도록 하는 것이 계획입니다. Python 3.5.0 이후의 버전(릴리스 전 버전 제외)은 NuGet의 패키지를 직접 참조하므로 축소된 형태로 쉽게 사용할 수 있습니다. 어느 접근 방식도 기존 릴리스를 다시 빌드할 필요가 없으며, 해당 릴리스의 소스를 변경할 필요도 없습니다.

관리자 설치

PyManager는 사용자의 자체 디렉터리에만 설치되므로 모든 사용자를 위한 Python 사본을 설치하는 것은 더 이상 불가능합니다. 컴퓨터별 설치가 업스트림 배포에 대한 우리의 의도에 부합한다는 것을 보여 주는 시나리오가 제시되지 않았으므로, 이러한 설치 옵션은 제공하지 않습니다. 이 기능을 원하는 제3자는 자체 배포판을 제공하는 것이 좋습니다.

PyManager는 모든 사용자를 대상으로만 설치할 수 있지만, MSIX를 설치하는 데 관리자 권한이 필요하지 않으며 관리자가 사용자가 설치할 수 있는 실제 런타임을 제한하는 것을 포함하여 광범위하게 구성할 수 있습니다. 또한 PyManager는 번들링을 위한 로컬 추출을 지원하므로, 임베딩 앱은 자체 레이아웃을 쉽게 생성할 수 있으며, 원하는 경우 이를 모든 사용자를 위해 설치할 수 있습니다.

이 시나리오에는 변경 사항의 유무와 관계없이 관리자의 개입이 필요하므로 이 변경 사항은 문서화만 합니다.

빌드 시 설치

임베더블 배포판을 사용하는 사용자는 패키지 URL을 검색하는 새로운 방법으로 변경해야 할 수 있지만, PyManager를 사용하여 검색하고 설치하는 것이 권장됩니다. 설치 프로그램 변경으로 인한 차이는 예상되지 않으며, 임베더블 배포판 패키지는 현재와 동일합니다.

NuGet 패키지에 대한 변경 사항은 제안되지 않습니다.

단일 아키텍처 설치 프로그램

현재 제안에서는 Intel 64비트 빌드의 PyManager만 사용할 수 있습니다. 따라서 32비트 운영 체제나 CPU만 사용하는 사용자는 PyManager를 설치할 수 없습니다. 오늘날 이러한 시스템은 극히 적고, PyManager의 대상 사용자인 개발자 시스템에서는 그보다도 더 적은 비율을 차지하므로, 사용자가 제외되는 문제는 우려하지 않습니다.

Windows ARM64 시스템은 효율적인 에뮬레이션을 통해 Intel 64비트용으로 빌드된 바이너리를 실행할 수 있습니다. 32비트 실행 파일과 통합하는 데 중요한 역할을 하며 64비트 바이너리로 대체할 수 없는 CPython 32비트 빌드는 계속 제공됩니다. PyManager는 독립 실행 파일로 실행되므로 관리자에게 이 기능은 필요하지 않습니다.

테스트 스위트 및 디버그 심볼

기존 설치 관리자는 Python 표준 라이브러리 테스트 스위트와 디버그 심볼을 선택적으로 설치할 수 있도록 합니다. 대부분의 사용자에게 이 둘은 필요하지 않지만, 일부 사용자에게는 편리합니다. 예비 테스트에 따르면 테스트 스위트와 디버그 심볼을 제외하면 압축 패키지의 크기가 약 60% 줄어듭니다(46MB에서 18MB로 줄어듭니다).

따라서 PyManager가 설치하는 “기본” CPython 패키지에는 테스트 스위트나 디버그 심볼이 포함되지 않습니다. 그러나 이러한 추가 항목을 포함하는 두 번째 패키지 세트도 있으며, 기본 PythonCore와 구분하여 PythonTest아래에 그룹화됩니다. 예를 들어 py install 3.13은 기본 런타임을 설치하지만, py install PythonTest\\3.13은 추가 파일이 포함된 두 번째 런타임을 설치합니다(이 런타임은 py -V:PythonTest\\3.13으로 실행하거나, 해당하는 PythonCore 버전이 설치되어 있지 않다면 간단히 py -V:3.13으로 실행할 수 있습니다).

디버그 바이너리는 더 이상 배포되지 않으며, 그 밖의 모든 선택적 기능은 기본적으로 포함됩니다.

전역 pip 명령

현재 Windows Store 설치와 달리 전역 pip 명령은 포함되지 않습니다(기존 설치 관리자도 PATH 수정 및 pip 설치 옵션을 선택하지 않는 한 전역 pip 명령을 포함하지 않으며, 이 중 첫 번째 옵션은 기본적으로 꺼져 있습니다). 이는 이미 권장되지 않는 패키지의 전역 설치에 영향을 주지만, 활성화된 가상 환경에는 영향을 주지 않습니다.

기존 권장 사항은 그대로 유지되며, pip를 실행하려면 python -m pip 또는 py -V:<TAG> -m pip를 실행합니다.

보안 관련 영향

이 절에서는 설치 관리자 자체의 보안 관련 영향을 기존 설치 관리자와 비교합니다. 시스템에 Python이 설치되어 발생하는 영향은 이 범위에 포함되지 않으며, 악의적인 사용자가 설치 관리자를 실행할 수 있는지도 이 범위에 포함되지 않습니다.

설치 관리자가 일반적으로 초래하는 위험은 권한 상승 설치로 인해 시스템이 변경되어 낮은 권한의 사용자가 나중에 높은 권한의 사용자에게 영향을 줄 수 있게 되는 것입니다. 예를 들어 공유 폴더에 대한 액세스 제어가 부적절하게 설정되는 경우가 이에 해당합니다. PyManager는 사용자와 동일한 권한 수준에서만 작동하므로 권한 상승 경로를 만들 수 없습니다.

앞서 설명한 MSI를 사용하는 설치는 더 오래된 설치 관리자 기술을 사용하므로 추가적인 위험을 초래할 수 있습니다. 일반 사용자는 안전한 MSIX 또는 Windows Store 설치 경로를 사용하도록 안내되며, MSI 사용자는 설치 프로세스의 보안을 보장할 수 있다고 가정합니다(예를 들어 설치 관리자를 실행하는 명령을 올바르게 인용하고 초기 시스템 구성이 적절한지 확인합니다).

PyManager가 시스템에 설치되면 악의적인 사용자가 이를 사용하여 Python을 설치할 가능성이 있습니다. 앞서 “Configuration”에서 설명한 관리자 전용 구성은 이러한 시나리오를 제어하기 위한 것입니다. 그러나 궁극적으로 PyManager를 실행할 수 있는 공격자는 사용자가 할 수 있는 모든 작업을 수행할 수 있으며, 완전한 애플리케이션 허용 목록 방식만이 Python 사용을 방지할 수 있습니다.

HTTPS를 통한 패키지 획득은 연결 보안으로 보호됩니다. 공개 인증서와 엔터프라이즈 인증서 및 인증된 프록시 서버를 지원하는 Windows 네이티브 다운로드 메커니즘을 사용합니다. 피드에는 다운로드 가능한 패키지의 해시가 포함될 수 있으며, 이러한 해시는 검증되지만, PyManager에는 타사 호스팅 검증 기능이 내장되어 있지 않습니다. 이는 오늘날의 모델과 일치합니다.

PyManager로 설치한 런타임은 현재 사용자가 완전히 액세스하고 수정할 수 있습니다. 이는 기존 설치 관리자나 NuGet 패키지를 사용한 일반적인 설치와 동등하지만, Store 설치나 기존 설치 관리자를 사용한 컴퓨터별 설치보다 변조에 더 취약합니다. 설치한 사용자로부터 설치를 완전히 보호하는 것은 불가능합니다. 설치를 다시 설치하거나 업데이트하면 새로 설치되며, 원래 설치 이후 발생했을 수 있는 모든 변조가 되돌려집니다.

런타임을 설치할 때 PyManager가 생성하는 별칭은 인접한 데이터 파일을 사용하여 올바른 대상을 실행하는 서명된 수정되지 않은 실행 파일을 사용하도록 설계되었습니다. 이를 악용하여 런처가 다른 대상을 실행하도록 지시하는 것은 쉽지만, 이를 해결하는 유일한 방법은 실행 파일 자체에 대한 신뢰를 희생하는 것이며, 그러면 데이터를 교체하는 대신 실행 파일을 쉽게 교체할 수 있게 됩니다. 이러한 위험은 이미 존재하며, 사용자가 실행할 수 있는 스크립트나 표준 라이브러리의 어떤 부분이든 교체하는 것과 같습니다. 중요한 점은 별칭이 사용자 간에 공유되지 않으므로 이 경로를 통한 권한 상승이 없다는 것입니다.

PyManager에는 컴퓨터별 설치를 수행하는 메커니즘이 없습니다. 이는 일부 사용자에게 유용한 기능일 수 있습니다. 일반 사용자가 설치를 전혀 수정할 수 없게 되기 때문입니다(가상 환경과 사용자 사이트 폴더는 제외합니다). 이러한 기능은 관리자가 PyManager와 기타 OS 명령을 사용하여 수동으로 모방할 수 있지만, 중요한 작업 흐름으로 간주되지는 않습니다. 권장되는 대안은 관리자가 PyManager를 제공하고 해당 구성을 재정의하는 것입니다.

기존 PEP에 미치는 영향

이 제안은 동일한 이름의 새로운 도구의 일부로 동일한 기능을 정의함으로써 PEP 397 (“Python launcher for Windows”) 및 PEP 486 (“Make the Python Launcher aware of virtual environments”)를 사실상 대체합니다. 둘 다 이미 최종본으로 간주되며, 런처는 해당 문서와 일반적인 호환성 절차로 정의됩니다. 새로운 기능은 원래 PEP 텍스트가 아니라 현재 구현을 기반으로 합니다.

이 제안은 PEP 394(“The “python” Command on Unix-Like Systems”)에 영향을 미치지 않으며, 모든 플랫폼의 사용자에게 유사한 지침을 제공할 수 있는 Windows 접근 방식을 고안한다는 점에서 이 PEP와 일관된 것으로 여겨집니다.

이 제안은 PEP 514(“Python registration in the Windows registry”)에 영향을 미치지 않으며, 오히려 자체 런타임을 등록하기 위한 더 유연한 시스템을 통해 이를 준수할 수 있는 능력을 향상합니다. PEP 514를 따르는 도구는 설치 방식과 관계없이 등록을 사용하기로 선택한 모든 런타임을 찾습니다.

이를 가르치는 방법

기본 사용법

이 제안의 핵심 목표는 “터미널에 ‘python’을 입력하십시오”가 가장 기본적인 경우에 충분한 지침이 되도록 하는 것입니다. Microsoft가 추가한 리디렉터 덕분에 이 지침을 따르면 적어도 유용한 일이 일어나며, PyManager를 사용하면 “유용한 일”이 사용자가 최신 버전을 실행하는 것을 의미하도록 보장할 수 있습니다.

실제로 무엇이 일어나는지 설명하기 위해 다음을 소개 문구로 제안합니다.

Python installs on Windows are managed using an installer tool. After it has
been installed, you can run ``python`` to launch the interpreter, and it will
choose the best version already installed, available online, or referenced by
the script you are launching (if any). If you have a preference for a
particular version, you can specify it with ``py -V:<version>`` followed
by the rest of your command.

To install a version of Python without running any command, use ``py install
<version>``. You can see all of your installs with ``py list`` and remove them
with ``py uninstall <version>``. Run ``py help`` to see all the options that
are available.

Because each version of Python will be shared by all your projects, we
recommend using virtual environments. This will usually be created for a
particular Python version by running ``py -V:<version> -m venv .venv``, and
activated with ``.venv\Scripts\Activate``. Now, rather than the install
manager, ``python`` or ``py`` will always launch your virtual environment, and
any packages you install are only available while this environment is active.
To get access to the manager again, you can ``deactivate`` the environment, or
use ``py <command>``.

많은 Python 프로젝트는 자체 README 파일의 일부로 프로젝트를 실행하는 방법에 대한 정보를 포함합니다. 역사적으로 이러한 정보는 사용자가 이용할 수 있는 옵션의 범위 때문에 복잡했습니다. 설치 관리자가 공개된 후에는 이러한 지침을 다음과 같은 방향으로 작성할 수 있다고 제안합니다.

To install and use our application, first install Python following the
guidance for your operating system at https://docs.python.org/using/. Then,
create a virtual environment and use 'pip' to install.

``python3 -m venv .venv``
``source .venv/bin/activate`` or ``.venv\Scripts\Activate`` (on Windows)
``python -m pip install OurAwesomePackage``
...

지침에 가상 환경에 대한 정보가 포함되지 않는다면 python 또는 python3 명령을 표시할 수 있으며, Windows에서는 설치 관리자를 사용하는 사용자에게 두 명령 모두 의도한 대로 작동합니다.

현재 Windows에서 py를 언급하는 지침은 계속 그렇게 사용할 수 있습니다. 설치 관리자가 사실상 동등한 명령을 제공하기 때문입니다. 올바른 버전을 설치하기 위해 -V: 또는 --install 옵션을 사용하는 등의 Windows 전용 지침을 제공하려는 프로젝트는 설치 관리자가 설치되었는지 확인하기 위한 지침으로 문서에도 링크해야 합니다.

제거

완전한 제거는 사용자가 설치 관리자를 제거하려고 고려하기 전에 다루어야 할 중요한 주제입니다. 관리자를 제거할 때 설치된 항목의 모든 부분을 자동으로 정리할 수 있는 것은 아니므로, 대부분을 제거하지 않기로 했습니다. 따라서 기본 pythonpy 명령은 사라지지만, 설치된 모든 런타임은 여전히 존재하며 사용할 수 있습니다.

다음과 같이 설명할 것을 제안합니다.

Before you uninstall the Python install manager, you'll want to uninstall any
runtimes that you added. This can be done easily with the "purge" option:

``py uninstall --purge``

This will remove all installs and any shortcuts that would otherwise be left
behind. If you already removed the manager, you can reinstall it and run the
above uninstall command again to clean up. Individual runtimes can be
uninstalled by specifying the tag instead of ``--purge``. Tags can be found
by looking at ``python list``.

구성

구성 파일은 문서화될 일반적인 기능이지만, 일반 사용자에게 가르칠 필요는 없습니다. 마찬가지로 시스템 관리자나 사용자가 선호하는 색인을 사용하도록 하려는 조직에서 사용할 수 있는 고급 배포 옵션은 참고 자료에서 다루는 것이 가장 적절합니다.

사용자 지정 색인

사용자가 특수 런타임이나 배포판을 설치하도록 안내할 때에만 색인을 소개하면 된다고 제안합니다. 색인을 제공하려는 관리자는 문서에서 관련 정보를 적극적으로 찾아볼 것으로 예상됩니다.

대체 색인을 언제 어떻게 사용하는지 설명하기 위해 다음과 같은 내용의 문구를 제안합니다.

Our distribution can be installed on Windows using the Python Install Manager
(include link) by referencing our index:

``py install --source <your index URL here> latest``

This index contains all our versions. Use ``py list --source <URL>`` to
see everything that is available.

참조 구현

참조 구현은 the author’s repository 에서 사전 컴파일된 MSIX 패키지인 Releases 아래에 제공됩니다. 이 샘플에는 호스팅된 색인 대신 번들된 색인이 포함되어 있으며, 설치 테스트를 수행할 수 있도록 기존 NuGet 패키지들을 다양하게 참조합니다.

참조 문서는 the same repository 에서도 확인할 수 있습니다.

채택하지 않은 아이디어

모든 플랫폼에서 PyManager 사용 가능하게 만들기

이 아이디어에 본질적으로 반대하는 것은 아니지만, 실현되려면 더 많은 구성 요소가 서로 맞물려야 합니다.

첫째, 현재 참조 구현에는 Windows에 특화된 지식이 많이 포함되어 있습니다. 다른 플랫폼에 상응하는 지식을 수집하고 구현해야 하며, Windows가 아닌 플랫폼에 특화된 추가 동작도 구현해야 합니다.

둘째, 시스템에 추출할 수 있는 사전 빌드된 재배치 가능 바이너리의 출처가 필요합니다. 그러한 출처가 존재하기는 하지만, 공급망에서 우리의 위치를 고려하면 이를 정당하게 사용할 수 없습니다(그들이 우리를 사용해야 합니다). Windows의 경우 자체 바이너리가 이미 이러한 기준을 충족하므로 수정 없이 다시 패키징할 수 있습니다.

셋째, 현재 구현은 번들된 Python 런타임에 의존하며, 명백한 이유로 이 런타임은 사용자의 간섭으로부터 격리되어야 합니다. 이를 위해서는 위에서 언급한 재배치 가능 바이너리도 필요하지만, 현재 이러한 바이너리는 Windows용으로만 보유하고 있습니다.

다른 플랫폼에서 이를 작동하게 만드는 데 필요한 추가 단계와 해당 플랫폼에 기존 설치 관리자를 교체할 필요가 없다는 사실을 고려하여, 이 아이디어는 이 PEP의 범위를 벗어난다고 판단합니다. 향후 추진될 수도 있습니다(이를 추진할 가능성이 가장 높은 기여자들은 검토 중이며 일관된 인터페이스를 사용할 수 있을 것이라고 밝혔습니다).

관리자와 함께 런타임 사전 설치하기

제안 내용은 PyManager에 완전한 Python 런타임을 포함하여, 해당 python.exe 별칭이 동적으로 사용 가능한 최적의 버전으로 확인되는 대신 직접 이 런타임을 가리키도록 하는 것입니다.

안정성과 업데이트를 위해 런타임 릴리스가 관리자와 완전히 독립적인 것이 매우 중요합니다. 기존 런타임 설치에 영향을 주지 않고 관리자를 업데이트할 수 있어야 하며, 마찬가지로 최신 런타임을 얻기 위해 관리자를 업데이트할 필요도 없어야 합니다.

가정적으로, Python 3.14.0을 설치할 필요가 없도록 관리자와 함께 포함한다면, 나중에 이를 3.15.0으로 교체하는 것은 호환성을 깨뜨리는 변경이 됩니다. 관리자에는 단일 설치본만 있으므로, 이렇게 하면 최신 설치본이 가장 오래된 런타임을 사용하게 됩니다.

이는 PyManager의 python별칭이 버전이 지정되지 않은 상태라는 점도 무시합니다. 사용자가 이 별칭을 실행하는 것은 어떤 버전을 받는지 하나를 지정할 만큼 신경 쓰지 않았기 때문입니다. 그러한 상황에서는 사용 가능한 최적의 버전을 선택하고, 적절한 방식으로 이를 고정할 수 있는 선택지(셰뱅 또는 활성 환경을 통한 방식)를 제공해야 합니다.

관리자 대신 런타임 포함

이것이 현재 상황이며, 우리는 이를 변경하려고 합니다. 여기까지 읽고도 여전히 이 주장을 하기로 했다면, 돌아가서 처음부터 다시 시작하십시오.

하위 명령 대신 내장 모듈 사용

py list 또는 py install과 같은 명령을 사용하는 대신 제안된 두 가지 대안은 py -m listpy -m install처럼 호출하는 전용 모듈을 사용하거나, py -m manage list처럼 호출하는 단일 전용 모듈을 사용하는 것입니다. 이 아이디어는 해당 의미 체계로 안정적으로 구현할 수 없는 시나리오에 기존 의미 체계를 재사용하려 하므로, 설명하고 이해하며 유지 관리하기 더 어려운 특수 처리가 필요하다는 이유로 거부됩니다.

이 아이디어를 거부하는 주된 이유는 그 자체로는 바람직한 두 의미 체계의 상호작용 때문입니다. 첫째, 기본 py명령은 직접 실행된 것처럼 사용 가능한 최신 런타임을 시작해야 합니다. 둘째, 특정 상황에서 -m의 동작을 특수 사례로 취급해서는 안 됩니다. 첫 번째 부분을 포기한다면 사용자가 기대하는 대로 동작하도록 명령을 자유롭게 수정할 것입니다. 호환성을 완전히 깨뜨리는 데 동의했다면 누구도 호환성 문제를 제기하지 않았을 것입니다. 그러나 두 번째 제약을 포기한다면 사용자는 그에 따른 혼란을 감수해야 합니다. (어느 쪽도 포기하자고 제안하는 것은 아닙니다. 결국 이는 거부된 아이디어이지만, 가능한 선택지가 무엇인지 보여 주는 데 도움이 됩니다.)

첫째, 하위 명령 중 하나는 첫 번째 런타임을 설치하기 위한 것이므로 python -m [manage] install을 기본 런타임을 통해 실행되는 것처럼 취급할 수 없습니다. 기본 런타임이 없기 때문입니다! 명령을 읽고 다른 프로그램을 통해 실행하려면 본질적으로 특수 처리가 필요합니다.

또한 Python에서는 -m앞이나 사이에 다른 옵션을 둘 수 있으므로, 이 특수 처리에서 이를 지원해야 합니다.

마지막으로 -m옵션의 의미 체계에는 초기 sys.path에서 일치하는 모듈 이름을 검색하는 동작이 포함됩니다. 이는 단순한 이름보다 훨씬 광범위한 검색입니다. py -m install은 파일 시스템, 환경, 레지스트리를 검사하여 찾은 여러 디렉터리와 그 안에서 전이적으로 포함된 경로를 검색한 후 install.py, install.pyc, install.pyd, install\\__init__.py 등도 기꺼이 실행합니다. 현재 작업 디렉터리에서 정확히 install이라는 파일만 오직 찾는 py install과 비교하면, -m의 동작은 실제 시나리오에서 이미 의존하고 있을 가능성이 훨씬 높습니다. (예를 들어 Django 프로젝트에는 일반적으로 manage.py 스크립트가 있으므로 py -m manage는 항상 잘못 동작합니다.)

py -m install-m처럼 동작하지 않고 대신 내부 명령을 실행하도록 변경하는 것은 py install을 변경하는 것보다 사용자를 중단시킬 가능성이 훨씬 큽니다. 따라서 이 아이디어는 거부됩니다.

하위 명령 대신 새로운 명령줄 옵션 사용

하위 명령에 대한 합리적인 대안은 하위 명령이 아니라 옵션처럼 앞에 구두점을 붙여 이름을 지정하는 것입니다. 예를 들어 py install 대신 py /install ...처럼 사용하거나 py --list처럼 사용할 수 있습니다. 이러한 항목 중 일부는 현재 일반 CPython 인터프리터에서 오류이므로, 하위 호환성 문제 없이 추가할 수 있습니다.

그러나 특히 Windows에서 일반적으로 사용하는 앞쪽 슬래시 형식은 CPython에서 오류가 아닙니다. 따라서 Windows 사용자는 기존 지식을 직접 적용할 수 없으며 옵션을 지정하는 새로운 방법을 배워야 합니다. Windows 전용 도구를 제안하는 상황에서 이는 매우 좋지 않은 출발입니다. 또한 Unix 스타일 명령줄에 익숙한 사용자는 옵션을 명령으로 잘못 사용하는 것으로 인식할 것입니다.

우리는 깔끔한 인터페이스를 만들고자 하며, 명백한 결함이나 학습상의 어려움을 포함한 설계로 시작하는 것은 그 목표에 어긋납니다. 현대적인 도구는 이러한 목적에 하위 명령을 보편적으로 사용하므로, 다른 방식을 사용하자는 아이디어는 거부됩니다.

대신 현재의 기존 설치 프로그램 개선

새 설치 메커니즘을 만드는 대신, 현재 설치 프로그램을 유지 관리하는 데 투자할 수 있습니다. 그러나 현 단계에서 현재 설치 프로그램은 전적으로 폐기된 기술에 기반하고 있습니다. Windows는 더 이상 Windows Installer 서비스를 개발하지 않으며, Wix는 우리가 사용하는 도구 모음 버전을 더 이상 개선하지 않습니다. 더 최신 버전의 Wix Toolset으로 마이그레이션하는 데는 상당한 작업이 필요하며, 결국 여전히 기존 기술에 종속됩니다.

앞서 언급했듯이, Windows Installer가 제공하는 가장 유용한 기능은 CPython에서 사용되지 않으며, 일반적으로 해결한 문제보다 더 많은 문제를 일으켰습니다(예를 들어, 파일 버전 정보가 자동으로 수집되어 발생하는 의도치 않은 다운그레이드가 있습니다).

설치 프로그램 로직의 주요 원천인 Burn 번들의 구현은 C++로 작성되었으며, 핵심 개발자 중 소수만 익숙한 프레임워크에 통합되어 있습니다. 이로 인해 유지 관리가 어려워지며, 장기적으로 취할 만한 좋은 방향도 아닙니다. 등록이 필요 없는 설치와 같은 원하는 기능을 Burn 번들로 마이그레이션하는 것은 불가능합니다(처음부터 끝까지 재구현한 뒤 사후적으로 통합하지 않는 한).

현재의 기존 설치 프로그램을 유지 관리하는 데 새 설치 프로그램을 구현하는 것만큼의 노력이 적어도 필요하며, 핵심 팀이나 사용자에게 의미 있는 이점을 제공하지 못할 것이라는 것이 우리의 견해입니다. 따라서 이 아이디어는 거부합니다.

스토어 패키지를 완전히 삭제하십시오

스토어 패키지를 제거하면 사용자가 Python 런타임을 선택할 때 직면하는 선택지의 수가 줄어듭니다. 안정성과 보안을 제외한 모든 측면에서 기존 설치 프로그램은 대체 수단으로 완전히 충분합니다. 생태계의 일부를 더 안전한 설정으로 마이그레이션하는 작업(예: DLL 하이재킹에 의존하지 않도록 하는 작업)은 대부분 완료되었지만, 여전히 덜 안전한 구성에서만 작동하는 일부 패키지가 남아 있으며, 모든 사용자를 이러한 구성으로 되돌리면 해당 패키지 사용자들이 현재 겪는 문제를 겪지 않게 할 수 있습니다.

그러나 스토어 패키지 사용자의 대다수는 불만이 없는 것으로 보입니다. 일화적으로 볼 때, 이들은 스토어 설치에 대체로 완전히 만족하며, 특히 설치의 간편성과 안정성을 높이 평가합니다. (개인적인 견해를 덧붙이자면, 이 글의 작성자는 Python 3.8부터 차단 문제 없이 스토어 패키지만 사용해 왔습니다.)

가장 많은 문제는 잘못 구성된 PATH 변수와 Microsoft가 설치하는 기본 python.exe 리디렉터리로 인해 발생했습니다. 다시 말해, 이는 전적으로 우리 패키지와 무관합니다(때로는 다른 설치 프로그램에서 해결할 수 없는 문제와 관련이 있기는 합니다). 이 경로를 통한 성공적인 설치 수가 많다는 점을 고려하면, 영향을 받은 사용자를 진단하고 지원하는 부담은 감수할 가치가 있다고 판단하며, 스토어 패키지를 단순히 제거하자는 아이디어는 거부합니다.

다만 PyManager가 스토어에 게시되면 사용자가 관리자를 찾을 수 있도록 스토어의 기존 런타임을 모두 목록에서 제거할 계획입니다. 이는 새 설치에만 영향을 미치며, 특정 버전을 이전에 설치한 사람은 누구나(로그인되어 있었다면 다른 컴퓨터에 설치한 경우에도) 해당 버전을 계속 사용하고 설치할 수 있습니다.

WinGet 또는 이에 상응하는 도구에 의존하십시오

WinGet, Chocolatey 및 기타 유사한 도구는 우리가 요구하는 의미의 설치 프로그램이 아닙니다. 이러한 도구는 자체 메타데이터 저장소를 사용하여 설치 프로그램을 다운로드하고, 검증하고, 실행합니다. 자체 설치 프로그램이 없으면 실행할 것이 없으므로 사용할 수 없습니다.

해당 도구의 메타데이터가 PyManager를 설치한 다음 이를 실행하여 특정 런타임을 설치하는 작업을 지원하지 않을 가능성이 있습니다. 이 경우 자체 바이너리 패키지를 직접 사용하는 방법을 검토해야 할 수 있습니다.

현재 이러한 설치 도구 중 CPython이 공식적으로 지원하는 것은 없으므로, 작동하도록 만들 의무도 없습니다.

모든 버전을 Windows 스토어 패키지로 만드십시오

현재처럼 각 버전을 Windows 스토어에 릴리스하되, 목록에 표시하지 않고 설치 프로그램(잠재적으로 PyManager, WinGet 또는 스토어 패키지를 설치할 수 있는 다른 도구)에 의존하는 것은 가능합니다. 이렇게 하면 사용자를 압도할 위험을 피하면서 패키지 관리에 대한 자체 책임을 크게 단순화할 수 있습니다.

패키지 업데이트가 수동 작업이므로, 스토어 게시 인터페이스에 접근할 수 있는 어느 기여자에게든 상당한 부담을 지우게 됩니다. 또한 앞서 설명한 기술적 제한 사항이 모든 Python 런타임에 적용됩니다. 따라서 이 아이디어는 거부됩니다.

스토어 게시 인터페이스를 피할 수 있더라도 모든 버전을 ZIP 대신 MSIX 패키지로 만들면 사용자에게 여전히 기술적 제한을 부과하게 됩니다. 이 또한 거부됩니다.

일반 ZIP 파일만 게시하십시오.

일반 ZIP 파일을 게시하는 것은 계획의 일부이지만, 눈에 띄게 나열하지는 않습니다(예를 들어 python.org 다운로드 페이지에는 나열하지 않지만 FTP 보기에서는 표시됩니다). 대안으로 이러한 패키지를 게시하고 나열한 다음, 사용자가 이를 다운로드하여 수동으로 압축을 풀고 구성하도록 할 수 있습니다.

우리가 확인한 작업 흐름에 비추어 볼 때, 대부분의 사용자는 Python 설치를 전혀 구성하고 싶어 하지 않는다고 생각합니다. 설치 위치를 선택하고 싶어 하지 않을 뿐만 아니라, 버전을 선택하거나 다운로드 제공자 또는 지침을 직접 검색해야 하는 것도 원하지 않습니다. 그러나 나중에 설치 항목을 찾고, 실행하고, 업데이트하거나 제거하거나, 알려진 모든 설치 항목을 나열할 수 있기를 원합니다.

현재 다운로드 페이지에 나열된 것보다 더 많은 ZIP 파일이 생기게 되므로 파일 목록이 길어질 것이라는 점도 인식할 필요가 있습니다. 이미 사용자는 올바른 다운로드를 선택하는 데 어려움을 겪고 있으며(기본 “Download” 버튼을 건너뛰고 사용 가능한 모든 버전의 목록과 그 뒤에 나오는 파일 목록을 확인하는 사용자들입니다), 이를 더 어렵게 만들고 싶지는 않습니다.

색인 프로토콜과 다운로드 목록은 이를 사용하려는 도구나, URL을 찾기 위해 JSON을 탐색할 의향이 있는 사용자가 이용할 수 있습니다. 설치 명령의 --target옵션은 간단한 다운로드 및 압축 해제 작업도 제공하므로, 사용자는 ZIP 파일과 동일한 경험을 할 수 있습니다. 또한 --download옵션을 사용하면 사용자가 ZIP 파일을 압축된 상태 그대로 받을 수 있습니다.

PyManager를 한 곳에만 게시하십시오.

Windows Store이든 python.org이든 한 위치에만 게시하는 것이 가능합니다.

그러나 사용자는 python.org에서 무언가를 다운로드할 수 있기를 강하게 기대합니다. 어떤 옵션이라도 제거한다면 필연적으로 사용자에게 피해를 주게 됩니다. python.org에서 MSIX를 이용할 수 없다면 사용자는 패키지를 다른 컴퓨터로 옮길 방법이 없으며, 관리자의 초기 설치를 완전히 스크립트로 처리할 수도 없습니다.

많은 사용자가 패키지를 설치할 때 Windows Store 앱에 의존하며, Windows에 내장된 리디렉터는 Store 페이지로만 열 수 있습니다. 따라서 Store 앱을 제거하는 것은 매달 수십만 건의 설치를 거부하는 것과 같습니다.

두 빌드는 사실상 동일합니다. Store에 제공하는 MSIX와 python.org로 보내는 MSIX의 유일한 차이점은 패키지 서명입니다. python.org 패키지는 저희가 직접 서명하고, Store 패키지는 게시 프로세스의 일부로 서명합니다. 그 외에는 두 패키지를 모두 제작하고 게시하는 데 추가 비용이 들지 않습니다.

인라인 스크립트 메타데이터

PEP 723에서는 서드파티 도구가 해석한 후 올바른 환경에서 Python 스크립트를 실행하도록 만든 구조화된 주석인 인라인 스크립트 메타데이터를 도입했습니다. 해당 PEP에서 가져온 예시는 다음과 같습니다.

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "requests<3",
#   "rich",
# ]
# ///

PyManager에는 종속 요소 설치를 위한 통합 지원이 없으며, 이를 추가할 계획도 없습니다. 따라서 이 메타데이터 처리를 완전히 구현할 수 없었고, 부분적으로 처리하는 것이 아무것도 하지 않는 것보다 나쁘다고 판단하여 전혀 구현하지 않기로 했습니다.

사용자가 예를 들어 py -V:>=3.11 my-script.py를 옵션으로 직접 제약 조건을 지정하여 선택 동작을 얻을 수는 있습니다.

메타데이터를 감지하고 선택한 런타임이 해당 요구 사항과 일치하지 않으면 경고할 수도 있지만, 이는 초기 제안의 일부가 아닙니다.