Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 426 – 파이썬 소프트웨어 배포 패키지 메타데이터 2.0

Author:
Alyssa Coghlan <ncoghlan at gmail.com>, Daniel Holth <dholth at gmail.com>, Donald Stufft <donald at stufft.io>
BDFL-Delegate:
Donald Stufft <donald at stufft.io>
Discussions-To:
Distutils-SIG list
Status:
Withdrawn
Type:
Informational
Topic:
Packaging
Requires:
440, 508, 518
Created:
30-Aug-2012
Post-History:
14-Nov-2012, 05-Feb-2013, 07-Feb-2013, 09-Feb-2013, 27-May-2013, 20-Jun-2013, 23-Jun-2013, 14-Jul-2013, 21-Dec-2013
Replaces:
345
Superseded-By:
566

Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

Important

This PEP is a historical document. The up-to-date, canonical spec, Core metadata specifications, is maintained on the PyPA specs page.

×

See the PyPA specification update process for how to propose changes.

Important

This PEP has been withdrawn.

×

이 PEP에서 제안한 근본적인 메타데이터 재설계는 이전 메타데이터 버전의 기본 Key:Value 형식을 유지하면서도 해당 형식을 중첩된 JSON 호환 데이터 구조로 변환하는 표준화된 메커니즘을 정의하는 보다 온건한 제안인 PEP 566을 채택하기 위해 철회되었습니다.

이 PEP(또는 관련 PEP 459)의 일부 아이디어는 이후 제안의 일부로 여전히 고려될 수 있지만, 실행 가능한 마이그레이션 계획 없이 하나의 대규모 제안으로 처리하는 대신 보다 점진적인 방식으로 다루게 됩니다.

초록

이 PEP는 파이썬 배포 패키지와 관련된 메타데이터를 게시하고 교환하는 메커니즘을 설명합니다. 여기에는 필드 이름과 그 의미 및 사용법에 관한 구체적인 내용이 포함됩니다.

이 문서는 메타데이터 형식의 출시된 적 없는 버전 2.0을 규정합니다.

버전 1.0은 PEP 241에 규정되어 있습니다. 버전 1.1은 PEP 314에 규정되어 있습니다. 버전 1.2는 PEP 345에 규정되어 있습니다.

메타데이터 형식의 버전 2.0은 사용자 지정 키-값 파일 형식을 직접 정의하는 방식에서 벗어나, API 및 아카이브 형식 정의와 같은 다른 컨텍스트에서 메타데이터 표현을 정의하는 데 사용할 수 있는 JSON 호환 메모리 내 표현을 대신 정의하는 방식으로의 마이그레이션을 제안했습니다.

이 버전은 또한 핵심 메타데이터 형식을 업데이트하지 않고도 특정 목적을 위한 새 필드를 추가할 수 있도록 공식 확장 메커니즘을 정의합니다.

PEP 기록에 관한 참고

이 PEP는 distutils-sig가 여러 다른 변경 작업을 진행함에 따라 2013년 12월부터 2017년 3월까지 장기간 처음 연기되었습니다. 이러한 변경 작업에는 다음이 포함됩니다:

  • 바이너리 호환성 태그 형식을 PEP 425에서 정의합니다.
  • 바이너리 아카이브 형식 (wheel)을 PEP 427에서 정의합니다.
  • 버전 관리와 버전 비교를 PEP 440에서 명시적으로 정의합니다.
  • PyPI “simple” API를 PEP 503에서 명시적으로 정의합니다.
  • 의존성 지정자와 extras 시스템을 PEP 508에서 명시적으로 정의합니다.
  • 정적 빌드 시스템 의존성(pyproject.toml)을 PEP 518에서 선언합니다.
  • PyPI 호스팅을 Rackspace로 이전하고 Fastly CDN 뒤에 배치하는 작업
  • CPython에 기본적으로 pip를 포함하여 제공하고, 해당 추가 사항을 Python 2.7에 백포트했습니다(PEP 453PEP 477에서).
  • 파이썬 패키징 생태계 문서에 대한 공통 접근 지점으로 packaging.python.org를 확립하는 작업
  • 패키징 관련 PEP를 추적하는 중앙 위치로 packaging.python.org의 specifications 섹션을 사용하는 방식으로 이전하는 작업

이러한 변경을 추진하는 데 소요된 시간은 어떤 메타데이터 형식 변경이 실제로 바람직한지, 또 어떤 변경을 단지 “변경을 위한 변경”으로서 개정된 사양에서 생략할 수 있는지에 대한 추가적인 관점을 제공했습니다.

또한 소프트웨어를 게시하고 배포하는 핵심 활동에 중요하지 않은 여러 기능을 PEP 459로 분리할 수 있게 했습니다. 이는 릴리스에 대한 추가적인 선택적 정보를 제공하는 여러 표준 메타데이터 확장을 제안하는 별도의 제안입니다.

2017년 9월 기준으로, 특별히 시급한 문제를 실제로 해결하는 데 도움이 되지 않는다는 이유로 다시 연기되었습니다:

  • JSON 표현은 기존 메타데이터 1.2 필드의 변환을 정의하는 방식으로 처리하는 것이 더 적절합니다.
  • 지난 몇 년 동안 정의된 추가 필드와 사양 관리 프로세스의 관련 변경 사항에 대한 명확화는 minor spec version update에서 다루는 것이 더 적절합니다.

마지막으로 이 PEP는 보다 점진적인 전략을 추구하는 PEP 566을 채택하기 위해 2018년 2월에 철회되었습니다.

목적

이 PEP의 목적은 Python 생태계에서 소프트웨어 공개 도구와 소프트웨어 통합 도구 간의 통신을 위한 공통 메타데이터 교환 형식을 정의하는 것입니다. 주요 목표 중 하나는 분석을 수행하는 사람이 임의의 Python 코드를 실행하지 않고도 해당 생태계에서 전체 의존성 분석을 지원하는 것입니다. 또 다른 목표는 Python 패키지 색인의 기존 사용자 거의 모두(게시자와 통합자 모두)의 현재 관행을 계속 지원하면서, 기본적으로 올바른 소프트웨어 배포 관행을 장려하는 것입니다. 마지막으로, 최종 사용자에게 투명한 방식으로 현재 사용 중인 메타데이터 형식에서 업그레이드할 수 있는 경로를 지원하는 것이 목표입니다.

이 설계는 Python 커뮤니티가 distutils 기반 소프트웨어 배포에서 쌓아 온 거의 20년간의 경험을 바탕으로 하며, Python의 setuptools, pip 및 기타 프로젝트, Ruby의 gems, Perl의 CPAN, Node.js의 npm, PHP의 composer, RPM과 APT 같은 Linux 패키징 시스템을 비롯한 다른 배포 시스템의 아이디어와 개념을 통합합니다.

이 형식의 세부 사항은 Python 생태계를 대상으로 하지만, 일부 아이디어는 앞으로 다른 의존성 관리 생태계의 발전에도 유용할 수 있습니다.

Python 소프트웨어의 개발, 배포 및 전개

이 PEP의 메타데이터 설계는 소프트웨어 개발 및 배포 프로세스에 대한 특정 개념적 모델을 기반으로 합니다. 이 모델은 다음 단계로 구성됩니다.

  • 소프트웨어 개발: 이 단계에서는 특정 애플리케이션의 소스 체크아웃을 사용하여 기능을 추가하고 버그를 수정합니다. 이 단계의 개발자는 소프트웨어를 빌드하고, 소프트웨어의 자동화된 테스트 모음을 실행하며, 프로젝트별 유틸리티 스크립트를 실행하고, 소프트웨어를 공개할 수 있어야 합니다.
  • 소프트웨어 공개: 이 단계에서는 개발된 소프트웨어를 가져와 소프트웨어 통합자가 사용할 수 있도록 합니다. 여기에는 이 PEP에서 정의한 설명 메타데이터를 생성하는 작업과 소프트웨어를 사용할 수 있도록 하는 작업(일반적으로 색인 서버에 업로드하는 작업)이 포함됩니다.
  • 소프트웨어 통합: 이 단계에서는 공개된 소프트웨어 구성 요소를 가져와 일관되고 통합된 시스템으로 결합합니다. 이는 Python에 특화된 크로스 플랫폼 도구를 직접 사용하여 수행할 수도 있고, 개발 언어에 중립적인 플랫폼별 패키징 시스템으로 변환하여 처리할 수도 있습니다.
  • 소프트웨어 전개: 이 단계에서는 통합된 소프트웨어 구성 요소를 가져와 소프트웨어가 실제로 실행될 대상 시스템에 전개합니다.

공개 단계와 통합 단계는 collectively 배포 단계라고 하며, 해당 단계에서 배포되는 개별 소프트웨어 구성 요소는 공식적으로 “배포 패키지”라고 하지만, 일반적으로는 단순히 “패키지”라고 부릅니다(문맥을 통해 이를 “하위 모듈이 있는 모듈” 종류의 Python 패키지와 구분합니다).

이러한 단계의 정확한 세부 사항은 특정 사용 사례에 따라 크게 달라집니다. 공개 Platform-as-a-Service 제공자에 웹 애플리케이션을 전개하는 경우, 웹 프레임워크나 과학 라이브러리의 새 릴리스를 공개하는 경우, 통합된 Linux 배포판을 만드는 경우, 보안 엔클레이브에서 실행되는 사용자 지정 애플리케이션을 업그레이드하는 경우는 모두 이 메타데이터 설계가 처리할 수 있어야 하는 상황입니다.

따라서 이 PEP에서 설명하는 메타데이터의 복잡성은 광범위한 시나리오에서 소프트웨어 개발, 배포 및 전개와 관련된 실제 복잡성에서 직접 비롯됩니다.

지원 정의

이 문서에서 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY” 및 “OPTIONAL”이라는 핵심 단어는 RFC 2119에 설명된 대로 해석해야 합니다.

“프로젝트”는 통합에 사용할 수 있도록 제공되는 소프트웨어 구성 요소입니다. 프로젝트에는 Python 라이브러리, 프레임워크, 스크립트, 플러그인, 애플리케이션, 데이터 또는 기타 리소스의 모음과 이들의 다양한 조합이 포함됩니다. 공개 Python 프로젝트는 일반적으로 Python Package Index에 등록됩니다.

“릴리스”는 프로젝트를 고유하게 식별할 수 있는 스냅샷입니다.

“배포 패키지”는 릴리스를 공개하고 배포하는 데 사용되는 패키지 파일입니다.

문맥에 따라 “패키지”는 배포판을 의미하거나, __path__ 특성을 가지므로 가져올 수 있는 하위 모듈도 가질 수 있는 가져오기 가능한 Python 모듈을 의미할 수 있습니다.

“소스 아카이브”와 “VCS 체크아웃”은 모두 sdist 또는 바이너리 아카이브를 만들기 전 릴리스의 원시 소스 코드를 의미합니다.

“sdist”는 배포 메타데이터와 해당 배포판의 바이너리 아카이브를 만드는 데 필수적인 소스 파일을 제공하는 공개 형식입니다. sdist에서 바이너리 아카이브를 만들려면 적절한 빌드 도구를 시스템에서 사용할 수 있어야 합니다.

“바이너리 아카이브”는 미리 빌드된 파일을 대상 시스템의 올바른 위치로 옮기기만 하면 됩니다. Python은 동적 바인딩을 사용하는 크로스 플랫폼 언어이므로, 소위 “바이너리” 아카이브 중 다수는 순수 Python 소스 코드만 포함합니다.

“기여자”는 소프트웨어 구성 요소를 함께 개발하는 개인과 조직을 의미합니다.

“게시자”는 소프트웨어 구성 요소를 통합에 사용할 수 있도록 제공하는 개인과 조직을 의미합니다(일반적으로 배포물을 색인 서버에 업로드합니다).

“통합자”는 게시된 배포물을 애플리케이션이나 더 큰 시스템의 구성 요소로 통합하는 개인과 조직을 의미합니다.

“빌드 도구”는 개발 시스템에서 실행되어 소스 및 바이너리 배포 아카이브를 생성하도록 설계된 자동화 도구입니다. 빌드 도구는 미리 빌드된 바이너리 아카이브가 아니라 sdist로 배포되는 소프트웨어를 빌드하기 위해 통합 도구에 의해 호출될 수도 있습니다.

“색인 서버”는 버전 및 의존성 메타데이터를 게시하고 허용되는 메타데이터에 제약을 설정하는 활성 배포 레지스트리입니다.

“공개 색인 서버”는 신뢰할 수 없는 제3자의 배포물 업로드를 허용하는 색인 서버입니다. Python Package Index는 공개 색인 서버입니다.

“게시 도구”는 개발 시스템에서 실행되어 소스 및 바이너리 배포 아카이브를 색인 서버에 업로드하도록 설계된 자동화 도구입니다.

“통합 도구”는 색인 서버나 기타 지정된 소스가 게시한 메타데이터와 배포 아카이브를 소비하고, 이를 설치하거나 플랫폼별 패키징 형식으로 변환하는 등의 방식으로 활용하는 자동화 도구입니다.

“설치 도구”는 배포 대상에서 실행되도록 특별히 설계된 통합 도구로, 색인 서버나 기타 지정된 위치에서 소스 및 바이너리 배포 아카이브를 가져와 대상 시스템에 배포합니다.

“자동화 도구”는 빌드 도구, 색인 서버, 게시 도구, 통합 도구 및 배포물의 버전과 의존성 메타데이터를 생성하거나 소비하는 기타 모든 소프트웨어를 포괄하는 집합적 용어입니다.

“레거시 메타데이터”는 이 메타데이터 사양의 이전 버전과 setuptools 프로젝트에서 정의한 지원 메타데이터 파일 형식을 의미합니다.

“Distro”는 Linux 배포판을 지칭하는 기본 용어로 사용되며, Python에 특화된 “배포 패키지”라는 용어와의 혼동을 피하는 데 도움이 됩니다.

“정규화된 이름”은 점으로 구분된 Python 식별자입니다. 가져온 모듈과 패키지의 경우 정규화된 이름은 __name__ 특성으로 사용할 수 있고, 함수와 클래스의 경우 __qualname__ 특성으로 사용할 수 있습니다.

“완전 정규화된 이름”은 Python 모듈 네임스페이스에서 객체의 위치를 고유하게 지정합니다. 가져온 모듈과 패키지의 경우 이는 정규화된 이름과 같습니다. 그 밖의 Python 객체의 경우 완전 정규화된 이름은 포함하는 모듈 또는 패키지의 정규화된 이름, 콜론(:), 그리고 포함하는 모듈 또는 패키지를 기준으로 한 객체의 정규화된 이름으로 구성됩니다.

“접두사 이름”은 정규화된 이름으로 시작하지만 반드시 정규화된 이름인 것은 아니며, 유효한 식별자가 아닌 점으로 구분된 추가 세그먼트를 포함할 수 있습니다.

배포물의 통합 및 배포

배포 메타데이터의 주된 목적은 더 큰 애플리케이션과 시스템의 일부로서 배포물을 통합하고 배포하는 일을 지원하는 것입니다.

통합과 배포는 다시 여러 하위 단계로 나눌 수 있습니다.

  • 빌드: 빌드 단계는 VCS 체크아웃, 소스 아카이브 또는 sdist를 바이너리 아카이브로 변환하는 과정입니다. 배포물의 바이너리 아카이브를 빌드하고 생성하려면 의존성을 사용할 수 있어야 합니다(대상 시스템에 설치되는 모든 문서를 포함합니다).
  • 설치: 설치 단계에서는 배포물과 모든 런타임 의존성을 대상 시스템에 가져옵니다. 이 단계에서 배포물은 시스템에 이미 존재할 수도 있고(업그레이드하거나 다시 설치하는 경우), 그렇지 않으면 완전히 새로 설치될 수도 있습니다.
  • 런타임: 대상 시스템에 설치된 후 배포물을 일반적으로 사용하는 단계입니다.

이 세 단계는 모두 대상 시스템에서 직접 수행될 수 있습니다. 또는 배포판 게시자가 제공하는 바이너리 아카이브를 사용하거나, 배포 전에 별도의 시스템에서 바이너리 아카이브를 생성하여 빌드 단계를 분리할 수 있습니다. 후자의 접근 방식은 배포 대상에 설치해야 하는 의존성을 최소화한다는 장점이 있습니다(빌드 의존성은 빌드 시스템에서만 필요하기 때문입니다).

배포 패키지에 게시된 메타데이터는 빌드 및 통합 도구의 도움을 받아 통합자가 다음을 수행할 수 있도록 해야 합니다:

  • 배포판을 생성하는 데 사용된 원본 소스 코드를 얻기
  • 배포판을 사용하는 데 필요한 의존성(있는 경우)을 식별하고 가져오기
  • 소스에서 배포판을 빌드하는 데 필요한 의존성(있는 경우)을 식별하고 가져오기
  • 배포판의 테스트 모음을 실행하는 데 필요한 의존성(있는 경우)을 식별하고 가져오기

배포판의 개발 및 게시

배포판 메타데이터의 두 번째 목적은 개발 단계에서 소프트웨어 기여자와 게시자 간의 효과적인 협업을 지원하는 것입니다.

배포판에 게시된 메타데이터는 빌드 및 게시 도구의 도움을 받아 기여자와 게시자가 다음을 수행할 수 있도록 해야 합니다:

  • 배포판을 효과적으로 통합하고 배포하는 데 필요한 모든 동일한 활동을 수행하기
  • 배포판을 개발하고 게시하는 데 필요한 추가 의존성을 식별하고 가져오기
  • 배포판을 사용하는 데 필요한 의존성(있는 경우)을 지정하기
  • 소스에서 배포판을 빌드하는 데 필요한 의존성(있는 경우)을 지정하기
  • 배포판의 테스트 모음을 실행하는 데 필요한 의존성(있는 경우)을 지정하기
  • 배포판을 개발하고 게시하는 데 필요한 추가 의존성(있는 경우)을 지정하기

메타데이터 형식

이 PEP에서 정의하는 형식은 문자열 키 딕셔너리로 표현되는 Python 배포판 메타데이터의 메모리 내 표현입니다. 개별 항목에 허용되는 값은 문자열, 문자열 목록 및 추가적인 중첩 문자열 키 딕셔너리입니다.

달리 명시된 경우를 제외하면, 배포판 메타데이터의 딕셔너리 키는 특성 기반 메타데이터 액세스 API를 지원하기 위해 유효한 Python 식별자여야 합니다.

개별 필드 설명에는 JSON 매핑의 일부로 직렬화될 때의 키 이름과 값의 예가 표시됩니다.

달리 표시되지 않는 한, 핵심 메타데이터로 식별된 필드는 필수입니다. 자동화 도구는 핵심 메타데이터가 누락된 배포판을 유효한 Python 배포판으로 허용해서는 안 됩니다.

그 밖의 모든 필드는 선택 사항입니다. 자동화 도구는 배포판이 해당 필드를 제공하지 않더라도 올바르게 작동해야 합니다. 단, 생략된 필드를 특별히 요구하는 작업은 예외입니다.

자동화 도구는 누락된 필드에 더미 데이터를 삽입해서는 안 됩니다. 필수 필드에 유효한 값이 제공되지 않으면 메타데이터와 관련 배포판을 유효하지 않은 것으로 거부해야 합니다. 선택 필드에 유효한 값이 제공되지 않으면 해당 필드를 완전히 생략해야 합니다. 자동화 도구는 다른 정보 출처(예: 버전 관리 시스템)에서 유효한 값을 자동으로 도출할 수 있습니다.

자동화 도구, 특히 공개 패키지 색인 서버는 이 PEP에 열거된 제한을 넘어 메타데이터 길이에 추가 제한을 부과할 수 있습니다. 이러한 제한은 사용 가능한 리소스와 합리적인 메타데이터 용량 요구 사항에 대한 서비스 제공자의 판단을 바탕으로 서비스의 무결성을 보호하는 데 필요한 경우 부과해야 합니다.

메타데이터 파일

이 PEP에 정의된 정보는 일부 사용 사례에서 pysdist.json 파일로 직렬화됩니다. 이는 UTF-8로 인코딩된 JSON 메타데이터를 포함하는 파일입니다.

각 메타데이터 파일은 이 PEP에 설명된 필드를 포함하는 단일 직렬화된 매핑으로 구성됩니다. 메타데이터를 직렬화할 때 자동화 도구는 변경 사항을 쉽게 검토할 수 있도록 모든 키와 목록 요소를 사전순으로 정렬해야 합니다.

이러한 메타데이터 파일에는 다음 세 가지 표준 위치가 사용될 것으로 예상됩니다.

  • {distribution}-{version}.dist-info/pysdist.json 파일로 sdist 소스 배포 아카이브에 저장됩니다.
  • {distribution}-{version}.dist-info/pysdist.json 파일로 wheel 바이너리 배포 아카이브에 저장됩니다.
  • {distribution}-{version}.dist-info/pysdist.json 파일로 로컬 Python 설치 데이터베이스에 저장됩니다.

이 파일은 세 위치 모두에서 동일해야 합니다. 소스 트리에서 소스 아카이브 또는 바이너리 아카이브를 생성할 때 만들어진 다음, 설치할 때 또는 소스 아카이브에서 바이너리 아카이브를 빌드할 때 변경되지 않은 상태로 보존됩니다.

Note

이러한 위치는 sdist 2.0의 정의와 개정된 설치 데이터베이스 표준에 따라 달라지므로 확정되어야 합니다. 또한 이 PEP가 승인된 후에는 2.0 이상 메타데이터 제공을 의무화하는 wheel 1.1 형식 업데이트가 이루어질 예정입니다.

이러한 메타데이터 파일은 포함된 위치의 버전이 해당 파일이 유효함을 나타내기에는 너무 낮더라도 처리될 수 있다는 점에 유의하십시오. 구체적으로, 버전이 지정되지 않은 sdist 아카이브, 버전이 지정되지 않은 설치 데이터베이스 디렉터리 및 wheel 사양 버전 1.0에서도 pysdist.json 파일을 제공할 수 있습니다.

Note

이 사양이 정식으로 Active로 표시될 때까지는 초안 형식을 따르는 도구가 최종적으로 표준화될 파일과 충돌하지 않도록 metadata.json 또는 pep426-20131213.json과 같은 대체 파일 이름을 사용하는 것이 좋습니다.

Python 배포와 관련된 다른 도구에서도 이 형식을 사용할 수 있습니다.

이러한 메타데이터 파일은 데이터 입력 형식으로 직접 사용되는 것이 아니라 setup.pypyproject.toml과 같은 다른 입력 형식을 기반으로 빌드 도구가 생성한다는 점에 유의하십시오. 게시 프로세스의 일부로 메타데이터를 생성하면 소스 URL과 버전 필드 자체를 포함한 버전별 필드도 처리하는 데 도움이 됩니다.

이전 설치 도구와의 하위 호환성을 위해 메타데이터 2.0 파일은 레거시 메타데이터와 함께 배포될 수 있습니다.

패키지 색인 서버는 레거시 메타데이터만 포함된 배포 패키지의 업로드를 허용할 수 있으며, 설치 도구는 레거시 메타데이터만 포함된 배포 패키지의 설치를 허용할 수 있습니다.

자동화 도구는 레거시 메타데이터를 이 PEP에 설명된 형식으로 자동 변환하려고 시도할 수 있습니다. 이를 효과적으로 수행하기 위한 지침은 부록 A에 제시되어 있습니다.

메타데이터 검증

배포 메타데이터에 대한 jsonschema 설명은 available에서 확인할 수 있습니다.

이 스키마는 현재 더 복잡한 문자열 필드 중 일부의 유효성 검사를 처리하지 않으며, 대신 해당 필드를 불투명한 문자열로 취급합니다.

달리 명시된 경우를 제외하고 메타데이터의 모든 URL 필드는 RFC 3986을 준수해야 합니다.

Note

현재 버전의 스키마 파일은 PEP의 이전 초안을 다루며, 필수 종속성 해결 메타데이터와 여러 표준 확장으로 분할된 현재 구조에 맞게 아직 업데이트되지 않았습니다. 또한 현재 초안과 이전 초안 사이의 여러 다른 차이도 아직 반영하지 않았습니다.

핵심 메타데이터

이 절에서는 모든 Python 배포에 필요한 핵심 메타데이터 필드를 지정합니다.

게시 도구는 배포 패키지를 게시할 때 적어도 이러한 필드가 포함되도록 보장해야 합니다.

색인 서버는 배포 패키지가 업로드될 때 메타데이터에 적어도 이러한 필드가 포함되도록 보장해야 합니다.

설치 도구는 기본적으로 이러한 필드 중 하나 이상이 누락된 배포 패키지의 설치를 거부해야 하지만, 사용자가 이러한 설치를 강제로 수행하도록 허용할 수 있습니다.

메타데이터 버전

파일 형식의 버전이며, "2.0"만 유효한 값입니다.

메타데이터를 사용하는 자동화 도구는 metadata_version이 지원하는 최고 버전보다 높으면 경고해야 하며, metadata_version의 주 버전이 지원하는 최고 버전의 주 버전보다 높으면 반드시 실패해야 합니다( PEP 440에 설명된 대로 주 버전은 첫 번째 점 앞의 값입니다).

더 폭넓은 호환성을 위해 빌드 도구는 필요한 모든 필드를 포함하는 가장 낮은 메타데이터 버전을 사용하여 배포 메타데이터를 생성할 수 있습니다.

예제:

"metadata_version": "2.0"

제너레이터

파일을 생성한 프로그램의 이름(및 선택적 버전)입니다(해당하는 경우). 수동으로 생성한 파일에서는 이 필드를 생략합니다.

예제:

"generator": "flit"
"generator": "setuptools (34.3.1)"

이름

배포 패키지의 이름은 PEP 508에 정의되어 있습니다.

배포 이름은 URL, 파일 이름, 명령줄 매개변수의 일부로 사용되며 다른 패키징 시스템과도 상호 운용되어야 하므로 허용되는 문자는 다음과 같이 제한됩니다.

  • ASCII 문자([a-zA-Z])
  • ASCII 숫자([0-9])
  • 밑줄(_)
  • 하이픈(-)
  • 마침표(.)

배포 이름은 ASCII 문자 또는 숫자로 시작하고 끝나야 합니다.

자동화 도구는 규정을 준수하지 않는 이름을 반드시 거부해야 합니다. 이러한 제약을 강제하기 위한 정규 표현식은 re.IGNORECASE로 실행할 때 다음과 같습니다.:

^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$

배포 이름의 모든 비교는 대소문자를 구분하지 않아야 하며, 하이픈과 밑줄을 동등한 것으로 간주해야 합니다.

색인 서버는 Unicode Consortium이 TR39: Unicode Security Mechanisms에서 정의한 “혼동 가능한” 문자를 동등한 것으로 간주할 수 있습니다.

신뢰할 수 없는 출처에서 임의의 배포 이름 등록을 허용하는 색인 서버는 새 배포를 등록할 때 혼동 가능한 문자를 동등한 것으로 간주해야 하며, 따라서 중복으로 거부해야 합니다.

통합 도구는 혼동 가능한 대체 철자가 요청된 배포 이름과 일치하는 것으로 조용히 받아들여서는 안 됩니다.

작성 시점을 기준으로 Unicode Consortium이 혼동 가능한 문자로 지정한 ASCII 부분 집합의 문자는 다음과 같습니다.

  • 1 (DIGIT ONE), l (LATIN SMALL LETTER L), I (LATIN CAPITAL LETTER I)
  • 0 (DIGIT ZERO), O (LATIN CAPITAL LETTER O)

예제:

"name": "ComfyChair"

버전

배포 패키지의 공개 또는 로컬 버전 식별자는 PEP 440에 정의되어 있습니다. 버전 식별자는 자동화 도구에서 사용하도록 설계되었으며 다양한 유연한 버전 지정 메커니즘을 지원합니다(PEP 440에 자세한 내용이 있습니다).

버전 식별자는 PEP 440에 정의된 형식을 반드시 준수해야 합니다.

버전 식별자는 각 프로젝트 내에서 고유해야 합니다.

패키지 색인 서버는 PEP 440에 설명된 대로 로컬 버전 식별자의 사용을 제한할 수 있습니다.

예제:

"version": "1.0a2"

요약

해당 배포 패키지가 수행하는 작업에 대한 간단한 요약입니다.

이 필드는 512자 미만이어야 하며 2048자 미만이어야 합니다.

이 필드에는 줄바꿈이 포함되지 않아야 합니다.

더 완전한 설명은 해당 배포 패키지의 sdist에 별도의 파일로 포함되어야 합니다. 자세한 내용은 PEP 459python-details 확장을 참조하십시오.

예제:

"summary": "A module that is more fiendish than soft cushions."

소스 코드 메타데이터

이 절에서는 이 배포 패키지를 생성하는 데 사용된 소스 코드의 식별 세부 정보를 제공하는 필드를 지정합니다.

이러한 필드는 모두 선택 사항입니다. 배포 패키지가 이러한 필드를 제공하지 않는 경우에도 자동화 도구는 올바르게 작동해야 하며, 이러한 필드 중 하나에 의존하는 작업이 요청될 때 정상적으로 실패해야 합니다.

소스 레이블

소스 레이블은 정의된 의미가 최소한인 텍스트 문자열입니다. 이는 통합자가 특정 배포 패키지에 추가적인 로컬 수정 사항을 적용한 경우에도 원본 소스 코드를 모호하지 않게 식별할 수 있도록 하기 위한 것입니다.

소스 레이블을 파일 이름과 URL의 일부로 쉽게 포함하고 16진수 해시 표현의 형식 불일치를 방지하려면, 소스 레이블은 다음 허용 문자 집합으로 제한되어야 합니다:

  • 소문자 ASCII 문자([a-z])
  • ASCII 숫자([0-9])
  • 밑줄(_)
  • 하이픈(-)
  • 마침표(.)
  • 더하기 기호(+)

소스 레이블은 ASCII 문자 또는 숫자로 시작하고 끝나야 합니다.

이러한 제약을 강제하는 정규 표현식은 re.IGNORECASE와 함께 실행할 때 다음과 같습니다.:

^([A-Z0-9]|[A-Z0-9][A-Z0-9._-+]*[A-Z0-9])$

프로젝트의 소스 레이블은 해당 프로젝트에 대해 정의된 어떤 버전과도 일치해서는 안 됩니다. 이 제한은 버전 식별자와 소스 레이블 사이에 모호성이 없도록 합니다.

예제:

"source_label": "1.0.0-alpha.1"

"source_label": "1.3.7+build.11.e0f985a"

"source_label": "v1.8.1.301.ga0df26f"

"source_label": "2013.02.17.dev123"

소스 URL

이 특정 버전의 배포 패키지에 대한 소스를 다운로드할 수 있는 전체 URL을 포함하는 문자열입니다.

소스 URL은 각 프로젝트 내에서 고유해야 합니다. 이는 URL이 "https://github.com/pypa/pip/archive/main.zip"같은 형식이어서는 안 되고, 대신 "https://github.com/pypa/pip/archive/1.3.1.zip"같은 형식이어야 한다는 의미입니다.

소스 URL은 적합한 VCS 체크아웃 생성을 허용하는 온라인 버전 관리 시스템의 소스 아카이브, 태그 또는 특정 커밋을 참조해야 합니다. 이는 주로 원본 소스 형식에서 배포본을 재생성하려는 통합자를 위한 것입니다.

모든 소스 URL 참조는 보안 전송 메커니즘(예: https)을 지정하고, 검증을 위해 URL에 예상 해시 값을 포함해야 합니다. 소스 URL이 해시 정보 없이 지정되었거나, 도구가 이해하지 못하는 해시 정보와 함께 지정되었거나, 도구가 신뢰하기에 너무 약하다고 판단하는 해시 알고리즘이 선택된 경우, 자동화 도구는 최소한 경고를 출력해야 하며 URL에 의존하지 않을 수 있습니다. 이러한 소스 URL이 안전하지 않은 전송도 사용하는 경우, 자동화 도구는 URL에 의존해서는 안 됩니다.

소스 아카이브 참조의 경우, URL 프래그먼트의 일부로 <hash-algorithm>=<expected-hash> 항목을 포함하여 예상 해시 값을 지정할 수 있습니다.

2017년 현재 소스 URL에는 'sha256' 해시를 사용하는 것이 권장됩니다. 이는 이 해시가 아직 악의적인 충돌 생성에 취약하다고 알려지지 않았으며 클라이언트 시스템에서 널리 사용 가능하기 때문입니다.

버전 관리 참조에는 버전 관리 시스템과 보안 전송을 모두 식별하기 위해 VCS+protocol 스킴을 사용해야 하며, 해시 기반 커밋 식별자를 사용하는 버전 관리 시스템을 사용해야 합니다. 자동화 도구는 해시 기반 커밋 식별자를 제공하지 않는 버전 관리 시스템에 대해서는 해시 누락 경고를 생략할 수 있습니다.

커밋 또는 태그 참조를 URL에 직접 포함하는 기능을 지원하지 않는 버전 관리 시스템을 처리하기 위해, 해당 정보를 @<commit-hash> 또는 @<tag>#<commit-hash> 표기법을 사용하여 URL 끝에 추가할 수 있습니다.

Note

이는 pip가 지원하는 기존 VCS 참조 표기법과 완전히 같지는 않습니다. 첫째, 배포 이름은 URL의 일부로 삽입되는 대신 별도의 필드입니다. 둘째, 태그를 기준으로 가져오는 경우에도 커밋 해시가 포함됩니다. 이는 위의 요구 사항, 즉 위조를 어렵게 만들기 위해 모든 링크에 해시를 포함해야 한다는 요구 사항을 충족하기 위한 것입니다(특정 태그를 가진 악성 저장소를 만드는 것은 쉽지만, 특정 해시를 가진 저장소를 만드는 것은 그보다 어렵습니다).

예시:

"source_url": "https://github.com/pypa/pip/archive/1.3.1.zip#sha256=2dc6b5a470a1bde68946f263f1af1515a2574a150a30d6ce02c6ff742fcc0db8
"source_url": "git+https://github.com/pypa/pip.git@1.3.1#7921be1537eac1e97bc40179a57f0349c2aee67d"
"source_url": "git+https://github.com/pypa/pip.git@7921be1537eac1e97bc40179a57f0349c2aee67d"

의미적 의존성

의존성 메타데이터를 사용하면 게시된 프로젝트가 특정 릴리스의 사본을 함께 묶지 않고도 다른 게시된 프로젝트가 제공하는 기능을 사용할 수 있습니다.

의미적 의존성을 사용하면 게시자는 어떤 다른 프로젝트가 필요한지뿐만 아니라 필요한지도 나타낼 수 있습니다. 이 추가 정보 덕분에 통합자는 특정 활동에 필요한 의존성만 설치할 수 있으며, 제약된 환경에서 설치 공간을 최소화하기가 쉬워집니다(그러한 제약의 이유와 관계없이).

기본적으로 의존성 선언은 “런타임 의존성”, 즉 게시된 릴리스를 실제로 사용하는 데 필요한 다른 릴리스를 의미하는 것으로 간주됩니다.

릴리스가 선언할 수 있는 선택적 의존성에는 네 가지 종류도 있습니다.

  • test 의존성: 이 릴리스의 자동화된 테스트 모음을 실행하는 데 필요하지만, 릴리스를 사용하기만 할 때는 필요하지 않은 다른 릴리스입니다(예: nose2 또는 pytest).
  • build 의존성: 소스에서 이 릴리스의 배포 가능한 바이너리 버전을 빌드하는 데 필요한 다른 릴리스입니다(예: flit 또는 setuptools).
  • doc 의존성: 이 배포본의 문서를 빌드하는 데 필요한 다른 릴리스입니다(예: sphinx 빌드 도구).
  • dev 의존성: 이 배포본을 작업할 때 필요한 다른 릴리스이지만, 다른 선택적 의존성 범주 중 정확히 하나에 해당하지 않는 의존성입니다(예: pylint, flake8). dev 의존성은 세 번 나열할 필요 없이 사실상 test, builddoc 의존성을 결합한 것으로도 간주됩니다.

이러한 선택적 범주는 Extras라고 합니다. 네 가지 표준 범주 외에도 프로젝트는 Extras 필드에서 자체적인 사용자 지정 범주를 선언할 수 있습니다.

다른 엑스트라에 대한 의존성을 암시하는 표준 엑스트라 범주도 두 가지 있습니다.

  • alldev: test, build, doc, dev 엑스트라를 암시합니다.
  • all: 달리 정의되지 않은 경우 선언된 모든 엑스트라를 암시합니다.

의존성 관리는 PEP 440에 정의된 버전 식별 및 지정 스킴과 PEP 508에 정의된 의존성 지정, 엑스트라 및 환경 마커 스킴에 크게 의존합니다.

이 모든 필드는 선택 사항입니다. 배포가 해당 필드를 제공하지 않는 경우, 자동화 도구는 누락된 필드가 “이 배포에 적용되지 않음”을 의미한다고 가정하여 올바르게 작동해야 합니다.

개발 및 배포 활동에 의존성 매핑

의존성의 여러 범주는 앞에서 식별한 다양한 배포 및 개발 활동을 기반으로 하며, 지정된 활동에 설치해야 하는 의존성을 결정합니다.

  • 필수 런타임 의존성:
    • 무조건적 의존성
  • 필수 빌드 의존성:
    • build 추가 기능
    • dev 추가 기능
    • 빌드 프로세스의 일부로 배포의 테스트 모음을 실행하는 경우, 무조건적 의존성과 test 추가 기능도 설치하십시오.
  • 필수 개발 및 게시 의존성:
    • 무조건적 의존성
    • test 추가 기능
    • build 추가 기능
    • doc 추가 기능
    • dev 추가 기능

다양한 작업에 정확히 무엇을 설치할지 결정하려면 Extras (optional dependencies)에 설명된 표기법을 사용해야 합니다.

설치 도구는 의존성을 충족할 수 없는 경우 오류를 보고해야 하고, 최소한 경고를 내보내야 하며, 사용자가 이에 관계없이 설치를 진행하도록 강제할 수 있도록 허용할 수도 있습니다.

이러한 의존성을 RPM spec 파일에 매핑하는 개요는 부록 B를 참조하십시오.

추가 기능

의존성 필드에서 조건부 의존성을 정의하는 데 사용할 수 있는 선택적 의존성 집합의 목록입니다. 자세한 내용은 Extras (optional dependencies)를 참조하십시오.

추가 기능의 이름은 배포 이름에 적용되는 것과 동일한 제한을 준수해야 합니다.

다음 추가 기능 이름은 기본적으로 사용할 수 있으며 이 필드에 명시적으로 선언해서는 안 됩니다.

  • all
  • alldev
  • build
  • dev
  • doc
  • test

예시:

"extras": ["warmup", "tea"]

의존성

이 릴리스를 실제로 실행하는 데 필요한 릴리스 요구 사항 목록입니다.

공개 색인 서버는 이 필드에서 엄격한 버전 일치 절이나 직접 참조를 금지할 수 있습니다.

예시입니다.:

"dependencies":
  {
    "requires": ["SciPy", "PasteDeploy", "zope.interface > 3.5.0"]
  },
  {
    "requires": ["pywin32 > 1.0"],
    "environment": "sys_platform == 'win32'"
  },
  {
    "requires": ["SoftCushions"],
    "extra": "warmup"
  }
]

프로젝트 릴리스를 사용하려면 많은 의존성이 필요하지만, 다른 의존성은 특정 플랫폼에서만 또는 릴리스의 특정 선택적 기능이 필요할 때만 필요합니다.

이를 처리하기 위해 릴리스 의존성 지정자는 다음 하위 필드를 갖는 매핑입니다.

  • requires: 의존성을 충족하는 데 필요한 요구 사항 목록입니다.
  • extra: 요청되어 함께 설치되는 선택적 의존성 집합의 이름입니다. 자세한 내용은 Extras (optional dependencies)을 참조하십시오.
  • environment: 이러한 의존성이 필요한 환경을 정의하는 환경 마커입니다. 환경 마커의 구문과 기능은 PEP 508에 정의되어 있습니다.

requires 목록의 개별 항목은 PEP 508에 정의된 의존성 선언 형식을 사용하는 문자열입니다. 단, 환경 마커는 개별 의존성 선언에 포함해서는 안 되며 별도의 environment 필드에 대신 제공해야 합니다.

requires는 필수 하위 필드 중 유일한 항목입니다. 이것이 유일한 하위 필드인 경우 해당 의존성은 무조건적이라고 합니다. extra 또는 environment가 지정된 경우 해당 의존성은 조건부입니다.

세 필드를 모두 제공할 수 있으며, 이는 특정 환경에서 명명된 extra가 요청된 경우에만 의존성이 필요함을 나타냅니다.

자동화 도구는 메타데이터를 직렬화할 때 관련 의존성 지정자(extraenvironment에 공통 값이 있는 지정자)를 여러 요구 사항을 나열하는 단일 지정자로 결합해야 합니다.

이렇게 정규화해야 하더라도 동일한 extra 이름이나 환경 마커가 여러 조건부 의존성에 나타날 수 있습니다. 예를 들어 extra 자체가 특정 환경에서만 일부 의존성을 필요로 하는 경우에 이러한 상황이 발생할 수 있습니다. 의존성 지정자 목록에서 고유해야 하는 것은 extra와 환경 마커의 조합뿐입니다.

여섯 가지 표준 extra 범주를 제외하고, 의존성 지정자에서 참조되는 모든 extra는 이 배포판의 Extras 필드에 이름이 지정되어야 합니다. 이렇게 하면 오탈자를 방지하고 전체 의존성 집합을 훑지 않고도 사용 가능한 extra를 쉽게 식별할 수 있습니다.

다른 extra의 일부로 extra 정의를 재사용하기 위해 프로젝트 릴리스는 자체적으로 의존성을 선언할 수 있습니다. 이러한 경우 무한 재귀를 방지하려면 자동화 도구가 프로젝트에서 자기 자신으로 향하는 의존성을 특별히 처리해야 합니다.

메타데이터 확장

메타데이터 확장은 extensions 키 아래의 매핑에 포함될 수 있습니다. 키는 유효한 접두사 이름이어야 하며, 값 자체는 중첩된 매핑이어야 합니다.

다음 두 키 이름은 아래에 설명된 경우를 제외하고 확장에서 사용해서는 안 됩니다.

  • extension_version
  • installer_must_handle

다음 예시는 PEP 459python.detailspython.commands 표준 확장을 보여 줍니다.:

"extensions" : {
  "python.details": {
    "license": "GPL version 3, excluding DRM provisions",
    "keywords": [
      "comfy", "chair", "cushions", "too silly", "monty python"
    ],
    "classifiers": [
      "Development Status :: 4 - Beta",
      "Environment :: Console (Text Based)",
      "License :: OSI Approved :: GNU General Public License v3 (GPLv3)"
    ],
    "document_names": {
        "description": "README.rst",
        "license": "LICENSE.rst",
        "changelog": "NEWS"
    }
  },
  "python.commands": {
    "wrap_console": [{"chair": "chair:run_cli"}],
    "wrap_gui": [{"chair-gui": "chair:run_gui"}],
    "prebuilt": ["reduniforms"]
  },
}

확장 이름은 어떤 방식으로든 추가로 게시된 메타데이터를 활용할 배포판에서 정의합니다.

이름 충돌 가능성을 줄이기 위해, 확장 기능 이름은 해당 확장 기능의 의미를 정의하는 배포 패키지의 모듈 이름에 대응하는 접두사를 사용해야 합니다. 이러한 관행은 메타데이터 확장 기능에 대한 권위 있는 문서를 더 쉽게 찾을 수 있게 합니다.

메타데이터 확장 기능을 사용하면 개발 도구가 이후 배포 단계에서 유용할 수 있는 정보를 메타데이터에 기록할 수 있지만, 종속성 해결이나 소프트웨어 빌드에 필수적인 것은 아닙니다.

확장 기능 버전 관리

확장 기능은 extension_version 키를 사용하여 버전을 지정해야 합니다. 그러나 이 키를 생략하면 암시되는 버전은 1.0입니다.

확장 기능 메타데이터를 사용하는 자동화 도구는 extension_version이 지원하는 최고 버전보다 큰 경우 경고해야 하며, extension_version의 주 버전이 지원하는 최고 버전의 주 버전보다 크면 반드시 실패해야 합니다(PEP 440에 설명된 대로 주 버전은 첫 번째 점 앞의 값입니다).

더 광범위한 호환성을 위해 빌드 도구는 필요한 모든 필드를 포함하는 가장 낮은 메타데이터 버전을 사용하여 확장 기능 메타데이터를 생성할 수 있습니다.

필수 확장 기능 처리

프로젝트에서는 일부 확장 기능을 올바르게 처리하는 것이 소프트웨어를 올바르게 설치하는 데 필수적이라고 판단할 수 있습니다. 이는 installer_must_handle 필드를 true로 설정하여 나타냅니다. 이를 false로 설정하거나 완전히 생략하면 배포 패키지를 설치할 때 확장 기능을 처리하는 것이 개발자에게 의무적인 것으로 간주되지 않음을 나타냅니다.

확장 기능에 대해 installer_must_handletrue로 설정되어 있는데 설치 도구가 해당 확장 기능을 처리할 능력이 전혀 없다면(직접 처리하든 도구별 플러그인 시스템을 통해 처리하든) 설치 도구는 반드시 실패해야 합니다.

설치 도구가 휠 아카이브에서 설치하려고 할 때 이해하지 못하는 필수 확장 기능을 만나면, 완전히 실패하는 대신 소스에서 설치를 시도하는 방식으로 대체할 수 있습니다.

Extras(선택적 종속성)

관련 PEP 508에 정의된 대로, 엑스트라는 프로젝트 릴리스의 선택적 기능을 활성화하는 추가 의존성이며, 흔히 코드의 try: import optional_dependency ... 블록에 해당합니다. 또한 일반적인 런타임 사용 이외의 활동(예: 구성 요소 테스트, 빌드 또는 작업)에 대한 의미적 종속성을 나타내는 데에도 사용됩니다.

선택적 종속성이 있는 릴리스를 사용하거나 사용하지 않을 수 있도록, 이러한 종속성은 릴리스의 핵심 런타임 종속성과 별도로 나열되며, 다른 프로젝트의 종속성 사양에서 또는 설치 도구에 명령을 발행할 때 명시적으로 요청해야 합니다.

선택적 종속성이 있는 배포 패키지의 예:

"name": "ComfyChair",
"extras": ["warmup"]
"dependencies": [
  {
    "requires": ["SoftCushions"],
    "extra": "warmup"
  },
  {
    "requires": ["cython"],
    "extra": "build"
  }
]

다른 배포 패키지는 종속성을 지정할 때 배포 패키지 이름 뒤의 대괄호 안에 관련 extra 이름을 넣어 추가 종속성을 요구합니다. 종속성에서 여러 extras를 요청하려면 다음을 배치하여

표준 all extra에 명시적으로 선언된 항목이 없으면 통합 도구는 이를 프로젝트에서 명시적으로 선언한 모든 extras에 대한 종속성으로 암시적으로 정의해야 합니다.

표준 alldev extra에 명시적으로 선언된 항목이 없으면 통합 도구는 이를 표준 test, build, docdev extras에 대한 종속성으로 암시적으로 정의해야 합니다.

그러면 전체 종속성 요구 사항 집합은 무조건적 종속성과 요청된 extras의 종속성을 함께 기반으로 합니다.

종속성 예(requires 하위 필드만 표시):

"requires": ["ComfyChair"]
    -> requires ``ComfyChair`` only

"requires": ["ComfyChair[warmup]"]
    -> requires ``ComfyChair`` and ``SoftCushions``

"requires": ["ComfyChair[all]"]
    -> requires ``ComfyChair`` and ``SoftCushions``, but will also
       pick up any new extras defined in later versions

메타데이터 사양 업데이트

메타데이터 사양은 새 PEP나 메타데이터 버전 변경 없이도 명확성을 위한 업데이트가 가능합니다.

기존 필드의 의미를 변경하거나 확장 기능 메커니즘을 통하지 않고 새 기능을 추가하려면 새 PEP에서 정의한 새 메타데이터 버전이 필요합니다.

부록 A: 레거시 메타데이터 변환 참고 사항

레거시 메타데이터를 메타데이터 2.0으로 변환하기 위한 참조 구현은 다음과 같습니다.

  • bdist_wheel 명령을 setuptools에 추가하는 wheel 프로젝트
  • 차세대 Python 패키지 색인 구현으로서 결국 Python Packaging Authority로 이전될 Warehouse 프로젝트
  • distutils2 프로젝트를 위해 구축된 핵심 패키징 인프라에서 파생된 distlib project은 프로젝트입니다.

Note

이러한 도구는 여러 필드를 표준 확장 기능으로 전환하는 작업에 맞게 아직 업데이트되지 않았습니다.

깔끔한 변환을 위해 수동 개입이 필요한 일부 특수한 경우가 있을 수 있지만, 이 사양은 PyPI의 거의 모든 프로젝트를 완전히 자동으로 변환할 수 있도록 설계되었습니다.

메타데이터 변환, 특히 인덱스 서버 측의 변환은 개발자가 더 새로운 빌드 시스템으로 업그레이드할 때까지 기다리지 않고 설치 및 분석 도구가 새로운 메타데이터 형식의 이점을 활용하기 시작할 수 있도록 하는 데 필요한 단계입니다.

부록 B: 의존성 선언을 RPM SPEC 파일에 매핑하기

이 PEP를 Linux 배포판 패키지에 매핑하는 예로, extras가 정의되지 않은 예시 프로젝트가 SPEC 파일에서 exampleexample-devel이라는 두 개의 RPM으로 분할된다고 가정하십시오.

무조건부 의존성은 “example” RPM의 Requires 의존성으로 매핑됩니다(Linux와 관련된 환경 마커를 SPEC 파일 조건으로 매핑하면 이러한 의존성도 올바르게 처리할 수 있습니다).

builddev extra 의존성은 “example” RPM의 BuildRequires 의존성으로 매핑됩니다. RPM의 %check 섹션이 정의된 방식에 따라 test extra도 RPM의 BuildRequires 선언으로 매핑될 수 있습니다.

dev, test, builddoc extras에 정의된 Linux 관련 모든 의존성은 “example-devel” RPM의 Requires 의존성이 됩니다.

Sphinx와 같은 문서 도구 체인 의존성은 build extra에 포함하거나(예를 들어 매뉴얼 페이지가 빌드된 배포판에 포함되는 경우), doc extra에 포함할 수 있습니다(예를 들어 문서가 Read the Docs 또는 프로젝트 웹사이트를 통해서만 게시되는 경우). 이렇게 하면 자동 변환기가 이를 SPEC 파일의 적절한 의존성으로 매핑할 수 있습니다.

프로젝트에 extras가 정의되어 있다면, 의존성 사양의 세부 사항에 따라 적절한 BuildRequires 및 Requires 항목을 포함하는 추가 가상 RPM으로 매핑할 수 있습니다. 또는 다른 시스템 패키지 관리자 기능(예: 약한 의존성)으로 매핑할 수도 있습니다.

메타데이터 확장 형식은 배포판별 형식으로 업스트림 메타데이터를 수동으로 중복 작성할 필요 없이 배포판별 힌트를 업스트림 프로젝트 메타데이터에 포함할 수 있는 방법도 제공해야 합니다.

부록 C: PEP 345와의 차이점 요약

  • Metadata-Version은 이제 2.0이며, 버전 변경 처리를 위한 의미론이 명시되어 있습니다.
  • 점점 더 복잡해지는 임의의 “Key: Value” 형식은 Python 딕셔너리, 문자열 및 리스트로 쉽게 표현할 수 있는 더욱 구조화된 JSON 호환 형식으로 대체되었습니다.
  • 이제 대부분의 필드는 선택 사항이며, 생략된 필드에 더미 데이터를 채우는 것은 명시적으로 허용되지 않습니다.
  • 사양의 새 버전을 릴리스하지 않고 제자리에서 명확히 설명을 추가하는 것이 명시적으로 허용되었습니다.
  • 이제 이 PEP는 허용되는 내용에 대한 단순한 설명을 제공하기보다는 필드가 존재하는 why에 대한 설명과 필드를 어떻게 사용하도록 의도되었는지에 대한 설명을 더 많이 제공하려고 합니다.
  • 버전 체계를 PEP 440에 기반하도록 변경했으며 PEP 386에 기반하지 않습니다.
  • 관련 PEP 440에 설명된 소스 레이블 메커니즘을 추가했습니다.
  • 의존성 선언, extras 및 환경 마커를 PEP 508에서 공식적으로 정의했습니다.
  • 추가 예약 extra 이름을 통해 여러 종류의 의존성을 지원합니다.
  • 오래된 항목 처리 메커니즘을 업데이트했습니다.
  • 잘 정의된 메타데이터 확장 메커니즘을 도입하고, 의존성 확인에 필요하지 않은 모든 필드를 표준 확장 기능으로 이전했습니다.
  • Charles Schulz와 Peanuts에 대한 모든 경의를 표하면서도, 많은 예제가 Python에 더 주제적으로 적합하도록 업데이트되었습니다 ;)

주요 변경 사항의 근거는 다음 절에서 제시합니다.

Metadata-Version 의미론

이제 주 버전 및 부 버전 증가의 의미론이 명시되었으며, PEP 427에서 wheel 형식에 대해 지정된 형식 버전 의미론과 동일한 모델을 따릅니다. 부 버전 증가는 주 버전이 같은 이전 메타데이터 버전만 이해하는 도구로 처리될 때 합리적으로 동작해야 하지만, 주 버전 증가는 기존 도구와 호환되지 않는 변경 사항을 포함할 수 있습니다.

이전 메타데이터 사양에 따라 PEP 426 메타데이터를 해석할 수 없음이 명백하므로, 사양의 주 버전 번호도 이에 따라 증가했습니다.

사양의 주 버전 번호가 증가할 때마다 배포에는 어느 정도 시간이 걸릴 것으로 예상합니다. 메타데이터를 소비하는 도구를 먼저 업데이트해야 다른 도구가 새 형식을 안전하게 생성하기 시작할 수 있거나, 아니면 sdist 및 wheel 형식과 설치 데이터베이스 정의를 업데이트하여 여러 버전의 메타데이터를 동시에 제공할 수 있도록 지원해야 하기 때문입니다.

기존 도구는 새 메타데이터 표준을 지원하도록 업데이트되기 전까지는 이 지침을 따르지 않으므로, 새로운 의미 체계는 먼저 가상의 2.x -> 3.0 전환에 적용됩니다. 1.x -> 2.x 전환에서는 도구가 새 표준 메타데이터 형식의 새 기능(공식 확장 메커니즘 포함)을 사용하여 지정된 동등한 파일을 생성하는 것에 더해, 기존 보조 파일(예: entry_points.txt)도 계속 생성하도록 하는 접근 방식을 사용합니다.

JSON 호환 형식으로 전환

기존의 “Key:Value” 형식은 점점 더 많은 제약을 갖게 되었으며, 파서가 어떤 필드에 둘 이상의 항목이 허용되는지, 어떤 필드가 환경 마커 구문을 지원하는지(값과 마커를 구분하기 위한 선택적 ";"를 포함하여), 나아가 특정 하위 필드 안에 임의의 JSON을 삽입할 수 있는지까지 알아야 하는 등 여러 복잡한 문제가 있었습니다.

기존 직렬화 형식은 새로운 설치 훅 API에서 사용하거나, 런타임 임포터 API의 향후 확장에서 설치 데이터베이스에 포함할 정보를 제공할 수 있도록 하기 위해 표준 Python 데이터 구조로 쉽게 변환하기에도 적합하지 않았습니다.

따라서 JSON 호환 메타데이터 형식으로 전환하는 조치를 취했습니다. 이 형식은 API에 더 적합하며 도구가 올바르게 파싱하고 생성하기도 훨씬 쉽습니다. 메타데이터 파일의 이름을 변경하면 1.x 및 2.x 메타데이터를 병렬로 쉽게 배포할 수 있으므로, 새 메타데이터 형식으로의 마이그레이션 과정에서 여러 측면을 크게 단순화할 수 있습니다.

선호되는 파일 이름으로 pydist.json을 선택한 구체적인 이유는 이 파일에 설명된 메타데이터가 특정 빌드가 아니라 배포 전체에 적용되기 때문입니다. 향후 특정 대상 환경을 위한 바이너리 배포판을 빌드한 후에만 결정할 수 있는 정보를 저장하기 위해 추가 메타데이터 형식이 정의될 수 있습니다.

버전 체계 변경

버전 관리 체계에 적용된 다양한 변경 사항에 대한 자세한 근거는 PEP 440을 참조하십시오.

소스 레이블

새로운 소스 레이블 지원은 공개 버전 식별자에 대한 제약이 주로 신뢰할 수 있는 자동화된 의존성 분석 도구를 만드는 데 도움이 되기 위한 것임을 더 명확하게 하기 위한 것입니다. 프로젝트는 내부적으로 원하는 버전 관리 체계를 자유롭게 사용할 수 있으며, 의존성 분석 도구가 이해할 수 있는 형태로 변환할 수 있기만 하면 됩니다.

또한 소스 레이블을 사용하면 해시나 태그 이름처럼 프로젝트 버전 관리 시스템에서 릴리스를 재구성할 수 있도록 하는 버전의 구체적인 세부 정보를 간단하게 기록할 수 있습니다.

배포판을 위한 선택적 의존성 지원

새로운 extras 시스템을 사용하면 배포판이 선택적 동작을 선언하고, 특정 의존성이 해당 동작을 지원하는 경우에만 필요한 때를 의존성 필드로 나타낼 수 있습니다. 이는 이미 setuptools의 일부로 널리 사용되는 동등한 시스템에서 파생되었으며, 레거시 setuptools 메타데이터의 해당 측면을 새로운 메타데이터 형식으로 정확하게 표현할 수 있도록 합니다.

setuptools에 비해 extras 구문에 추가된 사항은 다양한 가능한 의존성 조합, 특히 빌드 시스템(테스트 모음 실행을 선택적으로 지원하는 경우 포함) 및 개발 시스템과 관련된 조합을 더 쉽게 표현할 수 있도록 정의되었습니다.

서로 다른 종류의 의미론적 의존성 지원

Extras 시스템을 통해 다섯 가지 서로 다른 의존성 종류를 분리하면 프로젝트가 특정 의존성이 배포판을 개발, 빌드, 테스트 또는 사용하는 데 필요한 것인지 선택적으로 나타낼 수 있습니다.

이러한 구분을 업스트림 Python 전용 메타데이터에서 지원할 때의 장점은 프로젝트 자체가 이러한 구분을 중요하게 여기지 않더라도, 필드를 적절히 분리하는 다운스트림 재배포자의 패치를 더 쉽게 수용할 수 있다는 점입니다. 시간이 지나면 이를 통해 특정 의존성이 어디에, 언제 설치되는지 훨씬 더 효과적으로 제어할 수 있을 것입니다.

메타데이터 확장 지원

새로운 확장을 사용하면 메타데이터 네임스페이스의 일부를 다른 프로젝트에 위임하면서도, 특정 확장을 지원하지 않는 배포 도구가 쉽게 처리할 수 있도록 표준적인 전체 메타데이터 형식을 유지할 수 있습니다.

또한 새로운 build extra와 함께 사용하면 배포판이 선택한 확장을 처리할 줄 do 아는 도구에 의존하도록 할 수 있으며, 새로운 extras 메커니즘 전반을 통해 특정 확장에 대한 지원을 선택적 기능으로 제공할 수 있습니다.

확장의 향후 사용 사례로는 다른 프로젝트를 위한 플러그인 선언과 Linux 시스템 패키지로 자동 변환하기 위한 힌트가 있습니다.

확장을 필수로 선언할 수 있는 기능은 주로 메타데이터 훅 확장의 정의를 메타데이터 2.0 사양이 처음 채택된 후 일정 시점까지 연기할 수 있도록 포함되었습니다. 설치를 성공적으로 완료하려면 릴리스에서 postinstall 훅을 실행해야 하는 경우, 이전 버전의 도구는 wheel 파일에서 설치한 다음 예상되는 postinstall 훅을 실행하지 못하는 대신 소스에서 설치하는 방식으로 대체해야 합니다.

부록 D: 연기된 기능

새 메타데이터 표준으로 마이그레이션하는 데 노력을 더 효과적으로 우선 배분하기 위해, 잠재적으로 유용한 몇 가지 기능의 도입을 의도적으로 연기했습니다. 이러한 기능은 모두 새 메타데이터에 포함되면 유용할 수 있는 정보를 반영하지만, 메타데이터 2.0에서 이미 지원되는 사용 사례를 중단하지 않고 메타데이터 확장이나 메타데이터 2.1을 통해 쉽게 추가할 수 있습니다.

pypi, setuptools, pip, wheeldistlib 프로젝트가 메타데이터 2.0의 생성과 사용을 지원하게 되면, 이러한 추가 기능의 일부 또는 전부를 포함하는 메타데이터 2.1의 생성을 다시 검토할 수 있습니다.

표준 확장

기존 메타데이터 시스템이 제공하던 정보 중 일부는 PEP 459에서 정의한 표준 확장으로 분리되었습니다.

이에 따라 이러한 확장의 세부 사항이 모두 확정되기 전에도 핵심 의존성 메타데이터를 보다 쉽게 사용할 수 있는 형식으로 게시할 수 있습니다.

프로젝트의 폐기, 이름 변경 및 병합 처리 개선

이 PEP의 초기 초안에는 프로젝트의 폐기, 이름 변경 및 병합을 더욱 견고하게 자동으로 알리고 추적하기 위한 새로운 ProvidesObsoleted-By 필드가 포함되어 있었습니다.

이는 의존성 관리 시스템의 필수 기능이 아니므로, 향후 메타데이터 확장으로 추가할 수 있는 항목으로 무기한 연기되었습니다.

MIME 유형 등록

PEP가 승인된 후 어느 시점에 다음 MIME 유형 등록 요청을 IANA에 제출할 수 있습니다.

  • application/vnd.python.pydist+json

개별 하위 형식을 등록하는 대신 PSF의 이름으로 vnd.python 네임스페이스만 등록할 수 있을 가능성도 있습니다.

환경 마커의 문자열 메서드

환경 마커에서 최소한 “.startswith” 및 “.endswith” 문자열 메서드를 지원하면 일부 조건을 더 자연스럽게 작성할 수 있습니다. 예를 들어, "sys.platform.startswith('win')"은 Windows 전용 의존성을 표시하는 보다 직관적인 방법입니다. "'win' in sys.platform"cygwin 때문에 올바르지 않으며, 64비트 Windows도 여전히 win32로 표시된다는 점은 상당히 이상하기 때문입니다.

부록 E: 거부된 기능

다음 기능은 표현력 향상에 비해 추가되는 복잡성이 지나치게 크다고 판단되어 명시적으로 검토한 후 거부되었습니다.

조건부 의존성과 무조건부 의존성을 위한 별도 목록

이 PEP의 이전 버전에서는 조건부 의존성과 무조건부 의존성에 별도 목록을 사용했습니다. 이는 자동화 도구에서 처리하기 번거로운 것으로 드러났으며, 이를 제거하자 PEP와 메타데이터 스키마도 상당히 짧아졌습니다. 이는 해당 구분이 실제로 설명하기도 더 어려웠음을 시사합니다.

의미적 의존성을 위한 별도 목록

이 PEP의 이전 버전에서는 테스트, 빌드, 문서화 및 개발 의존성에 extras 시스템 대신 별도 필드를 사용했습니다. 이는 자동화 도구에서 처리하기 번거로운 것으로 드러났으며, 이를 제거하자 PEP와 메타데이터 스키마도 상당히 짧아졌습니다. 이는 해당 구분이 실제로 설명하기도 더 어려웠음을 시사합니다.

지나치게 정밀한 의존성 선언에 제약 도입

이 PEP의 이전 버전에서는 게시된 릴리스에서 지나치게 엄격한 의존성 선언을 부적절하게 사용하는 것을 어렵게 만들려고 했습니다. distutils-sig에서 논의한 결과, 이는 상호 운용성 사양 계층에서 직접 해결할 만큼 심각한 문제가 아니며, 향후 문제가 된다면 공개 Python 패키지 색인에 프로젝트를 업로드하는 시점에 해결하는 편이 더 낫다는 결론에 도달했습니다.

배포 이름에서 밑줄 사용 금지

Debian은 실제로 이름에 밑줄을 허용하지 않지만, 유효한 Python 식별자를 Python 배포 이름으로 사용하는 관행이 일반적이라는 점을 고려하면 이 사양에 그러한 제한을 두는 것은 지나치게 엄격해 보입니다. 밑줄을 하이픈으로 변환하는 Debian 측 정책은 충분히 쉽게 구현할 수 있어 보입니다. 또한 하이픈과 밑줄을 동등한 것으로 취급해야 한다는 요구 사항에 따라 이렇게 변환해도 이름 충돌이 발생하지 않습니다.

배포 이름에서 유니코드 사용 허용

이 PEP는 임의의 유니코드 식별자를 허용하는 Python 3의 방향을 의도적으로 따르지 않습니다. 소프트웨어 배포 사용 사례에서는 그러한 방식의 보안 영향이 상당히 더 심각하기 때문입니다. 이는 단순한 코드 난독화보다 훨씬 흥미로운 공격 벡터를 더 많이 열어 줍니다.

게다가, 기존 도구들은 이름을 ASCII로 제한해야만 실제로 제대로 작동하며, 이를 변경하려면 체인에 있는 모든 자동화 도구에 많은 작업이 필요합니다.

(먼) 미래의 어느 시점에 이 문제를 다시 검토하는 것이 합리적일 수 있지만, 더 일반적인 유니코드 식별자 지원을 추가하지 않더라도 더 신뢰할 수 있는 소프트웨어 배포 시스템을 구축하는 것만으로도 충분히 어려운 작업입니다.

소스 레이블에 의존하기

소스 레이블에 대한 의존성을 표현하는 메커니즘은 없습니다 - 소스 레이블은 내부 프로젝트 참조용으로만 메타데이터에 포함됩니다. 대신, 의존성은 공개 버전 또는 직접 URL 참조로 표현되어야 합니다.

대체 의존성

이 PEP의 초기 초안에서는 의존성을 만족하는 여러 방법이 있음을 나타내기 위해 의존성 명시에서 일반적인 문자열 대신 리스트를 허용하는 것을 고려했습니다.

개별 의존성 중 적어도 하나가 이미 사용 가능하다면 전체 의존성이 충족된 것으로 간주되며, 그렇지 않으면 첫 번째 항목이 의존성 집합에 추가됩니다.

대체 의존성 명시 예시:

["Pillow", "PIL"]
["mysql", "psycopg2 >= 4", "sqlite3"]

그러나 주어진 예시 중 어느 것도 특별히 설득력이 있지는 않은데, Pillow/PIL 방식의 포크는 흔하지 않으며, 데이터베이스 드라이버 사용 사례는 프로젝트가 SQL Alchemy에 의존하고 확장에서 업스트림 프로젝트가 호환성을 확인한 데이터베이스 드라이버를 선언하는, SQL Alchemy가 정의한 “지원되는 데이터베이스 드라이버” 메타데이터 확장으로 처리하는 것이 더 나을 것이기 때문입니다.

환경 마커에서의 호환 릴리스 비교

PEP 440는 환경 마커에서 python_versionpython_full_version에 유용할 수 있는 버전 비교를 위한 풍부한 구문을 정의합니다. 하지만 전체 구문을 허용하면 환경 마커가 더 이상 파이썬의 부분집합이 아니게 되며, 일부 비교만 허용하면 처리해야 할 또 다른 특수 사례가 생기게 됩니다.

환경 마커는 메타데이터 구조에 의해 상위 수준의 “or”가 암시되는 경우에만 사용되므로, 이것이 유용할 드문 경우에는 특정 파이썬 버전에 대한 여러 비교를 사용하도록 요구하는 편이 더 쉬워 보입니다.

조건부 provides

개정된 메타데이터 설계에서는, 런타임 기능이나 환경에 기반한 조건부 “provides”는 별도의 “may_provide” 필드에 들어가게 됩니다. 하지만 그렇게 할 만한 사용 사례가 있는지 명확하지 않으므로, 누군가 설득력 있는 사용 사례를 제시하지 않는 한 이 아이디어는 거부됩니다(설령 그렇다 하더라도 이 아이디어는 빨라도 메타데이터 2.1까지는 재고되지 않습니다).

참고 자료

이 문서는 메타데이터 형식의 버전 2.0을 명시합니다. 버전 1.0은 PEP 241에 명시되어 있습니다. 버전 1.1은 PEP 314에 명시되어 있습니다. 버전 1.2는 PEP 345에 명시되어 있습니다.

표준화된 버전 체계에 대한 초기 시도와 그러한 표준이 필요한 근거는 PEP 386에서 찾아볼 수 있습니다.