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의 모든 미러에서도 대역폭과 디스크 공간 양쪽에 비용이 발생합니다.
Python 패키징은 여러 계층으로 이루어진 생태계로, 이 생태계에서 PyPI는 주로 각 프로젝트 소유자가 가상 환경과 호환되는 패키지를 직접 배포하는 데 적합하며 그러한 용도로 사용됩니다. 이렇게 배포된 패키지는 최종 사용자가 직접 사용하거나, 다운스트림 배포자가 가져가 각자의 시스템 수준 패키지(RPM, deb, MSI 등)로 변환합니다.
PyPI 자체는 이러한 Python 전용이지만 플랫폼에 구애받지 않는 패키지만을 직접 다루지만, 우리는 커뮤니티 주도 및 상업적으로 이러한 패키지를 다음과 같은 특정 대상 환경을 위한 다운스트림 형식으로 변환하는 것을 권장합니다.
- conda 크로스 플랫폼 데이터 분석 생태계(conda-forge)
- deb 기반 Linux 생태계(Debian, Ubuntu 등)
- RPM 기반 Linux 생태계(Fedora, openSuSE, Mageia 등)
- Mac OS X용 homebrew, MacPorts, fink 생태계
- Windows 패키지 관리 생태계(NuGet, Chocolatey 등)
- 서드파티의 Windows MSI 및 설치 프로그램 제작(예: http://www.lfd.uci.edu/~gohlke/pythonlibs/ 에 있는 Christoph Gohlke의 작업)
- 기타 상업적 재배포 형식(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와 같은 파일 확장자를 사용하기 때문에 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개만 업로드되었을 정도로 PyPI에서 거의 사용되지 않습니다.
또한 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 파일로 더 잘 대응할 수 있습니다)에서 발생했음을 알 수 있습니다.
bdist_dmg와 bdist_msi로 업로드된 파일 수가 적고, bdist_wininst는 대체로 미러링 인프라를 통해 대역폭과 디스크 공간을 소비하기 위해 존재하거나 또는 bdist_egg로 손쉽게 대체할 수 있다는 점을 고려하여, 이 PEP는 이 세 형식을 금지 대상 목록에 포함할 것을 제안합니다.
파일 확장자
현재 sdist는 .tar.gz, .tar, .tar.bz2, .tar.xz, .zip, .tar.Z, .tgz, .tbz 같은 매우 다양한 파일 확장자를 지원합니다. 하지만 그중 무시할 수 없을 만큼 사용되는 확장자는 현재 sdist가 444,338개인 .tar.gz, 58,774개인 .zip, 3,265개인 .tar.bz2뿐입니다.
여러 형식을 허용하면 PyPI 내부와 외부의 도구 모두가 사용될 수도 있는 온갖 확장자를 처리해야 합니다(현재 아무도 사용하지 않더라도 말입니다). 이는 PyPI에만 영향을 미치는 것이 아니라 생태계 전반으로 파급됩니다. 또한 각 형식은 Python이 어떤 선택적 C 라이브러리와 링크되어 있어야 하는지에 대한 요구 사항과 어떤 Python 버전을 지원하는지에 대한 요구 사항이 모두 다릅니다. 게다가 여러 형식이 있으면 특정 프로젝트/릴리스에 내용이 미묘하게 다른 sdist 파일이 두 개 존재할 수 있는 이상한 상황도 생깁니다.
.tar.gz, .zip, .tar.bz2 이외의 것은 모두 금지해야 한다고 주장하기는 쉽습니다. 극소수를 제외하면 PyPI가 존재해 온 약 15년 동안 아무도 이러한 다른 유형의 파일을 적극적으로 업로드하지 않았으므로, 이들은 분명 그다지 유용하지 않았습니다. 또한 .tar.xz는 LZMA가 달성하는 더 나은 압축률 덕분에 이론적으로는 다른 .tar.* 형식보다 좋은 형식이지만, Python 3.3 이상에서만 사용할 수 있고 lzma C 라이브러리에 대한 선택적 의존성이 있습니다.
현재 실제로 사용 중인 세 확장자를 살펴보면, .tar.bz2도 금지할 수 있다고 결론 내리기 역시 꽤 쉽습니다. 이 확장자로 업로드된 파일 수는 꽤 적고, bzip2 압축을 처리하려면 추가적인 선택적 C 라이브러리가 필요합니다.
마지막으로 .tar.gz와 .zip을 살펴보겠습니다. 이 두 형식의 수치만 보면 .tar.gz는 총 444,338개가 업로드되어 .zip의 58,774개보다 훨씬 많이 업로드된 형식임을 알 수 있으며, POSIX 운영 체제에서는 현재 릴리스된 모든 버전의 Python과 setuptools가 기본으로 생성하는 형식도 .tar.gz입니다. 또한 이 두 파일 형식은 모두 같은 C 라이브러리(zlib)를 사용하며, 이 라이브러리는 bdist_wheel과 bdist_egg에도 필요합니다. .tar.gz와 .zip 중 하나를 고를 때 걸리는 두 가지 문제는, POSIX 운영 체제에서는 .tar.gz가 기본값이지만 Windows에서는 .zip이 기본값이고, bdist_wheel 형식도 zip을 사용한다는 점입니다.
이 PEP는 .tar.gz나 .zip 중 하나로 표준화하려 하는 대신, sdist에 .tar.gz와 .zip 중 어느 쪽이든 허용할 것을 제안합니다.
릴리스당 sdist 개수 제한
PyPI의 sdist는 소프트웨어의 특정 릴리스에 대한 단일한 진실 공급원(single source of truth)이어야 합니다. 그러나 현재 PyPI는 허용하는 sdist 파일 확장자마다 sdist를 하나씩 업로드할 수 있게 합니다. 현재는 이 때문에 한 프로젝트에 서로 다른 sdist가 10개가량 허용되며, 이 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.