PEP 711 – PyBI: Python 바이너리 배포를 위한 표준 형식
- Author:
- Nathaniel J. Smith <njs at pobox.com>
- PEP-Delegate:
- TODO
- Discussions-To:
- Discourse thread
- Status:
- Draft
- Type:
- Standards Track
- Topic:
- Packaging
- Created:
- 06-Apr-2023
- Post-History:
- 06-Apr-2023
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
“휠과 비슷하지만, 미리 빌드된 Python 패키지 대신 미리 빌드된 Python 인터프리터입니다”
동기
최종 목표: Pypi.org에 모든 인기 플랫폼에서 사용할 수 있는 모든 Python 버전용 미리 빌드된 패키지가 제공되므로, 자동화 도구가 그중 무엇이든 쉽게 가져와 설정할 수 있도록 하는 것입니다. 이를 통해 Python 프리릴리스를 빠르고 쉽게 사용해 보고, CI에서 Python 버전을 고정하고, 특정 Python 포인트 릴리스에서만 발생하는 버그 보고를 재현하기 위한 임시 환경을 만드는 등의 작업을 빠르고 쉽게 수행할 수 있습니다.
첫 단계(이 PEP): 기존 Python 패키징 표준을 가능한 한 많이 재사용하는, 미리 빌드된 Python 인터프리터를 담기 위한 표준 패키징 파일 형식을 정의하는 것입니다.
예제
예제 pybi 빌드는 pybi.vorpus.org에서 사용할 수 있습니다. 이것들은 zip 파일이므로, 구조를 파악하고 싶다면 압축을 풀고 내부를 살펴볼 수 있습니다.
이를 생성하는 데 사용한 도구도 살펴볼 수 있습니다.
사양
파일 이름
파일 이름: {distribution}-{version}[-{build tag}]-{platform tag}.pybi
이는 PEP 427에서 정의한 휠 파일 형식과 일치하지만, {python tag}와 {abi tag}를 제거하고 확장자를 .whl에서 .pybi로 변경합니다.
예를 들면 다음과 같습니다.
cpython-3.9.3-manylinux_2014.pybicpython-3.10b2-win_amd64.pybi
휠과 마찬가지로 pybi가 여러 플랫폼을 지원하는 경우, 점으로 구분하여 “압축된 태그 집합”을 만들 수 있습니다.
cpython-3.9.5-macosx_11_0_x86_64.macosx_11_0_arm64.pybi
(다만 실제로는 이 방식이 많이 사용되지는 않을 것입니다. 예를 들어 위 파일 이름은 관례상 cpython-3.9.5-macosx_11_0_universal2.pybi로 작성하는 편이 더 자연스럽습니다.)
파일 내용
.pybi 파일은 임의의 위치에 직접 압축을 풀고 독립 실행형 Python 환경으로 사용할 수 있는 zip 파일입니다. Python 환경이 자신이 사용하는 설치 스킴을 알고 있으므로 처음부터 올바른 위치에 파일을 배치할 수 있기 때문에, .data 디렉터리나 설치 스킴 키는 없습니다.
“임의의 위치”라는 부분이 중요합니다. pybi에는 하드코딩된 절대 경로가 포함될 수 없습니다. 특히 사전 설치된 스크립트는 셔뱅 줄에 절대 경로를 포함해서는 안 됩니다.
휠의 <package>-<version>.dist-info 디렉터리와 유사하게, pybi 아카이브에는 pybi-info/라는 최상위 디렉터리가 포함되어야 합니다. (그 이유는 dist-info 대신 pybi-info라고 부르면 도구가 어떤 종류의 메타데이터를 보고 있는지 혼동하지 않도록 할 수 있기 때문입니다. {name}-{version} 부분을 생략해도 괜찮은데, 주어진 디렉터리에는 하나의 pybi만 설치할 수 있기 때문입니다.) pybi-info/ 디렉터리에는 최소한 다음 파일이 포함됩니다.
.../PYBI:METADATA및WHEEL파일과 동일한 RFC822 유사 형식으로 작성된 아카이브 자체의 메타데이터입니다.Pybi-Version: 1.0 Generator: {name} {version} Tag: {platform tag} Tag: {another platform tag} Tag: {...and so on...} Build: 1 # optional
.../RECORD: 아래의 심볼릭 링크에 관한 참고 사항을 제외하면 휠의 경우와 같습니다..../METADATA: 현재 핵심 메타데이터 사양에 설명된 형식과 동일하지만, 의미가 없기 때문에 다음 키는 금지됩니다.Requires-DistProvides-ExtraRequires-Python
또한 아래에 설명된 새 필수 키도 있습니다.
Pybi별 핵심 메타데이터
전체 세부 사항을 설명하기 전에 새로운 METADATA 필드의 예를 들어 보겠습니다.:
Pybi-Environment-Marker-Variables: {"implementation_name": "cpython", "implementation_version": "3.10.8", "os_name": "posix", "platform_machine": "x86_64", "platform_system": "Linux", "python_full_version": "3.10.8", "platform_python_implementation": "CPython", "python_version": "3.10", "sys_platform": "linux"}
Pybi-Paths: {"stdlib": "lib/python3.10", "platstdlib": "lib/python3.10", "purelib": "lib/python3.10/site-packages", "platlib": "lib/python3.10/site-packages", "include": "include/python3.10", "platinclude": "include/python3.10", "scripts": "bin", "data": "."}
Pybi-Wheel-Tag: cp310-cp310-PLATFORM
Pybi-Wheel-Tag: cp310-abi3-PLATFORM
Pybi-Wheel-Tag: cp310-none-PLATFORM
Pybi-Wheel-Tag: cp39-abi3-PLATFORM
Pybi-Wheel-Tag: cp38-abi3-PLATFORM
Pybi-Wheel-Tag: cp37-abi3-PLATFORM
Pybi-Wheel-Tag: cp36-abi3-PLATFORM
Pybi-Wheel-Tag: cp35-abi3-PLATFORM
Pybi-Wheel-Tag: cp34-abi3-PLATFORM
Pybi-Wheel-Tag: cp33-abi3-PLATFORM
Pybi-Wheel-Tag: cp32-abi3-PLATFORM
Pybi-Wheel-Tag: py310-none-PLATFORM
Pybi-Wheel-Tag: py3-none-PLATFORM
Pybi-Wheel-Tag: py39-none-PLATFORM
Pybi-Wheel-Tag: py38-none-PLATFORM
Pybi-Wheel-Tag: py37-none-PLATFORM
Pybi-Wheel-Tag: py36-none-PLATFORM
Pybi-Wheel-Tag: py35-none-PLATFORM
Pybi-Wheel-Tag: py34-none-PLATFORM
Pybi-Wheel-Tag: py33-none-PLATFORM
Pybi-Wheel-Tag: py32-none-PLATFORM
Pybi-Wheel-Tag: py31-none-PLATFORM
Pybi-Wheel-Tag: py30-none-PLATFORM
Pybi-Wheel-Tag: py310-none-any
Pybi-Wheel-Tag: py3-none-any
Pybi-Wheel-Tag: py39-none-any
Pybi-Wheel-Tag: py38-none-any
Pybi-Wheel-Tag: py37-none-any
Pybi-Wheel-Tag: py36-none-any
Pybi-Wheel-Tag: py35-none-any
Pybi-Wheel-Tag: py34-none-any
Pybi-Wheel-Tag: py33-none-any
Pybi-Wheel-Tag: py32-none-any
Pybi-Wheel-Tag: py31-none-any
Pybi-Wheel-Tag: py30-none-any
사양:
Pybi-Environment-Marker-Variables: 이 Pybi의 설치 전반에서 정적인 모든 PEP 508 환경 마커 변수의 값으로 이루어진 JSON 딕셔너리입니다. 예를 들면 다음과 같습니다:python_version은 항상 존재합니다. Python 3.10 패키지는 항상python_version == "3.10"이기 때문입니다.platform_version은 일반적으로 존재하지 않습니다. Python이 실행 중인 운영 체제에 관한 자세한 정보를 제공하기 때문입니다. 예를 들어:#60-Ubuntu SMP Thu May 6 07:46:32 UTC 2021platform_release도 비슷한 문제가 있습니다.platform_machine은 대개 존재하지만, macOS universal2 pybi는 예외입니다. 이러한 pybi는 x86-64 모드 또는 arm64 모드로 실행될 수 있으며, 인터프리터가 실제로 호출될 때까지 어느 모드인지 알 수 없으므로 정적 메타데이터에 기록할 수 없습니다.
근거: 대부분의 경우 이를 통해 Linux에서 실행되는 리졸버가 Windows의 Python 환경에 사용할 패키지 고정을 계산하거나 그 반대로 계산할 수 있습니다. 단, 리졸버가 대상 플랫폼의 .pybi 파일에 액세스할 수 있어야 합니다. (
Requires-Python제약 조건은python_full_version값을 사용하여 확인할 수 있습니다.) 일부 키를 경우에 따라 제외해야 하지만, 제외되는 키는 상당히 쓸모없거나(platform_version,platform_release) 리졸버가 재구성할 수 있는 키(platform_machine)입니다.마커는 액세스 가능한 일반 정보로서도 유용합니다. 예를 들어
pypy3-7.3.2pybi가 있고 해당 pybi가 지원하는 Python 언어 버전을 알고 싶다면, 그 정보가python_version마커에 기록되어 있습니다.(참고:
platform_version과platform_release를 더 이상 사용하지 않도록 하거나 제거할 수도 있습니다? 이러한 항목은 문제가 있으며, 유용한 경우를 전혀 찾을 수 없습니다. 그러나 이는 이 특정 PEP의 범위를 벗어납니다.)Pybi-Paths: 휠을 설치하는 데 필요한 설치 경로(sysconfig.get_paths()와 동일한 키)로, zip 파일의 루트에서 시작하는 상대 경로로 표현된 JSON 딕셔너리입니다.이러한 경로는 백슬래시가 아닌 슬래시를 구분 기호로 사용하는 Unix 형식으로 작성해야 합니다.
{paths["scripts"]}/python을 실행하여 Python 인터프리터를 호출할 수 있어야 합니다. 대체 인터프리터 진입점(예: Windows GUI 앱용pythonw)이 있다면, 버전 번호를 붙이지 않은 관례적인 이름으로 해당 디렉터리에도 있어야 합니다. (원한다면python3.11심볼릭 링크를 추가로 둘 수도 있습니다. 이를 금지하는 규칙은 없습니다. 단,python이 존재하고 정상적으로 작동해야 합니다.)근거:
Pybi-Paths와Pybi-Wheel-Tags (아래 참조)는 함께 사용하면 설치 프로그램이 Python을 호출하지 않고도 휠을 선택하여 압축을 해제한 pybi 환경에 설치할 수 있을 만큼 충분한 정보를 제공합니다. 게다가 인터프리터 위치를 어딘가에 기록해야 하므로, 일석이조입니다.Pybi-Wheel-Tag: 이 인터프리터가 지원하는 휠 태그를 선호 순서(가장 선호하는 태그부터 가장 덜 선호하는 태그 순)로 나열한 것입니다. 단, 특수 플랫폼 태그인PLATFORM은 최종 설치 시스템에 따라 달라지는 모든 플랫폼 태그를 대신해야 합니다.논의: 설치 프로그램이 pybi에 대응하는 휠 태그를 미리 계산할 수 있다면 좋겠지만™ 합니다. 그러면 효율성을 높일 수 있을 뿐 아니라 Linux 호스트에서 Windows 환경을 설정하는 것과 같은 더 이색적인 사용 사례도 가능해지므로, 실제로 Python 인터프리터를 호출하여 태그를 조회하지 않고도 압축을 해제한 pybi에 휠을 설치할 수 있습니다.
그러나 안타깝게도 Python 설치가 지원하는 플랫폼 태그의 전체 집합을 미리 계산하는 것은 불가능합니다. 플랫폼 태그가 최종 시스템에 따라 달라질 수 있기 때문입니다.
manylinux_2_12_x86_64로 태그된 pybi는 항상manylinux_2_12_x86_64로 태그된 휠을 사용할 수 있습니다. 또한 사용할 수 있을 수도 있지만, 최종 설치 시스템에 glibc 2.17 이상이 있는 경우에만manylinux_2_17_x86_64태그가 붙은 휠을 사용할 수 있습니다.macosx_11_0_universal2로 태그된 pybi(동일한 바이너리에서 x86-64 및 arm64를 지원함)는macosx_11_0_arm64로 태그된 휠을 사용할 수도 있지만, “Apple Silicon” 시스템에 설치되어 arm64 모드로 실행되는 경우에만 가능합니다.
이 두 경우에 설치 도구는 로컬 플랫폼 태그를 계산하고,
Pybi-Wheel-Tag에서 휠 태그 템플릿을 가져온 다음, 특수한PLATFORM문자열을 실제 지원 플랫폼으로 대체하여 적절한 휠 태그 집합을 계산할 수 있습니다.그러나 훨씬 더 복잡한 다른 경우도 있습니다:
- 64비트 Windows에서 32비트 및 64비트 앱을 모두 (대개) 실행할 수 있습니다. 따라서 pybi
- 설치 프로그램은 현재 플랫폼에서 허용되는 pybi 태그 집합을 [
win32,win_amd64]로 계산할 수 있습니다. 하지만 그런 다음 그 집합을 그대로 pybi의 휠 태그 템플릿에 대입하면 말이 되지 않는 결과를 얻게 됩니다.[ "cp39-cp39-win32", "cp39-cp39-win_amd64", "cp39-abi3-win32", "cp39-abi3-win_amd64", ... ]
이를 처리하려면 설치 프로그램은 현재 머신에서 두 태그가 모두 유효한 태그인 경우
manylinux_2_12_x86_64pybi가manylinux_2_17_x86_64wheel을 사용할 수 있지만,win32pybi는 두 태그가 현재 머신에서 모두 유효한 경우에도win_amd64wheel을 사용할 수 없다는 것을 어떻게든 이해해야 합니다.
macosx_11_0_universal2태그가 붙은 pybi는macosx_11_0_x86_64태그가 붙은 wheel을 사용할 수도 있지만, x86-64 머신에 설치되었거나, 또는 ARM 머신에 설치되고 그리고 macOS에 바이너리를 x86-64 모드로 실행하도록 지시하는 마법의 명령으로 인터프리터가 호출된 경우에만 가능합니다. 따라서 설치 프로그램이 pybi를 어떻게 호출할 계획인지도 중요합니다!
따라서 실제로
Pybi-Wheel-Tag값을 사용하는 일은 보이는 것보다 간단하지 않으며, 상당히 정교한 도구에서만 유용할 가능성이 높습니다. 하지만 지능적인 pybi 설치 프로그램은 작동하는 pybi를 선택하기 위해 이미 이러한 플랫폼 호환성 문제를 많이 이해해야 합니다. 또한 플랫폼 간 고정 및 환경 구축의 경우에는 사용자가 대상으로 삼는 정확한 플랫폼을 판별하는 데 필요한 정보를 무엇이든 제공할 수 있습니다. 따라서 PyBI 메타데이터에 포함할 만큼은 여전히 유용합니다. 유용하다고 판단하지 않는 도구는 간단히 무시할 수 있습니다.
빌드된 인터프리터에서 이 스크립트를 실행하면 이러한 메타데이터 값을 생성할 수 있을 것입니다.
import packaging.markers
import packaging.tags
import sysconfig
import os.path
import json
import sys
marker_vars = packaging.markers.default_environment()
# Delete any keys that depend on the final installation
del marker_vars["platform_release"]
del marker_vars["platform_version"]
# Darwin binaries are often multi-arch, so play it safe and
# delete the architecture marker. (Better would be to only
# do this if the pybi actually is multi-arch.)
if marker_vars["sys_platform"] == "darwin":
del marker_vars["platform_machine"]
# Copied and tweaked version of packaging.tags.sys_tags
tags = []
interp_name = packaging.tags.interpreter_name()
if interp_name == "cp":
tags += list(packaging.tags.cpython_tags(platforms=["xyzzy"]))
else:
tags += list(packaging.tags.generic_tags(platforms=["xyzzy"]))
tags += list(packaging.tags.compatible_tags(platforms=["xyzzy"]))
# Gross hack: packaging.tags normalizes platforms by lowercasing them,
# so we generate the tags with a unique string and then replace it
# with our special uppercase placeholder.
str_tags = [str(t).replace("xyzzy", "PLATFORM") for t in tags]
(base_path,) = sysconfig.get_config_vars("installed_base")
# For some reason, macOS framework builds report their
# installed_base as a directory deep inside the framework.
while "Python.framework" in base_path:
base_path = os.path.dirname(base_path)
paths = {key: os.path.relpath(path, base_path).replace("\\", "/") for (key, path) in sysconfig.get_paths().items()}
json.dump({"marker_vars": marker_vars, "tags": str_tags, "paths": paths}, sys.stdout)
이 명령은 표준 출력에 JSON 딕셔너리를 출력하며, pybi별 태그 집합마다 별도의 항목을 포함합니다.
심볼릭 링크
현재 모든 Unix Python 설치에서는 심볼릭 링크가 기본적으로 사용됩니다(예: bin/python3 -> bin/python3.9). 또한 macOS 프레임워크 빌드를 .pybi 파일에 저장하려면 심볼릭 링크가 필수입니다. 따라서 휠 파일과 달리 .pybi 파일에서는 심볼릭 링크를 반드시 지원해야만 파일이 실제로 유용해집니다.
zip 파일에서 심볼릭 링크 표현하기
zip 파일에서 심볼릭 링크를 표현하는 사실상의 표준은 다음과 같이 작동하는 Info-Zip 심볼릭 링크 확장입니다.
- 심볼릭 링크의 대상 경로는 파일 콘텐츠인 것처럼 저장됩니다.
- Unix 권한 필드의 상위 4비트는
0xa로 설정됩니다. 즉,permissions & 0xf000 == 0xa000입니다. - 그리고 Unix 권한 필드는 “외부 속성” 필드의 상위 16비트로 저장됩니다.
따라서 Python의 zipfile 모듈을 사용하는 경우 다음과 같이 ZipInfo가 심볼릭 링크를 나타내는지 확인할 수 있습니다.
(zip_info.external_attr >> 16) & 0xf000 == 0xa000
또는 Rust의 zip 크레이트를 사용하는 경우 이에 해당하는 확인 방법은 다음과 같습니다.
fn is_symlink(zip_file: &zip::ZipFile) -> bool {
match zip_file.unix_mode() {
Some(mode) => mode & 0xf000 == 0xa000,
None => false,
}
}
Unix를 사용 중이라면 zip 및 unzip 명령이 이미 이 형식을 이해할 가능성이 높습니다.
RECORD 파일에서 심볼릭 링크 표현하기
일반적으로 RECORD 파일은 각 파일과 해당 해시 및 길이를 나열합니다.
my/favorite/file,sha256=...,12345
심볼릭 링크의 경우에는 대신 다음과 같이 작성합니다.
name/of/symlink,symlink=path/to/symlink/target,
즉, symlink라는 특수한 “해시 함수”를 사용한 다음 실제 심볼릭 링크 대상을 “해시 값”으로 저장합니다. 그리고 길이는 비워 둡니다.
근거: 이미 RECORD 파일에 주 아카이브의 모든 항목에 대한 중복 검사를 포함하기로 했으므로, 심볼릭 링크에 대해서는 적어도 일종의 해시와 이것이 심볼릭 링크임을 나타내는 일종의 플래그를 저장해야 합니다. 심볼릭 링크 대상 문자열은 해시와 대략 같은 크기이므로, 이를 그대로 저장하는 편이 좋습니다. 또한 이렇게 하면 Info-Zip 심볼릭 링크 확장을 이해하지 못하는 도구에서도 심볼릭 링크 정보에 더 쉽게 접근할 수 있으며, Windows 시스템에서 Unix pybi를 정보 손실 없이 풀고 다시 패키징할 수 있습니다. 이는 언젠가 누군가에게 유용할 수도 있습니다.
pybi 파일에 심볼릭 링크 저장하기
pybi 생성자가 심볼릭 링크를 저장할 때는 위에서 정의한 두 메커니즘을 모두 사용해야 합니다. 즉, Info-Zip 표현을 사용하여 zip 아카이브에 직접 저장하고, RECORD 파일에도 기록해야 합니다.
Pybi 사용자는 아카이브와 RECORD 파일의 심볼릭 링크가 서로 일치하는지 검증해야 합니다.
심볼릭 링크를 저장하는 데 RECORD 파일만 사용하는 방법도 고려했지만, 그렇게 하면 기본 unzip 도구로 해당 링크를 압축 해제할 수 없으며, 셸 스크립트에서 pybi를 설치하기도 어려워집니다.
제한 사항
심볼릭 링크는 잠재적으로 많은 문제를 일으킬 수 있습니다. 이를 통제하기 위해 다음 제한 사항을 적용합니다.
- Windows 또는 일급 심볼릭 링크 지원이 없는 기타 플랫폼을 대상으로 하는
.pybi는 심볼릭 링크를 사용해서는 안 됩니다. pybi-info디렉터리 내부에서는 심볼릭 링크를 사용해서는 안 됩니다. (이유: 그럴 필요가 없으며, 전체 아카이브를 압축 해제하지 않고pybi-info에서 정보를 추출해야 하는 확인자에게 작업을 단순하게 해 줍니다.)- 심볼릭 링크 대상은 상대 경로여야 하며, pybi 디렉터리 내부에 있어야 합니다.
- 아카이브에서
A/B/...가 심볼릭 링크로 기록된 경우, 아카이브에A/B/.../C와 같은 이름의 다른 항목이 있어서는 안 됩니다.예를 들어 아카이브에
foo -> bar라는 심볼릭 링크가 있고, 그 뒤에 아카이브에foo/blah.py라는 일반 파일이 있다면, 순진한 압축 해제 도구는 결국bar/blah.py라는 파일을 작성하게 될 수 있습니다. 순진하게 굴지 마십시오.
압축 해제 도구는 이러한 규칙이 준수되는지 반드시 확인해야 합니다. 그렇지 않으면 공격자가 foo -> /etc/passwd 또는 foo -> ../../../../../etc + foo/passwd -> ...와 같은 악성 심볼릭 링크를 만들어 큰 혼란을 일으킬 수 있습니다.
비규범적 주석
conda를 그냥 사용하면 안 됩니까?
이는 실제로 이 PEP의 범위에 속하는 내용은 아니지만, conda는 바이너리 Python 인터프리터를 배포하는 인기 있는 방법이므로 자연스러운 질문입니다.
간단한 답은 conda가 훌륭하다는 것입니다! 그러나 conda 사용자가 아닌 Python 사용자가 많으며, 이들에게도 좋은 도구가 필요합니다. 이 PEP는 이들에게 또 다른 선택지를 제공할 뿐입니다.
더 깊이 있는 답은 PyPI에 패키지를 업로드하는 유지 관리자가 Python 생태계의 중추라는 것입니다. 이들은 Python 패키징 도구의 첫 번째 대상 사용자입니다. 그리고 이들이 원하는 것 중 하나는 패키지를 한 번 업로드하고, Debian과 Fedora, Homebrew와 FreeBSD, Conda 환경, 대기업의 모노레포, Nix, Blender 플러그인, RenPy 게임 등 Python이 배포되는 모든 다양한 방식에서 해당 패키지에 접근할 수 있게 하는 것입니다. 무슨 뜻인지 아실 것입니다.
이러한 환경은 모두 패키지와 종속성을 관리하기 위한 자체 도구와 전략을 갖추고 있습니다. 따라서 PyPI와 wheel의 특별한 점은 모든 다운스트림 시스템이 사용할 수 있고 각자의 규칙으로 변환할 수 있도록 종속성을 표준적이고 추상적인 방식으로 설명하도록 설계되었다는 것입니다. 이것이 패키지 유지 관리자가 Python 전용 메타데이터를 사용하고 PyPI에 업로드하는 이유입니다. 이 메타데이터를 사용하면 이러한 모든 시스템을 동시에 대상으로 삼을 수 있기 때문입니다. conda용 Python 패키지를 빌드할 때마다 중간 wheel이 생성됩니다. wheel은 Python 패키지 빌드 시스템과 conda가 서로 통신할 때 사용할 수 있는 공통 언어이기 때문입니다.
그러나 sdist+wheels를 릴리스하는 유지 관리자라면, 임의의 PyPI 패키지와 버전에 의존할 수 있는 릴리스 결과물을 자연스럽게 테스트하고 싶을 것입니다. 따라서 PyPI에서 직접 Python 환경을 빌드하는 도구가 필요하지만, conda는 근본적으로 그렇게 하도록 설계되지 않았습니다. 그러므로 conda와 pip는 서로 다른 경우에 모두 필요하며, 이 제안은 그 방정식에서 pip 측을 대상으로 합니다.
Sdists(또는 그렇지 않은 것)
pybi를 위한 “sdist”에 해당하는 것을 제공하면 좋을 수 있습니다. 즉, 미리 빌드된 pybi를 사용할 수 없는 플랫폼에서 도구가 Python 소스 릴리스를 자동으로 가져와 pybi로 빌드할 수 있을 만큼 구조화된 일종의 형식입니다. 하지만 이는 MVP에 필요하지 않고 여러 복잡한 문제를 일으킬 수 있으므로, 나중에 걱정합시다.
pybi 안에 어떤 패키지를 번들로 포함해야 합니까?
pybi 빌더는 정확히 무엇을 내부에 포함할지 선택할 수 있습니다. 예를 들어 pybi의 site-packages 디렉터리에 미리 설치된 패키지를 일부 포함하거나, 원하지 않는 표준 라이브러리의 일부를 제거할 수 있습니다. 이를 막을 수는 없습니다! 다만 패키지를 미리 설치한다면 Pip이나 다른 도구가 무슨 일이 일어나고 있는지 파악할 수 있도록 올바른 메타데이터(.dist-info 등)도 포함하는 것이 강력히 권장됩니다.
제 “범용” 프로토타입 pybi에서 제가 선택한 것은 다음과 같습니다:
site-packages가 비어 있도록 하십시오.근거: 최종 사용자를 대상으로 하는 기존의 독립형 Python 설치 프로그램에서는 부트스트래핑 문제(PEP 453)를 피하기 위해 적어도
pip를 포함하는 것이 좋을 것입니다. 하지만 pybi는 다릅니다. pybi는 일종의 더 큰 자동화된 배포 프로세스의 일부로 pybi를 소비하는 “스마트” 도구를 통해 설치되도록 설계되었습니다. 이러한 설치 프로그램은 원할 수도 있고 원하지 않을 수도 있는 미리 설치된 패키지로 시작하는 것보다 빈 상태에서 시작한 다음 필요한 것을 추가하는 편이 더 쉽습니다. (게다가python -m ensurepip도 여전히 실행할 수 있습니다.)- 전체 표준 라이브러리를
test를 제외하고 포함하십시오.근거: 최상위
test모듈에는 CPython 자체의 테스트 모음이 포함되어 있습니다. 이 모듈은 매우 큽니다(test가 없는 CPython은 약 37MB이고,test가 여기에 다시 약 25MB를 추가합니다!). 또한 일반 사용자 코드에서는 사실상 사용되지 않습니다. 또한 선례로 공식 nuget 패키지, 공식 manylinux 이미지 및 여러 Linux 배포판은 모두 이를 제외하고 있으며, 이로 인해 지금까지 큰 문제가 발생하지 않았습니다.따라서 이는 광범위한 호환성과 합리적인 다운로드 및 설치 크기의 균형을 맞추는 최선의 방법인 듯합니다.
.pyc파일은 전혀 제공하지 않습니다. 해당 파일은 다운로드에서 공간을 차지하고, 최종 시스템에서 최소한의 비용으로 생성할 수 있으며, 이를 제거하면 위치 의존성의 원인이 하나 사라집니다. (.pyc파일은 해당.py파일의 절대 경로를 저장하고 이를 트레이스백에 포함합니다. 그러나 pybi는 재배치 가능하므로 올바른 경로는 설치가 완료될 때까지 알 수 없습니다.)
하위 호환성
하위 호환성에 관한 고려 사항은 없습니다.
보안 영향
바이너리를 배포하기로 한 사람은 누구나 보안을 관리할 계획을 세워야 한다는 사실(예: OpenSSL CVE가 공개된 후 새 빌드를 만들지 여부)을 제외하면 보안 영향은 없습니다. 하지만 전체적으로 Python 핵심 개발자들은 이미 모든 주요 플랫폼에 대한 바이너리 빌드를 유지 관리하고 있습니다(macOS 및 Windows는 python.org를 통해, Linux 빌드는 공식 manylinux 이미지를 통해). 따라서 공식 CPython 빌드를 PyPI에 릴리스하기 시작하더라도 새로운 보안 문제가 실제로 발생하지는 않습니다.
이 내용을 가르치는 방법
이는 최종 사용자를 대상으로 하지 않습니다. 예를 들어 해당 프로젝트의 유지 관리자가 이 PEP를 활용하기로 결정한다면, 최종 사용자는 자신의 pyenv 또는 tox 호출이 마법처럼 더 빠르고 안정적으로 실행된다는 경험만 하게 됩니다.
Copyright
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.