PEP 527 – PyPI에서 사용되지 않(는 거나 적)는 파일 형식/확장자 제거하기
- Author:
- Donald Stufft <donald at stufft.io>
- BDFL-Delegate:
- Alyssa Coghlan <ncoghlan at gmail.com>
- Discussions-To:
- Distutils-SIG list
- Status:
- Final
- Type:
- Standards Track
- Topic:
- Packaging
- Created:
- 23-Aug-2016
- Post-History:
- 23-Aug-2016
- Resolution:
- Distutils-SIG message
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
개요
이 PEP는 PyPI에 특정한 미사용 또는 저사용 파일 형식과 확장자를 업로드하는 것에 대한 지원을 폐기하고, 궁극적으로는 제거할 것을 권고합니다. 구체적으로는 bdist_dumb, bdist_rpm, bdist_dmg, bdist_msi, bdist_wininst 형식의 파일에 대한 추가 업로드를 금지하고, PyPI가 sdist, bdist_wheel, bdist_egg 파일 형식만 새로 업로드받도록 할 것을 권고합니다.
또한, 이 PEP는 .tar, .tar.bz2, .tar.xz, .tar.Z, .tgz, .tbz, 그리고 .tar.gz와 .zip을 제외한 그 밖의 확장자를 사용하는 sdist의 새 업로드에 대한 지원을 제거할 것을 제안합니다.
마지막으로, 이 PEP는 또한 PyPI에서 프로젝트의 개별 릴리스마다 허용되는 sdist 업로드 개수를, 허용되는 확장자마다 하나씩이 아니라 하나로 제한할 것을 제안합니다.
근거
파일 형식
현재 PyPI는 다음 파일 형식을 지원합니다:
sdistbdist_wheelbdist_eggbdist_wininstbdist_msibdist_dmgbdist_rpmbdist_dumb
그러나 이러한 서로 다른 유형의 파일들은 생태계에서 유용성이나 일반적인 사용도에 있어 차이가 있습니다. 이를 계속 지원하는 것은 PyPI뿐만 아니라 도구 제작자들에게도 유지보수 부담을 가중시키며, PyPI 자체뿐만 아니라 PyPI의 모든 미러에도 대역폭과 디스크 공간 양측에서 비용을 발생시킵니다.
파이썬 패키징은 다단계 생태계로, PyPI는 주로 각 프로젝트 소유자로부터 직접 가상 환경호환 패키지를 배포하는 데 적합하고 그렇게 사용됩니다. 이러한 패키지들은 최종 사용자가 직접 소비하거나, 또는 이 패키지들을 가져다가 각자의 시스템 수준 패키지(RPM, deb, MSI 등)로 변환하는 다운스트림 배포자가 소비하게 됩니다.
PyPI 자체는 이러한 파이썬 특화적이지만 플랫폼에 구애받지 않는 패키지만을 직접 다루는 반면, 저희는 이러한 패키지를 특정 대상 환경을 위한 다운스트림 형식으로 변환하는 커뮤니티 주도 및 상업적 작업을 장려합니다. 예를 들면 다음과 같습니다.
- conda 크로스 플랫폼 데이터 분석 생태계(conda-forge)
- deb 기반 리눅스 생태계(Debian, Ubuntu 등)
- RPM 기반 리눅스 생태계(Fedora, openSuSE, Mageia 등)
- Mac OS X용 homebrew, MacPorts, fink 생태계
- 윈도우 패키지 관리 생태계(NuGet, Chocolatey 등)
- 서드파티가 만든 윈도우 MSI 및 설치 프로그램(예: Christoph Gohlke의 작업, http://www.lfd.uci.edu/~gohlke/pythonlibs/ )
- 기타 상업적 재배포 형식(ActiveState의 PyPM, Enthought Canopy 등)
- 기타 오픈소스 커뮤니티 재배포 형식(Nix, Gentoo, Arch, *BSD 등)
이 PEP는 여러 플랫폼에 자원봉사자들의 한정된 시간을 분산시키는 대신, PyPI를 플랫폼에 구애받지 않는 형식에 집중시키는 것이 전체 생태계를 가장 잘 지원하는 방법이라고 믿습니다. 나아가 이 PEP는 특정 플랫폼에 잘 통합된 패키지를 제공하기에 가장 적합한 사람들은 모든 가능한 플랫폼을 아우르는 사람들이 아니라 해당 플랫폼에 집중하는 사람들이라고 믿습니다.
bdist_dumb
이름에서 알 수 있듯이 bdist_dumb은 그다지 복잡한 형식은 아니지만, 실제 사용에는 쓸모가 없을 정도로 단순합니다.
예를 들어, macOS에서 pyenv 같은 것을 사용하며 Python 3.5로 라이브러리를 빌드하는 경우, bdist_dumb은 exampleproject-1.0.macosx-10.11-x86_64.tar.gz와 같은 이름의 .tar.gz 파일을 생성합니다. 이 파일 이름은 sdist와 동일한 확장자를 사용하기 때문에 처음부터 구분하기가 다소 어렵습니다(그리고 PEP 440 이전의 레거시 버전에서는 1.0-macosx-10.11-x86_64도 상당히 우스꽝스럽긴 하지만 유효한 버전 번호입니다). 하지만 생성된 .tar.gz를 일단 열어 보면, 그 안에 의존성 검색 등에 사용할 수 있는 메타데이터가 전혀 없다는 것을 알 수 있으며, 사실상 이는 bdist_dumb을 생성한 컴퓨터에서 파일들이 설치되었을 경로가 하드코딩된 tarball에 불과합니다. 앞서 든 macOS에서의 pyenv 예시로 돌아가면, 제가 이를 생성했을 경우 다음과 같은 파일들이 포함된다는 의미입니다.
Users/dstufft/.pyenv/versions/3.5.2/lib/python3.5/site-packages/example.py
bdist_rpm
PyPI의 bdist_rpm 형식은 사용자가 .rpm 파일을 업로드하여 최종 사용자가 직접 수동으로 다운로드한 뒤 수동으로 설치할 수 있도록 합니다. 하지만 rpm의 일반적인 사용 방식은, PyPI가 제공하지 않는 의존성 자동 설치, 업그레이드 등을 지원하는 특별히 설계된 저장소와 함께 사용하는 것입니다. 따라서 이 파일 형식은 PyPI에서 거의 사용되지 않으며, 전체 662,544개 파일 중 약 460개만이 이 형식으로 업로드되었습니다.
게다가 COPR과 같은 서비스가 PyPI에서 앞으로도 얻기 어려울 만큼 잘 지원되는, RPM 파일을 게시하고 사용하는 메커니즘을 제공하고 있습니다.
bdist_dmg, bdist_msi, bdist_wininst
bdist_dmg, bdist_msi, bdist_winist 형식은 라이브러리를 환경에 설치하는 용도로만 쓰이는 OS 특화 설치 프로그램이라는 점에서 서로 유사하며, (Python 인터프리터 번들링 등이 필요한) 애플리케이션의 실제 사용자 대상 설치를 위해 설계된 것은 아닙니다.
이 세 가지 중 bdist_dmg와 bdist_msi의 사용률은 매우 낮아서, PyPI에 업로드된 파일은 bdist_msi가 약 500개, bdist_dmg가 약 50개에 불과합니다. bdist_wininst 형식은 사용률이 더 높아서, 지금까지 PyPI에 약 14,000개 파일이 업로드되었습니다.
bdist_dmg와 bdist_msi의 낮은 사용량을 보고 이를 제거해도 영향이 상당히 적을 것이라고 결론짓기는 꽤 쉽지만, bdist_wininst는 사용량이 몇 자릿수나 더 많습니다. 하지만 이는 다소 오해의 소지가 있는데, 그 파일들을 업로드하는 사람은 더 많지만 실제로 업로드된 파일들의 사용량은 상당히 낮기 때문입니다. 지난 30일을 살펴보면, PyPI에서 bdist_winist 파일 다운로드의 90%는 미러링 인프라에 의해 생성되었고 7%는 setuptools(현재 bdist_egg 파일로 더 잘 대체될 수 있음)에 의해 생성되었음을 알 수 있습니다.
이 PEP는 bdist_dmg와 bdist_msi에 대해 업로드된 파일 수가 적고, bdist_wininst가 주로 미러링 인프라를 통해 대역폭과 디스크 공간을 소비하거나 또는 bdist_egg로 손쉽게 대체될 수 있다는 이유만으로 존재한다는 점을 고려하여, 이 세 형식을 금지 목록에 포함할 것을 제안합니다.
파일 확장자
현재 sdist는 .tar.gz, .tar, .tar.bz2, .tar.xz, .zip, .tar.Z, .tgz, .tbz 등 다양한 파일 확장자를 지원합니다. 하지만 이들 중 무시할 수 없는 수준의 사용량을 보이는 확장자는 현재 444,338개의 sdist가 있는 .tar.gz, 현재 58,774개의 sdist가 있는 .zip, 현재 3,265개의 sdist가 있는 .tar.bz2뿐입니다.
여러 형식을 허용하면 (현재 아무도 사용하지 않더라도) 사용될 수도 있는 다양한 확장자를 모두 처리하기 위해 PyPI 내부와 외부 모두에서 도구가 필요합니다. 이는 PyPI에만 영향을 미치는 것이 아니라 생태계 전반에 파급됩니다. 게다가 여러 형식들은 파이썬이 링크된 선택적 C 라이브러리에 대한 요구사항과 지원하는 파이썬 버전에 대한 요구사항이 각기 다릅니다. 게다가 여러 형식은 특정 프로젝트/릴리스에 대해 미묘하게 다른 내용을 가진 두 개의 sdist 파일이 존재할 수 있는 이상한 상황을 만들기도 합니다.
.tar.gz, .zip, .tar.bz2 외의 것은 모두 허용하지 않아야 한다고 주장하기는 쉽습니다. 극소수를 제외하면, PyPI가 존재해온 약 15년 동안 아무도 이러한 다른 유형의 파일을 적극적으로 업로드하지 않았으므로, 이들이 특별히 유용하지 않았다는 것은 분명합니다. 게다가 .tar.xz는 LZMA로 달성되는 더 나은 압축률 덕분에 이론적으로는 다른 .tar.* 형식들보다 더 나은 형식이지만, 파이썬 3.3+에서만 사용할 수 있고 lzma C 라이브러리에 대한 선택적 의존성을 가지고 있습니다.
우리가 실제로 현재 사용 중인 세 가지 확장자를 살펴보면, .tar.bz2역시 금지될 수 있다는 결론을 내리기도 상당히 쉽습니다. 이 확장자로 업로드된 파일 수는 상당히 적으며, bzip2 압축을 처리하기 위해 추가적인 선택적 C 라이브러리가 필요합니다.
마지막으로 .tar.gz와 .zip을 살펴보겠습니다. 이 두 형식의 순수한 수치를 살펴보면, .tar.gz가 총 444,338건 업로드되어 .zip의 58,774건에 비해 단연 가장 많이 업로드된 형식임을 알 수 있으며, POSIX 운영 체제에서는 현재 릴리스된 모든 버전의 Python과 setuptools가 기본으로 생성하는 형식도 .tar.gz입니다. 또한 이 두 파일 형식은 모두 bdist_wheel과 bdist_egg에도 필요한 동일한 C 라이브러리(zlib)를 사용합니다. .tar.gz와 .zip 중 어느 것을 선택할지 결정할 때 두 가지 곤란한 점은, POSIX 운영 체제에서는 .tar.gz가 기본값인 반면 Windows에서는 .zip이 기본값이며 bdist_wheel 형식 역시 zip을 사용한다는 것입니다.
.tar.gz나 .zip 중 하나로 표준화를 시도하는 대신, 본 PEP는 sdist에 대해 .tar.gz와 .zip 둘 중 하나를 허용할 것을 제안합니다.
릴리스당 sdist 개수 제한
PyPI 상의 sdist는 소프트웨어의 특정 릴리스에 대한 단일한 진실 공급원(single source of truth)이어야 합니다. 그러나 현재 PyPI는 허용된 sdist 파일 확장자마다 sdist를 하나씩 업로드할 수 있도록 허용하고 있습니다. 현재 이는 하나의 프로젝트에 대해 약 10개의 서로 다른 sdist를 허용하는 셈이며, 본 PEP를 적용하더라도 단일 버전에 대해 두 개의 서로 다른 진실 공급원을 허용하게 됩니다. 여러 개의 sdist를 갖는 것은 종종 사용자가 어떤 sdist를 사용했는지에 따라서만 드러나는 이상한 버그의 원인이 될 수 있습니다.
이를 해결하기 위해, 본 PEP는 프로젝트의 릴리스당 오직 하나의 sdist만을 허용할 것을 제안합니다.
제거 절차
본 PEP는 PyPI에서 기존 파일을 제거하는 것을 제안하는 것이 아니며, 단지 새로운 파일의 업로드를 금지할 뿐입니다. 이 제한 사항은 프로젝트별로 단계적으로 도입되어, 해당되는 프로젝트들이 새로운 제한 사항에 적응할 수 있도록 할 것입니다.
먼저, 기존 프로젝트는 모두 레거시 파일 형식을 업로드할 수 있도록 플래그가 지정되며, 이 플래그가 없는 프로젝트(즉 신규 프로젝트)는 .tar.gz 또는 .zip 확장자를 가진 sdist, bdist_wheel, bdist_egg 외에는 아무것도 업로드할 수 없습니다. 그다음, 레거시 파일 형식 플래그가 필요한 파일을 한 번도 업로드한 적 없는 기존 프로젝트는 해당 플래그가 제거되어 새로운 제한 사항의 적용을 받게 됩니다. 마지막으로, 여전히 레거시 플래그가 지정된 모든 프로젝트의 관리자에게 이메일이 발송되며, 이 이메일은 곧 시행될 업로드 제한 사항을 안내하고 해당 제한이 1개월 후부터 해당 프로젝트의 향후 업로드에 적용될 것임을 알려줍니다. 마지막으로, 1개월 후에는 모든 프로젝트에서 레거시 파일 형식 플래그가 제거되며, 이러한 유형의 파일 업로드에 대한 지원은 PyPI에서 더 이상 존재하지 않게 됩니다.
이 계획은 기존 파일을 전혀 제거하지 않으므로 최소한의 혼란만 초래할 것이며, 업로드가 금지되는 파일 유형은 그다지 유용하지(또는 사용되지) 않는 유형이거나, 또는 프로세스를 약간만 변경하면 유사한 유형의 파일을 계속 업로드할 수 있는 유형입니다.
Copyright
This document has been placed in the public domain.