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 태그}-{abi 태그}-{플랫폼 태그}입니다.
- 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바이트(base64로 인코딩하면 8문자)를 사용할 수 있지만, 이러한 구현은 바이너리 배포판을 배포할 필요성이 그다지 크지 않을 것입니다. 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로 태그된 패키지와, C 확장을 포함하지 않는 py3-none-any로 태그된 같은 배포판을 릴리스할 수 있습니다. 이 경우 지원되는 태그 목록에서의 태그 인덱스로 우열을 가리며, C 확장이 있는 패키지의 태그가 목록에서 먼저 나타나므로 C 확장이 있는 패키지가 C 확장이 없는 패키지보다 우선하여 설치됩니다.
압축된 태그 집합
둘 이상의 호환성 태그 삼중항에서 동작하는 bdist의 파일 이름을 간결하게 만들 수 있도록, 파일 이름의 각 태그는 단일 태그 대신 ‘.’으로 구분되고 정렬된 태그 집합이 될 수 있습니다. 예를 들어 같은 소스 코드로 Python 2와 3에서 실행되도록 작성된 순수 Python 패키지인 pip는 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.