PEP 425 – 빌드 배포판 호환성 태그
- Author:
- Daniel Holth <dholth at gmail.com>
- BDFL-Delegate:
- Alyssa Coghlan <ncoghlan at gmail.com>
- Status:
- Final
- Type:
- Standards Track
- Topic:
- Packaging
- Created:
- 27-Jul-2012
- Python-Version:
- 3.4
- Post-History:
- 08-Aug-2012, 18-Oct-2012, 15-Feb-2013
- Resolution:
- Python-Dev message
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 PEP는 빌드 배포판 또는 바이너리 배포판이 어떤 Python 버전과 호환되는지 나타내는 태깅 시스템을 지정합니다. 세 태그의 집합은 빌드 배포판에 필요한 Python 구현과 언어 버전, ABI 및 플랫폼을 나타냅니다. 태그는 파일 이름에 포함되므로 간결합니다.
PEP 수락
이 PEP는 2013년 2월 17일에 Alyssa Coghlan이 수락했습니다.
근거
오늘날 “python setup.py bdist”는 PyPy와 CPython에서 동일한 파일 이름을 생성하지만, 호환되지 않는 아카이브이므로 동일한 폴더나 색인에서 빌드된 배포 패키지를 공유하기 어렵게 합니다. 대신 빌드 배포판에는 특정 아카이브가 특정 구현과 호환되는지 판단하기에 충분한 정보가 포함된 파일 이름 지정 규칙이 있어야 합니다.
이전의 노력은 CPython이 유일하게 중요한 구현이었고 ABI가 Python 언어 릴리스와 동일했던 시기에 나온 것입니다. 이 사양은 Python 구현, 언어 버전, ABI 및 플랫폼을 태그 집합으로 포함하여 이전 체계를 개선합니다.
설치 프로그램은 지원하는 태그와 배포판에 나열된 태그를 비교하여 전체 메타데이터를 읽지 않고도 특정 빌드 배포판을 다운로드할지 여부를 합리적으로 판단할 수 있습니다.
개요
태그 형식은 {python tag}-{abi tag}-{platform tag}입니다.
- Python 태그
- ‘py27’, ‘cp33’
- ABI 태그
- ‘cp32dmu’, ‘none’
- 플랫폼 태그
- ‘linux_x86_64’, ‘any’
예를 들어 py27-none-any 태그는 ABI 요구 사항 없이 모든 플랫폼에서 Python 2.7(모든 Python 2.7 구현)과 호환됨을 나타냅니다.
사용법
wheel 빌드 패키지 형식은 파일 이름에 이러한 태그를 포함하며, 형식은 {distribution}-{version}(-{build tag})?-{python tag}-{abi tag}-{platform tag}.whl입니다. 다른 패키지 형식에는 고유한 규칙이 있을 수 있습니다.
세부 사항
Python 태그
Python 태그는 배포판에 필요한 구현과 버전을 나타냅니다. 주요 구현에는 처음부터 다음과 같은 축약 코드가 사용됩니다.
- py: 일반 Python(구현별 기능을 요구하지 않습니다)
- cp: CPython
- ip: IronPython
- pp: PyPy
- jy: Jython
다른 Python 구현은 sys.implementation.name을 사용해야 합니다.
버전은 py_version_nodot입니다. CPython은 점이 없어도 문제없지만, 점이 필요한 경우에는 대신 밑줄 _을 사용합니다. PyPy는 여기서 자체 버전인 pp18, pp19를 사용하는 것이 좋을 것입니다.
많은 순수 Python 배포판에서는 버전을 주 버전 2 또는 3으로만 표시하거나 py2, py3로 표시할 수 있습니다.
특히 py2 및 py3와 같은 주 버전 전용 태그는 py20 및 py30의 약칭이 아니라는 점이 중요합니다. 대신 이러한 태그는 패키저가 버전 간 호환 배포판을 의도적으로 릴리스했음을 의미합니다.
단일 소스 Python 2/3 호환 배포판은 복합 태그 py2.py3를 사용할 수 있습니다. 아래의 Compressed Tag Sets를 참조하십시오.
ABI 태그
ABI 태그는 포함된 확장 모듈에 필요한 Python ABI를 나타냅니다. 구현별 ABI의 경우 구현 이름은 Python 태그와 같은 방식으로 축약됩니다. 예를 들어 cp33d는 디버깅 기능이 포함된 CPython 3.3 ABI를 의미합니다.
CPython 안정 ABI는 공유 라이브러리 접미사와 마찬가지로 abi3입니다.
ABI가 매우 불안정한 구현은 소스 코드 리비전과 컴파일러 플래그 등의 SHA-256 해시에서 처음 6바이트를 가져와 8개의 base64 인코딩 문자로 사용할 수 있지만, 바이너리 배포판을 배포할 필요성은 크지 않을 것입니다. 각 구현의 커뮤니티는 ABI 태그를 가장 적절하게 사용하는 방법을 결정할 수 있습니다.
플랫폼 태그
플랫폼 태그는 모든 하이픈 -및 마침표 .를 밑줄 _로 바꾼 distutils.util.get_platform()입니다.
- win32
- linux_i386
- linux_x86_64
사용
설치 프로그램은 잠재적인 빌드 배포판 목록에서 어떤 빌드 배포판을 다운로드할지 결정할 때 태그를 사용합니다. 설치 프로그램은 지원할 (pyver, abi, arch) 튜플 목록을 유지 관리합니다. 빌드 배포판의 태그가 목록에 in 포함되어 있으면 설치할 수 있습니다.
설치 프로그램은 우선 기본적으로 사용 가능한 빌드 배포판 중 기능이 가장 풍부한 것(설치 환경에 가장 구체적인 것)을 선택한 후, 이전 Python 릴리스용으로 게시된 순수 Python 버전으로 대체하는 것이 좋습니다. 또한 설치 프로그램은 허용되는 호환성 태그 목록을 구성하고 순서를 변경할 수 있는 방법을 제공하는 것이 좋습니다. 예를 들어 사용자는 순수 Python임을 명시하는 빌드 패키지만 다운로드하도록 *-none-any 태그만 허용할 수 있습니다.
또 다른 바람직한 설치 프로그램 기능은 호환 가능하지만 레거시인 일부 사전 빌드 옵션보다 “가능한 경우 소스에서 다시 컴파일”을 더 우선하는 기능일 수 있습니다.
이 예시 목록은 linux_x86_64 시스템에서 CPython 3.3으로 실행되는 설치 프로그램을 위한 것입니다. 현재 Python 버전용으로 빌드된 컴파일된 확장 모듈을 포함하는 배포판부터 이전 Python 버전으로 빌드된 순수 Python 배포판까지, 선호도가 가장 높은 항목에서 가장 낮은 항목 순서로 나열되어 있습니다.
- cp33-cp33m-linux_x86_64
- cp33-abi3-linux_x86_64
- cp3-abi3-linux_x86_64
- cp33-none-linux_x86_64*
- cp3-none-linux_x86_64*
- py33-none-linux_x86_64*
- py3-none-linux_x86_64*
- cp33-none-any
- cp3-none-any
- py33-none-any
- py3-none-any
- py32-none-any
- py31-none-any
- py30-none-any
- 빌드 배포판은 C 확장 이외의 이유로도 플랫폼별로 달라질 수 있으며, 예를 들어 서브프로세스로 호출되는 네이티브 실행 파일을 포함할 수 있습니다.
때때로 특정 패키지 버전에 대해 지원되는 빌드 배포판이 둘 이상 존재할 수 있습니다. 예를 들어 패키지 제작자는 선택적 C 확장을 포함하는 cp33-abi3-linux_x86_64 태그가 지정된 패키지와, 이를 포함하지 않는 py3-none-any 태그가 지정된 동일한 배포판을 릴리스할 수 있습니다. 지원되는 태그 목록에서 태그의 인덱스가 동률을 해소하며, 해당 태그가 목록에서 먼저 나타나므로 C 확장이 포함된 패키지가 포함되지 않은 패키지보다 우선하여 설치됩니다.
압축된 태그 집합
둘 이상의 호환성 태그 트리플에서 작동하는 bdist의 간결한 파일 이름을 허용하려면, 파일 이름의 각 태그를 대신 ‘.’로 구분되고 정렬된 태그 집합으로 나타낼 수 있습니다. 예를 들어 pip는 동일한 소스 코드로 Python 2와 3에서 실행되도록 작성된 순수 Python 패키지이므로 py2.py3-none-any 태그가 지정된 bdist를 배포할 수 있습니다. 단순 태그의 전체 목록은 다음과 같습니다.:
for x in pytag.split('.'):
for y in abitag.split('.'):
for z in archtag.split('.'):
yield '-'.join((x, y, z))
이 방식을 구현하는 bdist 형식은 bdist별 메타데이터에 확장된 태그를 포함해야 합니다. 이 압축 방식은 지원되지 않는 태그와 어떤 Python 구현에서도 지원되지 않는 “불가능한” 태그(예: “cp33-cp31u-win64”)를 대량으로 생성할 수 있으므로, 신중하게 사용하십시오.
FAQ
- 기본적으로 어떤 태그가 사용됩니까?
- 도구는 기본적으로 가장 선호되는 아키텍처 종속 태그(예:
cp33-cp33m-win32) 또는 가장 선호되는 순수 Python 태그(예:py33-none-any)를 사용해야 합니다. 패키지 제작자가 기본값을 재정의한다면, 이는 Python 간 호환성을 제공하려는 의도임을 나타냅니다. - 배포 패키지가 최신 Python 버전에만 있는 기능을 사용하는 경우 어떤 태그를 사용합니까?
- 호환성 태그는 설치 프로그램이 배포 패키지의 단일 버전에 대해 가장 호환성이 높은 빌드를 선택하는 데 도움을 줍니다. 예를 들어
beaglevote-1.2.0에 Python 3.3 호환 빌드가 없더라도(이 패키지가 Python 3.4 전용 기능을 사용하기 때문입니다),py34-none-any태그 대신py3-none-any태그를 사용할 수 있습니다. Python 3.3 사용자는 새 기능을 사용하지 않는 이전 릴리스beaglevote-1.1.0에 대한 요구 사항과 같은 다른 한정자를 결합해야 호환 가능한 빌드를 얻을 수 있습니다. - Python 버전 번호에
.이 없는 이유는 무엇입니까? - CPython은 3자리 메이저 릴리스 없이 20년 넘게 지속되어 왔습니다. 이는 당분간 계속될 것으로 예상됩니다. 다른 구현체는 구분자로 _를 사용할 수 있는데, -와 .가 모두 주변 파일 이름을 구분하는 데 쓰이기 때문입니다.
- 하이픈과 기타 영숫자가 아닌 문자를 밑줄로 정규화하는 이유는 무엇입니까?
- 파일 이름의 구성 요소를 구분하는 “.”와 “-” 문자와 충돌하지 않도록 하고, 파일 이름에 대한 파일시스템 제약이 가장 폭넓게 적용되는 환경에서도(URL 경로에서 따옴표 없이 사용 가능한 것을 포함하여) 더 나은 호환성을 확보하기 위해서입니다.
- “.”나 “-” 대신 특수 문자 <X>를 사용하지 않는 이유는 무엇입니까?
- 그 문자가 일부 맥락에서 불편하거나 혼동을 줄 수 있기 때문이거나(“+”는 URL에서 따옴표로 묶어야 하고, “~”는 POSIX에서 사용자의 홈 디렉터리를 나타내는 데 쓰입니다), 혹은 PEP 427에서 정의된 wheel 형식의 기존 참조 구현을 변경할 만큼 그 이점이 충분히 설득력 있지 않았기 때문입니다(예를 들어 압축된 태그에서 구성 요소를 구분할 때 “.” 대신 “,”를 사용하는 경우).
- 축약된 구현체 레지스트리는 누가 관리합니까?
- 새로운 두 글자 축약형은 python-dev 메일링 리스트에서 요청할 수 있습니다. 경험칙상 축약형은 현재 가장 널리 쓰이는 4개 구현체를 위해 예약되어 있습니다.
- 호환성 태그는 METADATA나 PKG-INFO에 들어갑니까?
- 아닙니다. 호환성 태그는 빌드된 배포판의 메타데이터의 일부입니다. METADATA / PKG-INFO는 해당 배포판의 특정 빌드 하나가 아니라 배포판 전체에 대해 유효해야 합니다.
- 제가 좋아하는 Python 구현체를 언급하지 않은 이유는 무엇입니까?
- 축약된 태그는 공개 색인에서 컴파일된 Python 코드를 공유하기 쉽게 해줍니다. 여러분의 Python 구현체도 이 명세를 사용할 수 있지만, 더 긴 태그를 사용해야 합니다. 모든 “순수 Python” 빌드 배포판은 단순히 ‘py’를 사용한다는 점을 기억하십시오.
- 참조 구현에서 ABI 태그(두 번째 태그)가 때때로 “none”인 이유는 무엇입니까?
- Python 2에는 SOABI에 접근하는 쉬운 방법이 없으므로(이 개념은 Python 3의 최신 버전에서 등장했습니다) 이 글을 쓰는 시점의 참조 구현은 “none”으로 추측합니다. 이상적으로는 최신 버전의 Python과 마찬가지로 “py27(d|m|u)”를 감지해야 하지만, 그때까지는 “none”이 “모른다”는 의미를 나타내기에 충분합니다.
참고 문헌
[1] Egg 파일 이름에 내장된 메타데이터 (http://peak.telecommunity.com/DevCenter/EggFormats#filename-embedded-metadata)
[2] 빌드 배포판 생성하기 (https://docs.python.org/3.4/distutils/builtdist.html)
감사의 말
저자는 소중한 도움과 조언을 준 Paul Moore, Alyssa Coghlan, Marc Abramowitz, Michele Lacchia 씨에게 감사드립니다.
Copyright
This document has been placed in the public domain.