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

Python 개선 제안 한국어 번역

PEP 440 – 버전 식별 및 의존성 명세

Author:
Alyssa Coghlan <ncoghlan at gmail.com>, 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:
18-Mar-2013
Post-History:
30-Mar-2013, 27-May-2013, 20-Jun-2013, 21-Dec-2013, 28-Jan-2014, 08-Aug-2014, 22-Aug-2014
Replaces:
386
Resolution:
Distutils-SIG message

Table of Contents

번역·라이선스 안내

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

Important

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

×

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

초록

이 PEP는 Python 소프트웨어 배포판의 버전을 식별하고 특정 버전에 대한 의존성을 선언하기 위한 체계를 설명합니다.

이 문서는 PEP 345PEP 386에 설명된 이전의 표준화된 버전 관리 방식이 지닌 몇 가지 한계를 다룹니다.

정의

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

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

“릴리스”는 고유하게 식별되는 프로젝트의 스냅샷입니다.

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

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

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

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

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

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

버전 체계

배포판은 정의된 모든 버전 비교 연산을 지원하는 공개 버전 식별자로 식별됩니다.

버전 체계는 특정 배포 아카이브가 제공하는 배포판 버전을 설명하는 데 사용될 뿐만 아니라, 소프트웨어를 빌드하거나 실행하는 데 필요한 의존성 버전에 제약을 두는 데에도 사용됩니다.

공개 버전 식별자

정식 공개 버전 식별자는 다음 체계를 반드시 준수해야 합니다.:

[N!]N(.N)*[{a|b|rc}N][.postN][.devN]

공개 버전 식별자에는 앞뒤 공백이 포함되어서는 안 됩니다.

공개 버전 식별자는 해당 배포판 내에서 고유해야 합니다.

설치 도구는 이 체계를 준수하지 않는 공개 버전을 무시하는 것이 좋지만, 아래에 지정된 정규화도 반드시 포함해야 합니다. 설치 도구는 규정을 준수하지 않거나 모호한 버전이 감지될 때 사용자에게 경고할 수 있습니다.

정식 형식의 엄격한 준수 여부를 확인하는 정규 표현식과, 이후 정규화가 필요할 수 있는 입력을 허용하는 더 관대한 정규 표현식을 제공하는 Appendix B : Parsing version strings with regular expressions도 참조하십시오.

공개 버전 식별자는 최대 다섯 개의 세그먼트로 구분됩니다.

  • 에포크 세그먼트: N!
  • 릴리스 세그먼트: N(.N)*
  • 사전 릴리스 세그먼트: {a|b|rc}N
  • 사후 릴리스 세그먼트: .postN
  • 개발 릴리스 세그먼트: .devN

모든 릴리스는 다음 섹션에서 정의하는 “최종 릴리스”, “사전 릴리스”, “사후 릴리스” 또는 “개발 릴리스” 중 하나입니다.

모든 숫자 구성 요소는 ASCII 숫자의 시퀀스로 표현되는 음이 아닌 정수여야 합니다.

모든 숫자 구성 요소는 텍스트 문자열이 아니라 숫자 값에 따라 해석되고 정렬되어야 합니다.

모든 숫자 구성 요소는 0일 수 있습니다. 릴리스 세그먼트에 대해 아래에서 설명하는 경우를 제외하면, 숫자 구성 요소가 0인 것은 버전 정렬에서 항상 가능한 가장 낮은 값이라는 점 외에는 특별한 의미가 없습니다.

Note

기존의 공개 및 비공개 Python 프로젝트 전반에서 폭넓게 사용되는 버전 관리 관행을 더 잘 수용하기 위해, 이 체계에서는 일부 읽기 어려운 버전 식별자를 허용합니다.

따라서 PEP에서 기술적으로 허용하는 일부 버전 관리 관행은 새 프로젝트에서 강력히 권장하지 않습니다. 이러한 경우에는 관련 세부 사항을 다음 섹션에서 설명합니다.

로컬 버전 식별자

로컬 버전 식별자는 다음 체계를 준수해야 합니다.:

<public version identifier>[+<local version label>]

로컬 버전 식별자는 일반 공개 버전 식별자(이전 섹션에서 정의함)와 임의의 “로컬 버전 레이블”로 구성되며, 로컬 버전 레이블은 더하기 기호로 공개 버전 식별자와 구분됩니다. 로컬 버전 레이블에는 특정 의미가 할당되지 않지만, 몇 가지 구문 제한이 적용됩니다.

로컬 버전 식별자는 업스트림 프로젝트의 API(해당하는 경우 ABI)와 완전히 호환되는 패치 버전을 나타내는 데 사용됩니다. 예를 들어, 새 업스트림 릴리스로 업그레이드하면 애플리케이션이나 기타 통합 시스템(예: Linux 배포판)에 지나치게 큰 영향을 미치는 경우, 애플리케이션 개발자와 시스템 통합자가 특정 백포트된 버그 수정을 적용하여 이러한 버전을 만들 수 있습니다.

로컬 버전 레이블을 포함하면 다운스트림 통합자가 잠재적으로 변경한 재빌드와 업스트림 릴리스를 구별할 수 있습니다. 로컬 버전 식별자를 사용해도 릴리스의 종류는 바뀌지 않지만, 소스 배포본에 적용된 경우에는 해당 업스트림 릴리스와 정확히 동일한 코드를 포함하지 않을 수 있음을 나타냅니다.

로컬 버전 식별자를 파일 이름과 URL의 일부로 쉽게 통합하고 16진수 해시 표현의 형식 불일치를 방지하려면, 로컬 버전 레이블을 다음 허용 문자 집합으로 제한해야 합니다.

  • ASCII 문자([a-zA-Z])
  • ASCII 숫자([0-9])
  • 마침표(.)

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

로컬 버전의 비교 및 정렬에서는 로컬 버전의 각 세그먼트(.로 구분됨)를 별도로 고려합니다. 세그먼트가 ASCII 숫자로만 구성된 경우 비교 목적으로 해당 부분을 정수로 간주하며, 세그먼트에 ASCII 문자가 하나라도 포함된 경우 해당 세그먼트는 대소문자를 구분하지 않고 사전식으로 비교합니다. 숫자 세그먼트와 사전식 세그먼트를 비교할 때는 숫자 부분이 항상 사전식 세그먼트보다 큰 것으로 비교됩니다. 또한 더 짧은 로컬 버전의 세그먼트가 더 긴 로컬 버전의 시작 부분과 정확히 일치하는 한, 세그먼트 수가 더 많은 로컬 버전은 세그먼트 수가 더 적은 로컬 버전보다 항상 큰 것으로 비교됩니다.

“업스트림 프로젝트”는 자체 공개 버전을 정의하는 프로젝트입니다. “다운스트림 프로젝트”는 업스트림 프로젝트를 추적하고 재배포하며, 업스트림 프로젝트의 이후 버전에서 보안 수정 및 버그 수정을 백포트할 수도 있는 프로젝트입니다.

공개 색인 서버에 업스트림 프로젝트를 게시할 때는 로컬 버전 식별자를 사용하지 않는 것이 좋지만, 프로젝트 소스에서 직접 만든 비공개 빌드를 식별하는 데 사용할 수 있습니다. 다운스트림 프로젝트는 공개 버전 식별자로 식별되는 업스트림 프로젝트 버전과 API 호환되지만 추가 변경 사항(예: 버그 수정)을 포함하는 버전을 릴리스할 때 로컬 버전 식별자를 사용하는 것이 좋습니다. Python 패키지 색인은 업스트림 프로젝트를 색인하고 호스팅하는 용도로만 사용되므로, 로컬 버전 식별자의 사용을 허용해서는 안 됩니다.

로컬 버전 식별자를 사용하는 소스 배포본은 PEP 459에서 정의한 python.integrator 확장 메타데이터를 제공하는 것이 좋습니다.

최종 릴리스

릴리스 세그먼트와 선택적으로 에포크 식별자로만 구성된 버전 식별자를 “최종 릴리스”라고 합니다.

릴리스 세그먼트는 점으로 구분된 하나 이상의 음이 아닌 정수 값으로 구성됩니다.:

N(.N)*

프로젝트 내 최종 릴리스에는 반드시 일관되게 증가하는 방식으로 번호가 매겨져야 합니다. 그렇지 않으면 자동화 도구가 이를 올바르게 업그레이드할 수 없습니다.

릴리스 세그먼트의 비교 및 순서는 릴리스 세그먼트의 각 구성 요소의 숫자 값을 차례로 고려합니다. 구성 요소 수가 서로 다른 릴리스 세그먼트를 비교할 때는 필요한 만큼 추가 0을 사용하여 더 짧은 세그먼트를 채웁니다.

이 체계에서는 첫 번째 이후에 추가되는 구성 요소의 수에 제한이 없지만, 가장 일반적인 변형은 두 개의 구성 요소(“major.minor”) 또는 세 개의 구성 요소(“major.minor.micro”)를 사용하는 것입니다.

예를 들면:

0.9
0.9.1
0.9.2
...
0.9.10
0.9.11
1.0
1.0.1
1.1
2.0
2.0.1
...

릴리스 시리즈는 공통 접두사로 시작하는 모든 최종 릴리스 번호의 집합입니다. 예를 들어, 3.3.1, 3.3.53.3.9.45는 모두 3.3 릴리스 시리즈에 속합니다.

Note

X.YX.Y.0은 서로 다른 릴리스 번호로 간주되지 않습니다. 릴리스 세그먼트 비교 규칙은 세 개의 구성 요소를 포함하는 릴리스 세그먼트와 비교할 때 두 구성 요소 형식을 암묵적으로 X.Y.0으로 확장하기 때문입니다.

날짜 기반 릴리스 세그먼트도 허용됩니다. 릴리스 연도와 월을 사용하는 날짜 기반 릴리스 체계의 예:

2012.4
2012.7
2012.10
2013.1
2013.6
...

사전 릴리스

일부 프로젝트에서는 최종 릴리스 전에 사용자가 테스트할 수 있도록 “알파, 베타, 릴리스 후보” 사전 릴리스 주기를 사용합니다.

프로젝트의 개발 주기의 일부로 사용되는 경우, 이러한 사전 릴리스는 버전 식별자에 사전 릴리스 세그먼트를 포함시켜 표시됩니다:

X.YaN   # Alpha release
X.YbN   # Beta release
X.YrcN  # Release Candidate
X.Y     # Final release

릴리스 세그먼트와 사전 릴리스 세그먼트로만 구성된 버전 식별자를 “사전 릴리스”라고 합니다.

사전 릴리스 세그먼트는 사전 릴리스 단계를 나타내는 알파벳 식별자와 음이 아닌 정수 값으로 구성됩니다. 주어진 릴리스에 대한 사전 릴리스는 먼저 단계(alpha, beta, release candidate)로 정렬되고, 그다음 해당 단계 내의 숫자 구성 요소로 정렬됩니다.

설치 도구는 기존의 레거시 배포판을 처리하기 위해 동일한 릴리스 세그먼트에 대해 crc 릴리스를 모두 허용할 수 있습니다(MAY).

설치 도구는 c 버전을 rc 버전과 동등하게 해석해야 합니다(SHOULD)(즉, c1rc1과 같은 버전을 나타냅니다).

빌드 도구, 게시 도구 및 색인 서버는 동일한 릴리스 세그먼트에 대해 rcc 릴리스를 모두 생성하는 것을 허용하지 않아야 합니다(SHOULD).

사후 릴리스

일부 프로젝트는 배포된 소프트웨어에 영향을 주지 않는 최종 릴리스의 사소한 오류(예: 릴리스 노트의 오류 수정)를 해결하기 위해 사후 릴리스를 사용합니다.

프로젝트의 개발 주기의 일부로 사용되는 경우, 이러한 사후 릴리스는 버전 식별자에 사후 릴리스 세그먼트를 포함시켜 표시됩니다:

X.Y.postN    # Post-release

개발 릴리스 세그먼트 없이 사후 릴리스 세그먼트를 포함하는 버전 식별자를 “사후 릴리스”라고 합니다.

사후 릴리스 세그먼트는 문자열 .post뒤에 음이 아닌 정수 값이 이어지는 형태로 구성됩니다. 사후 릴리스는 숫자 구성 요소에 따라 정렬되며, 해당 릴리스 바로 다음에 오고 이후의 어떤 릴리스보다도 앞섭니다.

Note

실제 버그 수정을 포함하는 유지 보수 릴리스를 게시하기 위해 사후 릴리스를 사용하는 것은 강력히 권장되지 않습니다. 일반적으로는 더 긴 릴리스 번호를 사용하여 각 유지 보수 릴리스마다 마지막 구성 요소를 증가시키는 것이 더 좋습니다.

사후 릴리스는 사전 릴리스에 대해서도 허용됩니다:

X.YaN.postM   # Post-release of an alpha release
X.YbN.postM   # Post-release of a beta release
X.YrcN.postM  # Post-release of a release candidate

Note

프리릴리스의 포스트릴리스를 생성하는 것은 강력히 권장되지 않습니다. 이는 사람이 읽기에 버전 식별자를 파싱하기 어렵게 만들기 때문입니다. 일반적으로, 숫자 구성 요소를 증가시켜 새 프리릴리스를 만드는 것이 훨씬 더 명확합니다.

개발 릴리스

일부 프로젝트는 정기적으로 개발 릴리스를 만들며, 시스템 패키저(특히 리눅스 배포판용)는 이후 프로젝트 릴리스와 충돌하지 않는 초기 릴리스를 소스 관리 시스템에서 직접 생성하고자 할 수 있습니다.

프로젝트의 개발 주기 일부로 사용되는 경우, 이러한 개발 릴리스는 버전 식별자에 개발 릴리스 세그먼트를 포함시켜 표시합니다.:

X.Y.devN    # Developmental release

개발 릴리스 세그먼트를 포함하는 버전 식별자를 “개발 릴리스”라고 부릅니다.

개발 릴리스 세그먼트는 문자열 .dev와 그 뒤에 오는 음이 아닌 정수 값으로 구성됩니다. 개발 릴리스는 숫자 구성 요소로 정렬되며, 해당 릴리스 바로 이전(그리고 릴리스 세그먼트가 같은 프리릴리스보다도 이전)에 위치하며, 이전의 모든 릴리스(포스트릴리스 포함)보다는 뒤에 위치합니다.

개발 릴리스는 프리릴리스와 포스트릴리스에도 허용됩니다.:

X.YaN.devM       # Developmental release of an alpha release
X.YbN.devM       # Developmental release of a beta release
X.YrcN.devM      # Developmental release of a release candidate
X.Y.postN.devM   # Developmental release of a post-release

Note

지속적 통합 목적으로는 유용할 수 있지만, 프리릴리스의 개발 릴리스를 범용 공개 색인 서버에 게시하는 것은 강력히 권장되지 않습니다. 이는 사람이 읽기에 버전 식별자를 파싱하기 어렵게 만들기 때문입니다. 그러한 릴리스를 게시해야 하는 경우, 숫자 구성 요소를 증가시켜 새 프리릴리스를 만드는 것이 훨씬 더 명확합니다.

포스트릴리스의 개발 릴리스 또한 강력히 권장되지 않지만, 코드 변경을 포함할 수 있는 전체 유지보수 릴리스에 포스트릴리스 표기법을 사용하는 프로젝트에는 적합할 수 있습니다.

버전 에포크

버전 식별자에 포함되는 경우, 에포크는 다른 모든 구성 요소보다 앞에 나타나며, 느낌표로 릴리스 세그먼트와 구분됩니다.:

E!X.Y  # Version identifier with epoch

명시적인 에포크가 주어지지 않으면, 암묵적 에포크는 0입니다.

대부분의 버전 식별자는 epoch를 포함하지 않습니다. 명시적 epoch는 프로젝트가 버전 번호를 처리하는 방식을 변경하여 일반적인 버전 정렬 규칙이 잘못된 결과를 낼 때만 필요하기 때문입니다. 예를 들어, 어떤 프로젝트가 2014.04와 같은 날짜 기반 버전을 사용하다가 1.0과 같은 시맨틱 버전으로 전환하려 한다면, 일반적인 정렬 방식을 사용할 때 새 릴리스가 날짜 기반 릴리스보다 더 오래된 것으로 식별됩니다.:

1.0
1.1
2.0
2013.10
2014.04

하지만 명시적인 epoch를 지정하면 정렬 순서를 적절히 바꿀 수 있는데, 이는 이후 epoch의 모든 버전이 이전 epoch의 버전보다 뒤에 정렬되기 때문입니다:

2013.10
2014.04
1!1.0
1!1.1
1!2.0

정규화

기존 버전과의 호환성을 더 잘 유지하기 위해, 버전을 파싱할 때 반드시 고려해야 하는 여러 가지 “대체” 구문이 있습니다. 이러한 구문은 버전을 파싱할 때 반드시 고려해야 하지만, 위에서 정의한 표준 구문으로 “정규화”되어야 합니다.

대소문자 구분

버전 내의 모든 ASCII 문자는 대소문자를 구분하지 않고 해석해야 하며, 정규형은 소문자입니다. 이로써 1.1RC1과 같은 버전이 허용되며, 이는 1.1rc1로 정규화됩니다.

정수 정규화

모든 정수는 내장 함수 int()를 통해 해석되며, 출력의 문자열 형태로 정규화됩니다. 즉, 정수 버전 000으로 정규화되고, 090009000으로 정규화된다는 의미입니다. 이는 1.0+foo0100과 같이 이미 정규화된 형태인 로컬 버전의 영숫자 세그먼트 내부에 있는 정수에는 해당하지 않습니다.

프리릴리스 구분자

프리릴리스는 릴리스 세그먼트와 프리릴리스 세그먼트 사이에 ., -, _ 구분자를 허용해야 합니다. 이에 대한 정규형은 구분자가 없는 형태입니다. 이는 1.1.a1 또는 1.1-a1과 같은 버전을 허용하며, 이들은 1.1a1로 정규화됩니다. 또한 프리릴리스 지시자와 숫자 사이에 구분자를 사용하는 것도 허용해야 합니다. 이는 1.0a.1과 같은 버전을 허용하며, 이는 1.0a1로 정규화됩니다.

프리릴리스 철자

프리릴리스는 a, b, rc, rc, rc에 대해 각각 alpha, beta, c, pre, preview라는 추가 철자를 허용합니다. 이는 1.1alpha1, 1.1beta2, 1.1c3과 같은 버전을 허용하며, 이들은 각각 1.1a1, 1.1b2, 1.1rc3으로 정규화됩니다. 모든 경우에 있어 추가 철자는 해당 정규형과 동등하게 취급되어야 합니다.

암묵적 프리릴리스 번호

프리릴리스는 숫자를 생략하는 것을 허용하며, 이 경우 암묵적으로 0으로 간주됩니다. 이에 대한 정규형은 0을 명시적으로 포함하는 형태입니다. 이는 1.2a와 같은 버전을 허용하며, 이는 1.2a0으로 정규화됩니다.

포스트 릴리스 구분자

포스트 릴리스는 구분자로 ., -, _를 허용하며 구분자를 완전히 생략하는 것도 허용합니다. 이것의 정규 형식은 . 구분자를 사용하는 것입니다. 이를 통해 1.2-post21.2post2같은 버전이 허용되며, 이는 1.2.post2로 정규화됩니다. 프리 릴리스 구분자와 마찬가지로, 이것도 포스트 릴리스 표시자와 숫자 사이에 선택적인 구분자를 허용합니다. 이를 통해 1.2.post-2같은 버전이 허용되며, 이는 1.2.post2로 정규화됩니다.

포스트 릴리스 철자

포스트 릴리스는 revr이라는 추가 철자를 허용합니다. 이를 통해 1.0-r4같은 버전이 허용되며, 이는 1.0.post4로 정규화됩니다. 프리 릴리스와 마찬가지로, 이 추가 철자는 정규 형식과 동등한 것으로 간주해야 합니다.

암묵적 포스트 릴리스 번호

포스트 릴리스는 숫자를 생략하는 것을 허용하며, 이 경우 암묵적으로 0으로 간주됩니다. 이것의 정규 형식은 0을 명시적으로 포함하는 것입니다. 이를 통해 1.2.post같은 버전이 허용되며, 이는 1.2.post0으로 정규화됩니다.

암묵적 포스트 릴리스

포스트 릴리스는 post 표시자를 완전히 생략할 수 있습니다. 이 형식을 사용할 때 구분자는 반드시 -이어야 하며, 다른 형식은 허용되지 않습니다. 이를 통해 1.0-1과 같은 버전이 1.0.post1로 정규화될 수 있습니다. 이 특정 정규화는 암시적 포스트 릴리스 번호 규칙과 함께 사용되어서는 안 됩니다. 다시 말해, 1.0-는 유효한 버전이 아니며, 1.0.post0으로 정규화되지도 않습니다.

개발 릴리스 구분자

개발 릴리스는 ., -, _ 구분자를 허용하며, 구분자를 완전히 생략하는 것도 허용합니다. 이에 대한 정규 형식은 . 구분자를 사용하는 것입니다. 이를 통해 1.2-dev21.2dev2와 같은 버전이 1.2.dev2로 정규화될 수 있습니다.

암시적 개발 릴리스 번호

개발 릴리스는 숫자를 생략할 수 있으며, 이 경우 암시적으로 0으로 간주됩니다. 이에 대한 정규 형식은 0을 명시적으로 포함하는 것입니다. 이를 통해 1.2.dev와 같은 버전이 1.2.dev0으로 정규화됩니다.

로컬 버전 세그먼트

로컬 버전의 경우, 세그먼트의 구분자로 .을 사용하는 것 외에 -_도 사용할 수 있습니다. 정규 형식은 . 문자를 사용하는 것입니다. 이를 통해 1.0+ubuntu-1과 같은 버전이 1.0+ubuntu.1로 정규화될 수 있습니다.

선행하는 v 문자

v1.0과 같은 일반적인 버전 표기법을 지원하기 위해, 버전 앞에 리터럴 v 문자 하나를 붙일 수 있습니다. 이 문자는 모든 목적에서 반드시 무시해야 하며, 버전의 모든 정규화된 형태에서 생략해야 합니다. v가 있는 버전과 없는 버전은 동일한 버전으로 간주됩니다.

선행 및 후행 공백

선행 및 후행 공백은 버전의 모든 정규화된 형태에서 자동으로 무시되고 제거되어야 합니다. 여기에는 " ", \t, \n, \r, \f, \v가 포함됩니다. 이를 통해 1.0\n과 같은 버전이 1.0으로 정규화되는 것처럼, 우발적인 공백을 합리적으로 처리할 수 있습니다.

준수하는 버전 체계의 예

표준 버전 체계는 공개 및 비공개 파이썬 프로젝트 전반에 걸친 다양한 식별 관행을 포괄하도록 설계되었습니다. 실제로는, 단일 프로젝트가 이 체계가 제공하는 유연성을 완전히 활용하려 한다면, 위의 규칙들이 모든 준수 도구가 일관되게 버전을 정렬하도록 보장함에도 불구하고, 사람 사용자가 버전들의 상대적 순서를 파악하기 어려운 상황이 발생할 수 있습니다.

다음 예시들은 프로젝트가 릴리스를 식별하기 위해 선택할 수 있는 다양한 접근 방식 중 일부를 보여주며, 이때 “최신 릴리스”와 “최신 안정 릴리스”는 사람 사용자와 자동화 도구 모두가 쉽게 판별할 수 있도록 보장합니다.

단순한 “major.minor” 버전 관리:

0.1
0.2
0.3
1.0
1.1
...

간단한 “major.minor.micro” 버전 관리:

1.1.0
1.1.1
1.1.2
1.2.0
...

alpha, beta, candidate 사전 릴리스가 있는 “major.minor” 버전 관리:

0.9
1.0a1
1.0a2
1.0b1
1.0rc1
1.0
1.1a1
...

개발 릴리스, 릴리스 후보, 사소한 수정을 위한 사후 릴리스가 있는 “major.minor” 버전 관리:

0.9
1.0.dev1
1.0.dev2
1.0.dev3
1.0.dev4
1.0c1
1.0c2
1.0
1.0.post1
1.1.dev1
...

각 연도 내에서 0을 건너뛰고 증가하는 일련번호를 사용하는 날짜 기반 릴리스:

2012.1
2012.2
2012.3
...
2012.15
2013.1
2013.2
...

허용되는 접미사와 상대적 순서 요약

Note

이 절은 버전 관리 방식을 결정하는 Python 배포판 개발자보다는 배포 메타데이터를 자동으로 처리하는 도구의 작성자를 주된 대상으로 합니다.

버전 식별자의 epoch 세그먼트는 주어진 epoch의 숫자 값에 따라 정렬되어야 합니다(MUST). epoch 세그먼트가 없는 경우, 암묵적인 숫자 값은 0입니다.

버전 식별자의 릴리스 세그먼트는, 정규화된 릴리스 세그먼트를 다음과 같이 파싱했을 때 Python의 튜플 정렬과 동일한 순서로 정렬되어야 합니다(MUST):

tuple(map(int, release_segment.split(".")))

비교에 관련된 모든 릴리스 세그먼트는 필요에 따라 더 짧은 세그먼트를 0으로 채워 일관된 길이로 변환되어야 합니다(MUST).

숫자 릴리스(1.0, 2.7.3) 내에서는 다음 접미사가 허용되며 표시된 순서로 정렬되어야 합니다(MUST):

.devN, aN, bN, rcN, <no suffix>, .postN

c는 의미상 rc와 동등한 것으로 간주되며, rc인 것처럼 정렬되어야 한다는 점에 유의하십시오. 도구는 동일한 릴리스 세그먼트에서 crc가 같은 N을 갖는 경우를 모호한 것으로 거부할 수 있으며(MAY), 그렇게 해도 PEP를 준수하는 것으로 간주됩니다.

alpha(1.0a1), beta(1.0b1), 또는 릴리스 후보(1.0rc1, 1.0c1) 내에서는 다음 접미사가 허용되며 표시된 순서로 정렬되어야 합니다(MUST):

.devN, <no suffix>, .postN

사후 릴리스(1.0.post1) 내에서는 다음 접미사가 허용되며 표시된 순서로 정렬되어야 합니다(MUST):

.devN, <no suffix>

devNpostN은, 숫자 버전 바로 뒤에 사용되는 경우(예: 1.0.dev456, 1.0.post1)에도 항상 앞에 점이 와야 한다는(MUST) 점에 유의하십시오.

접두사가 공유되는 사전 릴리스, 사후 릴리스 또는 개발 릴리스 세그먼트 내에서, 순서는 반드시 숫자 구성 요소의 값에 따라 정해져야 합니다.

다음 예시는 가능한 조합 중 많은 부분을 다룹니다.:

1.dev0
1.0.dev456
1.0a1
1.0a2.dev456
1.0a12.dev456
1.0a12
1.0b1.dev456
1.0b2
1.0b2.post345.dev456
1.0b2.post345
1.0rc1.dev456
1.0rc1
1.0
1.0+abc.5
1.0+abc.7
1.0+5
1.0.post456.dev34
1.0.post456
1.0.15
1.1.dev1

서로 다른 메타데이터 버전 간의 버전 순서

메타데이터 v1.0(PEP 241)과 메타데이터 v1.1(PEP 314)은 표준 버전 식별 또는 순서 지정 체계를 규정하지 않습니다. 그러나 메타데이터 v1.2(PEP 345)는 PEP 386에 정의된 스킴을 명시적으로 지정합니다.

단순 설치기 API의 특성상, 설치기가 특정 배포판이 사용한 메타데이터 버전을 인지하는 것은 불가능합니다. 또한 설치기는 프로젝트의 어떤 버전을 설치해야 할지 결정하기 위해, 해당 프로젝트의 모든 버전 또는 가능한 한 많은 버전을 포함하는 합리적으로 우선순위가 매겨진 목록을 만들 수 있는 능력이 필요했습니다. 이러한 요구 사항으로 인해, 프로젝트의 모든 버전에 사용될 단일 파싱 메커니즘에 걸친 표준화가 필요합니다.

위와 같은 이유로, 이 PEP는 메타데이터의 모든 버전에 사용되어야만 하며, 메타데이터 v1.2에 대해서도 PEP 386을 대체합니다. 도구는 이 PEP의 규칙으로 파싱할 수 없는 버전을 무시해야 하지만(SHOULD), 이 PEP를 준수하는 버전이 없는 경우에는 구현별로 정의된 버전 파싱 및 순서 지정 체계로 대체할 수 있습니다(MAY).

배포판 사용자는 자신이 관리하는 비공개 패키지 색인에서 규정을 준수하지 않는 버전을 명시적으로 제거하고 싶을 수 있습니다.

다른 버전 체계와의 호환성

일부 프로젝트는 이 PEP에서 정의된 공개 버전 체계를 준수하기 위해 변환이 필요한 버전 체계를 사용하기로 선택할 수 있습니다. 이러한 경우, 프로젝트 고유의 버전은 메타데이터에 저장될 수 있으며, 변환된 공개 버전은 버전 필드에 게시됩니다.

이를 통해 자동화된 배포 도구는 게시된 릴리스의 일관되고 올바른 순서를 제공할 수 있으며, 개발자는 여전히 자신의 프로젝트에 선호하는 내부 버전 관리 체계를 사용할 수 있습니다.

시맨틱 버저닝

Semantic versioning은 릴리스 번호의 다양한 요소가 갖는 의미에 관해 이 PEP보다 더 규범적인, 널리 쓰이는 버전 식별 체계입니다. 프로젝트가 시맨틱 버전 관리의 세부 사항을 따르지 않기로 선택하더라도, 이 체계는 다른 배포판에 의존할 때와 다른 이들이 의존하는 배포판을 게시할 때 발생할 수 있는 많은 문제를 다루고 있으므로 이해할 가치가 있습니다.

시맨틱 버전 관리의 “Major.Minor.Patch”(이 PEP에서는 “major.minor.micro”로 설명함) 측면(2.0.0 명세의 조항 1-8)은 이 PEP에서 정의한 버전 체계와 완전히 호환되며, 이러한 측면을 따르는 것이 권장됩니다.

하이픈(사전 릴리스 - 조항 10)이나 더하기 기호(빌드 - 조항 11)를 포함하는 시맨틱 버전은 이 PEP와 호환되지 않으며, 공개 버전 필드에서 허용되지 않습니다.

이러한 시맨틱 버전 관리 기반 소스 레이블을 호환되는 공개 버전으로 변환하는 한 가지 가능한 방법은 .devN 접미사를 사용하여 적절한 버전 순서를 지정하는 것입니다.

특정 빌드 정보는 로컬 버전 레이블에도 포함될 수 있습니다.

DVCS 기반 버전 레이블

많은 빌드 도구는 버전 식별자에 식별용 해시를 추가하기 위해 Git과 Mercurial 같은 분산 버전 관리 시스템과 통합됩니다. 해시는 신뢰성 있게 정렬할 수 없으므로 이러한 버전은 공개 버전 필드에서 허용되지 않습니다.

시맨틱 버전 관리와 마찬가지로, 게시를 위해 이러한 릴리스를 고유하게 식별하는 데 공개 .devN 접미사를 사용할 수 있으며, 원래의 DVCS 기반 레이블은 프로젝트 메타데이터에 저장할 수 있습니다.

식별용 해시 정보는 로컬 버전 레이블에도 포함될 수 있습니다.

Olson 데이터베이스 버전 관리

pytz 프로젝트는 해당 Olson 시간대 데이터베이스 버전 관리 체계로부터 버전 관리 체계를 물려받았습니다. 즉, 연도 뒤에 해당 연도 내 데이터베이스 버전을 나타내는 소문자가 붙습니다.

이는 <year>.<serial> 형식의 규격에 맞는 공개 버전 식별자로 변환할 수 있으며, 여기서 serial은 0 또는 1(‘<year>a’ 릴리스의 경우)에서 시작하여 해당 연도 내에서 후속 데이터베이스 업데이트가 있을 때마다 증가합니다.

다른 변환된 버전 식별자와 마찬가지로, 해당 Olson 데이터베이스 버전은 프로젝트 메타데이터에 기록할 수 있습니다.

버전 지정자

버전 지정자는 쉼표로 구분된 일련의 버전 절로 구성됩니다. 예를 들어:

~= 0.9, >= 1.0, != 1.3.4.*, < 2.0

비교 연산자는 버전 절의 종류를 결정합니다:

쉼표(“,”)는 논리 and 연산자와 동등합니다: 후보 버전이 지정자 전체와 일치하려면 주어진 모든 버전 절과 일치해야 합니다.

조건 연산자와 그 뒤에 오는 버전 식별자 사이의 공백은 선택 사항이며, 쉼표 주변의 공백도 마찬가지입니다.

여러 후보 버전이 버전 지정자와 일치하는 경우, 선호되는 버전은 표준 Version scheme에서 정의한 일관된 순서에 따라 결정되는 최신 버전이어야 합니다(SHOULD). 프리릴리스가 후보 버전으로 간주되는지 여부는 Handling of pre-releases에 설명된 대로 처리해야 합니다(SHOULD).

아래에 특별히 명시된 경우를 제외하고, 로컬 버전 식별자는 버전 지정자에서 허용되어서는 안 되며(MUST NOT), 후보 버전이 주어진 버전 지정자와 일치하는지 확인할 때 로컬 버전 레이블은 완전히 무시되어야 합니다(MUST).

호환 릴리스

호환 릴리스 절(compatible release clause)은 호환 릴리스 연산자 ~=와 버전 식별자로 구성됩니다. 이는 지정된 버전과 호환될 것으로 예상되는 모든 후보 버전과 일치합니다.

지정된 버전 식별자는 Version scheme에 설명된 표준 형식이어야 합니다. 로컬 버전 식별자는 이 버전 지정자에서 허용되지 않습니다.

주어진 릴리스 식별자 V.N에 대해, 호환 릴리스 절은 대략 다음 비교 절 쌍과 동등합니다:

>= V.N, == V.*

이 연산자는 ~=1과 같은 단일 세그먼트 버전 번호와 함께 사용해서는 안 됩니다(MUST NOT).

예를 들어, 다음 버전 절 그룹들은 동등합니다:

~= 2.2
>= 2.2, == 2.*

~= 1.4.5
>= 1.4.5, == 1.4.*

사전 릴리스, 사후 릴리스 또는 개발 릴리스가 호환 릴리스 절에서 V.N.suffix로 명명된 경우, 필요한 접두사 일치를 판단할 때 접미사는 무시됩니다:

~= 2.2.post3
>= 2.2.post3, == 2.*

~= 1.4.5a4
>= 1.4.5a4, == 1.4.*

릴리스 세그먼트 비교에 대한 패딩 규칙으로 인해, 호환 릴리스 절에서 가정되는 순방향 호환성의 정도는 버전 지정자에 추가로 0을 붙임으로써 제어할 수 있습니다:

~= 2.2.0
>= 2.2.0, == 2.2.*

~= 1.4.5.0
>= 1.4.5.0, == 1.4.5.*

버전 매칭

버전 매칭 절은 버전 매칭 연산자 ==와 버전 식별자를 포함합니다.

지정된 버전 식별자는 Version scheme에 설명된 표준 형식이어야 하지만, 아래에서 설명하는 바와 같이 공개 버전 식별자에는 마지막에 .*를 붙일 수 있습니다.

기본적으로 버전 매칭 연산자는 엄격한 동등성 비교를 기반으로 합니다: 지정된 버전은 요청된 버전과 정확히 동일해야 합니다. 수행되는 유일한 대체는 릴리스 세그먼트가 같은 길이로 비교되도록 하기 위한 릴리스 세그먼트의 0 패딩입니다.

엄격한 버전 매칭이 적절한지 여부는 버전 지정자의 구체적인 사용 사례에 달려 있습니다. 자동화 도구는 엄격한 버전 매칭이 부적절하게 사용될 경우 최소한 경고를 발행해야 하며(SHOULD), 완전히 거부할 수도 있습니다(MAY).

버전 매칭 절의 버전 식별자 끝에 .*를 붙여서 엄격한 비교 대신 접두사 매칭을 요청할 수 있습니다. 이는 버전 식별자가 해당 절과 일치하는지 판단할 때 뒤에 오는 추가 세그먼트는 무시됨을 의미합니다. 지정된 버전이 릴리스 세그먼트만 포함하는 경우, 릴리스 세그먼트의 후속 구성 요소(또는 그 부재)도 무시됩니다.

예를 들어, 버전 1.1.post1이 주어졌을 때, 다음 절들은 아래와 같이 일치하거나 일치하지 않습니다:

== 1.1        # Not equal, so 1.1.post1 does not match clause
== 1.1.post1  # Equal, so 1.1.post1 matches clause
== 1.1.*      # Same prefix, so 1.1.post1 matches clause

접두사 매칭 목적상 사전 릴리스 세그먼트 앞에는 암묵적으로 .이 있는 것으로 간주하므로, 버전 1.1a1이 주어졌을 때 다음 절들은 아래와 같이 일치하거나 일치하지 않습니다:

== 1.1        # Not equal, so 1.1a1 does not match clause
== 1.1a1      # Equal, so 1.1a1 matches clause
== 1.1.*      # Same prefix, so 1.1a1 matches clause if pre-releases are requested

정확히 일치하는 경우도 접두사 매칭으로 간주됩니다(이 해석은 버전 식별자의 릴리스 세그먼트에 대한 일반적인 0 채움 규칙에서 암묵적으로 도출됩니다). 버전 1.1이 주어졌을 때, 다음 절들은 아래와 같이 일치하거나 일치하지 않습니다:

== 1.1        # Equal, so 1.1 matches clause
== 1.1.0      # Zero padding expands 1.1 to 1.1.0, so it matches clause
== 1.1.dev1   # Not equal (dev-release), so 1.1 does not match clause
== 1.1a1      # Not equal (pre-release), so 1.1 does not match clause
== 1.1.post1  # Not equal (post-release), so 1.1 does not match clause
== 1.1.*      # Same prefix, so 1.1 matches clause

1.0.dev1.* 또는 1.0+foo1.*처럼 개발 릴리스나 로컬 릴리스를 포함하는 접두사 매칭은 유효하지 않습니다. 개발 릴리스 세그먼트가 존재하는 경우 항상 공개 버전의 마지막 세그먼트이며, 로컬 버전은 비교 목적상 무시되므로, 둘 중 하나를 접두사 매칭에 사용하는 것은 아무런 의미가 없습니다.

게시된 배포판에 대한 의존성을 정의할 때 (최소한 와일드카드 접미사 없이) ==를 사용하는 것은 보안 수정 사항의 배포를 크게 복잡하게 만들기 때문에 강력히 권장되지 않습니다. 엄격한 버전 비교 연산자는 주로 공유 배포 색인을 사용하는 동안 반복 가능한 애플리케이션 배포에 대한 의존성을 정의할 때 사용하기 위한 것입니다.

지정된 버전 식별자가 공개 버전 식별자(로컬 버전 레이블 없음)인 경우, 버전을 매칭할 때 후보 버전들의 로컬 버전 레이블은 반드시 무시해야 합니다.

지정된 버전 식별자가 로컬 버전 식별자인 경우, 버전을 매칭할 때 후보 버전들의 로컬 버전 레이블을 반드시 고려해야 하며, 공개 버전 식별자는 위에서 설명한 대로 매칭하고, 로컬 버전 레이블은 엄격한 문자열 동등성 비교를 사용하여 동등성을 검사합니다.

버전 제외

버전 제외 절은 버전 제외 연산자 !=와 버전 식별자를 포함합니다.

허용되는 버전 식별자와 비교 의미론은 번역한 텍스트 연산자와 동일하지만, 일치 여부의 의미가 반대라는 점만 다릅니다.

예를 들어, 버전 1.1.post1이 주어졌을 때, 다음 절들은 아래와 같이 일치하거나 일치하지 않습니다:

!= 1.1        # Not equal, so 1.1.post1 matches clause
!= 1.1.post1  # Equal, so 1.1.post1 does not match clause
!= 1.1.*      # Same prefix, so 1.1.post1 does not match clause

포함 순서 비교

포함 순서 비교 절은 비교 연산자와 버전 식별자를 포함하며, 표준 Version scheme에서 정의된 일관된 순서에 따라 후보 버전과 지정된 버전의 상대적 위치를 기준으로 비교가 올바른 모든 버전과 일치합니다.

포함 순서 비교 연산자는 <=>=입니다.

버전 매칭과 마찬가지로, 릴리스 세그먼트는 동일한 길이로 비교되도록 필요에 따라 0으로 채워집니다.

로컬 버전 식별자는 이 버전 지정자에서 허용되지 않습니다.

배타 순서 비교

배타 순서 비교 연산자 ><는 표준 Version scheme에서 정의된 일관된 순서에 따라 후보 버전과 지정된 버전의 상대적 위치에 의존한다는 점에서 포함 순서 비교와 유사합니다. 그러나 이들은 지정된 버전의 사전 릴리스, 사후 릴리스, 로컬 버전을 명시적으로 제외합니다.

배타 순서 비교 >VV 자체가 사후 릴리스가 아닌 한 주어진 버전의 사후 릴리스를 허용해서는 안 됩니다. >V.postN을 사용하여 추가 사후 릴리스를 포함해 특정 사후 릴리스보다 이후의 릴리스를 요구할 수 있습니다. 예를 들어, >1.71.7.1을 허용하지만 1.7.0.post1은 허용하지 않으며, >1.7.post21.7.11.7.0.post3을 허용하지만 1.7.0은 허용하지 않습니다.

배타 순서 비교 >V는 지정된 버전의 로컬 버전과 일치해서는 안 됩니다.

배타 순서 비교 <V는 지정된 버전 자체가 사전 릴리스가 아닌 한 지정된 버전의 사전 릴리스를 허용해서는 안 됩니다. 특정 사전 릴리스보다 이르지만 같지는 않은 사전 릴리스를 허용하려면 <V.rc1 또는 이와 유사한 형태를 사용하면 됩니다.

버전 매칭과 마찬가지로, 릴리스 세그먼트는 동일한 길이로 비교되도록 필요에 따라 0으로 채워집니다.

이 버전 지정자에서는 로컬 버전 식별자를 사용할 수 없습니다.

임의 동등성

임의 동등성 비교는 제로 패딩이나 로컬 버전과 같은 의미 정보를 전혀 고려하지 않는 단순 문자열 동등성 연산입니다. 이 연산자는 또한 == 연산자와 달리 접두사 매칭을 지원하지 않습니다.

임의 동등성의 주된 사용 사례는 이 PEP로는 달리 표현할 수 없는 버전을 지정할 수 있도록 하는 것입니다. 이 연산자는 특수한 연산자로, 이 PEP를 구현한 도구를 사용하는 사람이 이 PEP와 호환되지 않는 레거시 버전을 여전히 설치할 수 있도록 해주는 탈출구 역할을 합니다.

예를 들어 ===foobarfoobar 버전과 일치합니다.

이 연산자는 또한 ===1.0처럼 프로젝트의 패치되지 않은 버전을 명시적으로 요구하는 데 사용될 수도 있으며, 이 경우 1.0+downstream1 버전과는 일치하지 않습니다.

이 연산자의 사용은 강력히 권장되지 않으며, 도구는 이 연산자가 사용될 때 경고를 표시할 수도 있습니다(MAY).

프리릴리스 처리

개발 릴리스를 포함한 모든 종류의 프리릴리스는 시스템에 이미 존재하거나, 사용자가 명시적으로 요청하거나, 버전 지정자를 만족하는 유일하게 사용 가능한 버전이 프리릴리스인 경우가 아닌 한, 모든 버전 지정자에서 암묵적으로 제외됩니다.

기본적으로 의존성 해결 도구는 다음과 같이 동작해야 합니다(SHOULD):

  • 모든 버전 지정자에 대해 이미 설치된 프리릴리스를 허용합니다.
  • 버전 지정자를 만족하는 정식 릴리스나 포스트 릴리스가 없는 경우, 원격에서 사용 가능한 프리릴리스를 허용합니다.
  • 그 밖의 모든 프리릴리스는 고려 대상에서 제외합니다.

의존성 해결 도구는 버전 지정자를 만족시키기 위해 프리릴리스가 필요한 경우 경고를 표시할 수도 있습니다(MAY).

의존성 해석 도구는 사용자가 다음과 같은 대체 동작을 요청할 수 있도록 허용해야 합니다(SHOULD).

  • 모든 버전 지정자에 대해 사전 릴리스를 허용
  • 모든 버전 지정자에 대해 사전 릴리스를 제외(사전 릴리스가 이미 로컬에 설치되어 있거나, 특정 지정자를 만족시키는 유일한 방법이 사전 릴리스인 경우 오류 또는 경고를 보고)

의존성 해석 도구는 배포 패키지 단위로 위 동작을 제어할 수 있도록 허용할 수도 있습니다(MAY).

사후 릴리스와 최종 릴리스는 버전 지정자에서 특별한 처리를 받지 않습니다 - 명시적으로 제외되지 않는 한 항상 포함됩니다.

예제

  • ~=3.1: 버전 3.1 이상이지만, 버전 4.0 이상은 아닙니다.
  • ~=3.1.2: 버전 3.1.2 이상이지만, 버전 3.2.0 이상은 아닙니다.
  • ~=3.1a1: 버전 3.1a1 이상이지만, 버전 4.0 이상은 아닙니다.
  • == 3.1: 정확히 버전 3.1(또는 3.1.0)이며, 모든 사전 릴리스, 사후 릴리스, 개발 릴리스 및 3.1.x 유지보수 릴리스를 제외합니다.
  • == 3.1.*: 3.1로 시작하는 모든 버전입니다. ~=3.1.0 호환 릴리스 절과 동등합니다.
  • ~=3.1.0, != 3.1.3: 버전 3.1.0 이상이지만, 버전 3.1.3은 아니고 버전 3.2.0 이상도 아닙니다.

직접 참조

일부 자동화 도구는 일반 버전 지정자의 대안으로 직접 참조 사용을 허용할 수 있습니다. 직접 참조는 지정자 @와 명시적인 URL로 구성됩니다.

직접 참조가 적절한지 여부는 버전 지정자의 특정 사용 사례에 따라 달라집니다. 자동화 도구는 직접 참조가 부적절하게 사용될 경우 최소한 경고를 발행해야 하며(SHOULD), 이를 완전히 거부할 수도 있습니다(MAY).

공개 색인 서버는 업로드된 배포판에서 직접 참조의 사용을 허용해서는 안 됩니다(SHOULD NOT). 직접 참조는 배포자보다는 소프트웨어 통합자를 위한 도구로 의도되었습니다.

사용 사례에 따라, 직접 URL 참조의 적절한 대상은 sdist 또는 wheel 바이너리 아카이브가 될 수 있습니다. 지원되는 정확한 URL과 대상은 도구에 따라 다릅니다.

예를 들어, 로컬 소스 아카이브는 직접 참조될 수 있습니다:

pip @ file:///localbuilds/pip-1.3.1.zip

또는, 미리 빌드된 아카이브 역시 참조될 수 있습니다:

pip @ file:///localbuilds/pip-1.3.1-py33-none-any.whl

로컬 파일 URL을 가리키지 않는 모든 직접 참조는 (https와 같은) 보안 전송 메커니즘을 지정해야 하며(SHOULD), 검증 목적으로 URL에 예상 해시 값을 포함해야 합니다(AND). 직접 참조가 해시 정보 없이, 도구가 이해하지 못하는 해시 정보와 함께, 또는 도구가 신뢰하기에 너무 약하다고 간주하는 선택된 해시 알고리즘과 함께 지정된 경우, 자동화 도구는 최소한 경고를 발행해야 하며(SHOULD), 해당 URL을 신뢰하지 않을 수도 있습니다(MAY). 그러한 직접 참조가 안전하지 않은 전송 방식도 사용하는 경우, 자동화 도구는 해당 URL을 신뢰해서는 안 됩니다(SHOULD NOT).

소스 아카이브 해시에는 표준 라이브러리의 hashlib 모듈 최신 버전에서 무조건적으로 제공되는 해시만 사용하는 것이 권장됩니다(RECOMMENDED). 작성 시점 기준으로, 그 목록은 'md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512'로 구성됩니다.

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

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

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

Note

이것은 pip에서 지원하는 기존 VCS 참조 표기법과 완전히 같지는 않습니다. 첫째, 배포 패키지 이름이 URL의 일부로 내장되는 대신 앞으로 옮겨집니다. 둘째, 위조를 더 어렵게 만들기 위해 모든 링크가 해시를 포함해야 한다는 위의 요구사항을 충족하기 위해, 태그를 기반으로 가져올 때도 커밋 해시가 포함됩니다(특정 태그를 가진 악의적인 저장소를 만드는 것은 쉽지만, 특정 해시를 가진 저장소를 만드는 것은 그보다 어렵습니다).

원격 URL 예시:

pip @ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686
pip @ git+https://github.com/pypa/pip.git@7921be1537eac1e97bc40179a57f0349c2aee67d
pip @ git+https://github.com/pypa/pip.git@1.3.1#7921be1537eac1e97bc40179a57f0349c2aee67d

파일 URL

파일 URL은 file://<host>/<path> 형식을 취합니다. <host>가 생략되면 localhost로 간주되며, <host>가 생략되더라도 세 번째 슬래시는 반드시 존재해야 합니다. <path>는 접근할 파일시스템 상의 파일 경로를 정의합니다.

다양한 *nix 운영 체제에서 <host>에 허용되는 값은 생략되거나, localhost이거나, 현재 머신이 자신의 호스트와 일치한다고 판단하는 다른 FQDN뿐입니다. 다시 말해, *nix에서 file:// 스킴은 로컬 머신의 경로에 접근하는 데에만 사용할 수 있습니다.

Windows에서는 파일 형식에 해당하는 경우 드라이브 문자를 <path>의 일부로 포함해야 합니다(예: file:///c:/path/to/a/file). *nix와 달리 Windows에서는 <host> 매개변수를 사용하여 네트워크 공유에 있는 파일을 지정할 수 있습니다. 다시 말해, \\machine\volume\filefile:// URL로 변환하면 file://machine/volume/file이 됩니다. Windows에서 file:// URL에 대한 자세한 정보는 MSDN [4]을 참고하십시오.

버전 관리 명세 갱신

버전 관리 명세는 새로운 PEP나 메타데이터 버전의 변경 없이도 명확화를 위해 갱신될 수 있습니다.

버전 식별 및 비교 구문과 의미론에 영향을 미치는 모든 기술적 변경은 새로운 PEP에서 갱신된 버전 관리 체계를 정의할 것을 요구합니다.

pkg_resources.parse_version과의 차이점 요약

  • 참고: 이 비교는 PEP가 작성될 당시 존재했던 pkg_resourses.parse_version을 기준으로 합니다. PEP가 승인된 이후, setuptools 6.0 및 이후 버전은 이 PEP에 설명된 동작을 채택했습니다.
  • 로컬 버전은 정렬 방식이 다릅니다. 이 PEP는 로컬 버전이 로컬 버전이 없는 동일한 버전보다 크게 정렬되도록 요구하는 반면, pkg_resources.parse_version은 이를 사전 릴리스 표시로 간주합니다.
  • 이 PEP는 유효한 버전을 구성하는 구문을 의도적으로 제한하는 반면, pkg_resources.parse_version임의의 문자열에서 어떤 의미든 도출하려고 시도합니다.
  • pkg_resources.parse_version1.0.dev1.post1.dev5와 같이 임의로 깊게 중첩된 버전 표시자를 허용합니다. 그러나 이 PEP는 각 유형을 한 번만 사용하도록 허용하며, 특정 순서로 존재해야 합니다.

PEP 386과의 차이점 요약

  • 버전 지정자에 대한 설명을 버전 관리 PEP로 이동했습니다.
  • 각 도구가 자체적인 표기법을 고안할 필요 없이 리소스에 대한 직접 참조를 위한 표준 표기법으로 “직접 참조” 개념을 추가했습니다.
  • 시스템 통합자가 업스트림 도구에서 지원되는 방식으로 패치된 빌드를 표시할 수 있도록, 그리고 바이너리 배포판의 버전 관리에 빌드 태그를 포함할 수 있도록 “로컬 버전 식별자”와 “로컬 버전 레이블” 개념을 추가했습니다.
  • “호환 릴리스” 절을 추가했습니다.
  • 접두사 기반 버전 일치 및 제외를 위한 후행 와일드카드 구문을 추가했습니다.
  • .devN 접미사의 최상위 정렬 위치를 변경했습니다.
  • 단일 값 버전 번호 허용
  • 앞뒤 공백의 명시적 제외
  • 날짜 기반 버전에 대한 명시적 지원
  • 모호함을 유발하지 않는 범위에서 PyPI의 기존 버전 메타데이터와의 호환성을 개선하기 위한 명시적 정규화 규칙
  • 프리 릴리스가 이미 존재하거나 의존성을 충족하는 데 필요한 경우가 아니라면 암묵적으로 제외
  • 포스트 릴리스를 한정자가 없는 릴리스와 동일하게 취급
  • 메타데이터 버전 간의 순서와 의존성 논의
  • c를 선호하던 것에서 rc로 전환

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

버전 스킴 변경

이 PEP의 버전 스킴이 PEP 386의 버전 스킴과 대비되는 핵심 변경 사항 중 하나는 X.Y.devN과 같은 최상위 개발 릴리스를 X.Ya1과 같은 알파 릴리스보다 앞에 정렬하는 것입니다. 이는 훨씬 더 논리적인 정렬 순서인데, 개발 릴리스와 알파/베타/릴리스 후보를 모두 사용하는 프로젝트들은 자신들의 개발 릴리스가 릴리스 후보와 최종 릴리스 사이에 정렬되는 것을 원하지 않기 때문입니다. 단순히 추가적인 릴리스 후보를 만드는 대신 그 위치에 dev 릴리스를 사용해야 할 근거는 없습니다.

갱신된 정렬 순서는 또한 dev 버전의 정렬이 이제 메타데이터 표준과 pkg_resources의 기존 동작(그리고 그에 따른 현재 설치 도구들의 동작) 사이에서 일관성을 갖는다는 것을 의미합니다.

이 변경을 적용하면 영향을 받는 기존 프로젝트들이 최신 버전의 메타데이터 표준으로 이전하기가 더 쉬워질 것입니다.

버전 스킴에 대한 또 다른 변경 사항은 Mozilla Firefox, Google Chrome, Fedora Linux 배포판과 같은 비Python 프로젝트에서 사용되는 것과 유사한 단일 숫자 버전을 허용하는 것입니다. 이는 실제로 버전 지정자에 더 유용할 것으로 예상되지만, 두 정의를 분리하기보다는 버전 지정자와 릴리스 번호 모두에 대해 이를 허용하는 것이 더 쉽습니다.

선행 및 후행 공백의 제외는 후행 \n 문자만 다른 버전 식별자를 가진 프로젝트 몇 개가 PyPI에서 발견된 후 명시적으로 규정되었습니다.

아래의 버전 정규화에 관한 별도 절에서 설명하는 바와 같이 다양한 다른 정규화 규칙들도 추가되었습니다.

Appendix A는 2014년 8월 8일에 수집된 PyPI 배포 패키지 버전 정보 분석의 상세 결과를 보여줍니다. 이 분석은 이 PEP에서 정의된 명시적으로 순서가 지정된 버전 스킴의 동작을 setuptools의 동작으로 정의되는 사실상의 표준과 비교합니다. 이 PEP의 의도는 (setuptools가 하는 것처럼 적절한 순서를 추측하려 하기보다는) 순서를 매길 수 없는 버전에 대해서는 여전히 예외를 발생시키면서도, 실현 가능한 한 기존 setuptools 동작을 최대한 따르는 것이므로 이러한 지표들은 유용합니다.

버전 관리 스킴에 대한 더 견해가 뚜렷한 설명

관련 PEP 386에서와 마찬가지로, 주된 초점은 기존 프로젝트에 작업 흐름을 대폭 변경하도록 요구하기보다 기존 관행을 체계화하여 자동화에 더 적합하게 만드는 데 있습니다. 그러나 표준 스킴은 대다수의 단순한 Python 패키지(이런 패키지는 종종 유지 보수 릴리스조차 필요하지 않으며, 많은 사용자가 버그 수정을 위해 새 기능 릴리스로 업그레이드해야 하는 것에 만족합니다)에 필요한 것보다 훨씬 더 많은 유연성을 허용합니다.

초보 개발자를 위해, 그리고 다양한 사용 사례를 더 잘 이해하고자 하는 숙련된 개발자를 위해, 이 명세는 이제 정의된 버전 스킴의 구성 요소에 대해 각 구성 요소가 실제로 어떻게 사용될 수 있는지에 대한 예시를 포함하여 훨씬 더 자세히 다룹니다.

이 PEP는 또한 개발자들을 시맨틱 버전 관리 방향으로 명시적으로 안내하며(이를 요구하지는 않습니다), 기존 프로젝트의 관행과 Linux 배포판을 위한 소프트웨어 리패키징에서 나타나는 난해한 예외 상황을 다루기 위해 대부분 포함된 전체 버전 관리 스킴의 여러 측면의 사용을 지양합니다.

버전 관리 스킴과 함께 버전 지정자 설명하기

표준화된 버전 스킴을 애초에 두는 주된 이유는 신뢰할 수 있는 자동화된 의존성 분석을 더 쉽게 하기 위함입니다. 버전 식별자의 주된 사용 사례를 그 정의와 함께 설명하는 것이 더 타당합니다.

버전 지정자의 해석 변경

버전 지정자의 이전 해석은 의존성의 사전 릴리스 버전을 실수로 다운로드하기 매우 쉽게 만들었습니다. 이는 다시 개발자가 Python 패키지 색인에 소프트웨어의 사전 릴리스 버전을 게시하기 어렵게 만들었는데, 패키지를 숨김으로 표시하는 것만으로는 자동화 도구가 이를 다운로드하지 못하게 막기에 충분하지 않았기 때문이며, 또한 사용자가 주 PyPI 웹 인터페이스를 통해 수동으로 테스트 릴리스를 얻는 것도 더 어렵게 만들었습니다.

이전 해석은 또한 충분히 정당화되지 않은 이유로 일부 버전 지정자에서 포스트 릴리스를 배제했습니다.

갱신된 해석은 사전 릴리스 버전이 의존성을 만족시키는 것으로 실수로 받아들여지기 어렵게 하는 한편, 의존성을 만족시키는 유일한 방법일 때는 사전 릴리스 버전이 자동으로 검색될 수 있도록 허용하는 것을 목표로 합니다.

“일부 상위 호환성을 가정하는” 버전 제약은 Ruby 커뮤니티의 “비관적 버전 제약” 연산자 [2]에서 파생된 것으로, 프로젝트가 상위 호환성 약속에 신중한 접근 방식을 취하면서도 의존성에 필요한 최소 버전을 쉽게 설정할 수 있도록 허용합니다. 호환 릴리스 절(~=)의 표기법은 Ruby(~>)와 PHP(~)의 동등한 표기법에서 영감을 받았습니다.

동일한 라이브러리의 여러 버전을 병렬로 설치하는 처리 방식에 대한 추가 개선도 계획되어 있으나, 이는 설치 데이터베이스 정의의 갱신과 동적 경로 조작을 위한 개선된 도구에 달려 있습니다.

접두사 기반 버전 매칭을 요청하기 위한 후행 와일드카드 구문은 호환 릴리스 절을 합리적으로 정의할 수 있도록 추가되었습니다.

날짜 기반 버전 식별자 지원

날짜 기반 버전을 배제하는 것은 pytz를 새 메타데이터 표준으로 이전하는 데 상당한 문제를 일으켰습니다. 이는 또한 OpenStack 개발자들에게도 우려를 불러일으켰는데, 그들은 날짜 기반 버전 관리 체계를 사용하며 이를 변경하지 않고도 새 메타데이터 표준으로 이전할 수 있기를 원하기 때문입니다.

버전 에포크 추가

버전 에포크는 Fedora 및 Debian Linux 배포판의 것과 같은 다른 버전 관리 체계에 포함된 것과 동일한 이유로 추가되었습니다. 즉, 새 릴리스가 이전 릴리스보다 낮은 버전 번호를 가진 것처럼 보이지 않게 하면서도 프로젝트의 이름을 바꾸지 않고도 릴리스 번호 부여 방식을 부드럽게 변경할 수 있도록 프로젝트에 허용하기 위해서입니다.

특히, 버전 에포크를 지원하면 이전에 날짜 기반 버전 관리를 사용하던 프로젝트가 새 버전 에포크를 지정함으로써 시맨틱 버전 관리로 전환할 수 있습니다.

! 문자는 다른 시스템에서 흔히 사용되는 : 문자 대신 에포크 버전을 구분하기 위해 선택되었는데, 이는 :가 Windows 디렉터리 이름에서 유효한 문자가 아니기 때문입니다.

직접 참조 추가

직접 참조(direct reference)는 표준 배포 모델에 깔끔하게 대응되지 않는 지저분한 실제 상황을 처리하기 위한 “탈출구(escape clause)”로 추가되었습니다. 여기에는 내부 사용을 위한 미공개 소프트웨어에 대한 의존성뿐 아니라, 서드파티 라이브러리를 C 확장으로 감쌀 때 발생할 수 있는 더 복잡한 호환성 문제를 처리하는 것도 포함됩니다(이는 과학 커뮤니티에서 특히 우려하는 사항입니다).

색인 서버(index server)는 주로 배포자보다는 통합자(integrator)를 위한 도구로 의도되었기 때문에, 직접 참조를 허용하지 않을 자유가 의도적으로 크게 부여되어 있습니다. 특히 PyPI는 신뢰할 수 없는 외부 서비스가 설치 작업 속도를 늦추고 PyPI 자체의 신뢰성 저하로 이어지는 효과가 있기 때문에, 외부 참조에 대한 의존성을 제거하는 과정을 현재 진행하고 있습니다.

임의 동등성(arbitrary equality) 추가

임의 동등성은 준수하지 않는 버전을 사용하는 프로젝트를 누군가 설치해야 하는 경우를 처리하기 위한 “탈출구”로 추가되었습니다. 이 PEP는 이미 PyPI에 있는 버전들과 약 97%의 호환성을 달성할 수 있지만, 여전히 파싱할 수 없는 버전이 약 3% 남아 있습니다. 이 연산자는 그것들이 의미하는 바를 “추측”할 필요 없이 여전히 의존할 수 있는 간단하고 효과적인 방법을 제공합니다(엄격한 문자열 기반 동등성 외의 다른 것이 지원되었다면 이러한 추측이 필요했을 것입니다).

로컬 버전 식별자(local version identifier) 추가

다운스트림 통합자가 업스트림 버그 수정을 이전 버전으로 백포트해야 하는 경우가 종종 있다는 것은 현실적인 사실입니다. 이는 리눅스 배포판 벤더가 대가를 받는 서비스 중 하나이며, 애플리케이션 개발자 또한 번들된 의존성에 필요한 패치를 적용할 수 있습니다.

역사적으로 이러한 관행은 플랫폼 간 언어별 배포 도구에는 보이지 않았습니다 — 업스트림 메타데이터에 보고된 “버전”은 수정되지 않은 코드와 동일합니다. 이러한 부정확성은 통합자가 제공한 코드와 수정되지 않은 업스트림 코드가 혼재된 상태로 작업하려 할 때, 혹은 단순히 소프트웨어의 정확한 설치 버전을 파악하려 할 때 문제를 일으킬 수 있습니다.

버전 관리 체계에 로컬 버전 식별자와 “로컬 버전 레이블(local version label)”을 도입하고, 이에 대응하는 python.integrator 메타데이터 확장을 함께 적용하면 이러한 종류의 활동을 정확하게 나타낼 수 있으며, 이는 업스트림 도구와 다양한 통합 플랫폼 간의 상호운용성을 개선할 것입니다.

선택된 정확한 체계는 대체로 기존의 pkg_resources.parse_versionpkg_resources.parse_requirements의 동작을 본떠 만들어졌으며, 주된 차이점은 pkg_resources가 현재 정확한 일치를 위해 버전을 비교할 때 항상 접미사를 고려하는 반면, 이 PEP는 버전 지정자 절에 로컬 버전 레이블이 없는 경우 후보 버전의 로컬 버전 레이블을 무시하도록 요구한다는 점입니다. 또한 이 PEP는 (허용되는 문자 집합을 제한하고 그 순서를 정의하는 것 외에는) 로컬 버전 레이블에 어떠한 구조도 강제하려 하지 않습니다.

이 변경은 통합자가 제공한 pip 1.5+1또는 pip 1.5+1.git.abc123de와 같은 버전이 pip>=1.5와 같은 버전 지정자를 계속 충족하도록 보장하기 위한 것입니다.

더하기 기호는 주로 로컬 버전 식별자의 가독성을 위해 선택되었습니다. 하이픈 대신 더하기 기호를 선택한 것은 pkg_resources.parse_version이 이를 사전 릴리스로 구문 분석하는 것을 방지하기 위해서이며, 이는 더욱 구조화된 새로운 버전 관리 체계로 성공적으로 마이그레이션하는 데 중요합니다. 물결표 대신 더하기 기호를 선택한 것은 Debian의 버전 순서 지정 알고리즘에서 물결표가 갖는 중요성 때문입니다.

명시적인 버전 정규화 규칙 제공

역사적으로 Python에서 버전을 구문 분석하는 사실상의 표준은 setuptools 프로젝트의 pkg_resources.parse_version명령이었습니다. 이 명령은 어떤 버전도 거부하려 하지 않고, 주어진 것이 무엇이든 성공 정도는 다양하지만 의미 있는 결과를 만들려고 합니다. 몇 가지 간단한 규칙이 있지만, 그 외에는 대체로 문자열 비교에 의존합니다.

이 PEP에서 제공하는 정규화 규칙은 주로 pkg_resources.parse_version과의 호환성을 높이거나, 특히 rev, r, pre등 문서화된 사용 사례에서의 호환성을 높이거나, PyPI에 이미 존재하는 버전을 더 합리적으로 처리하기 위해 마련되었습니다.

가능한 모든 정규화 규칙은 모호성을 일으킬 가능성이 높은지 여부를 기준으로 평가되었습니다. (예를 들어 누군가 v1.01.0을 서로 다른 릴리스로 간주하는 체계를 고안할 수는 있지만, 실제로 누군가가 그렇게 할 가능성, 특히 눈에 띄는 규모로 그렇게 할 가능성은 상당히 낮습니다.) 또한 특정 버전 문자열을 pkg_resources.parse_version이 어떻게 처리했는지, 특히 어떤 순서로 정렬했는지를 기준으로 평가했습니다. 마지막으로 각 규칙을 통해 허용되는 추가 버전의 종류, 그러한 버전이 얼마나 “보기 흉한지”, 구문 분석이 얼마나 어려운지(정신적으로나 기계적으로나), 그리고 얼마나 많은 추가 호환성을 제공하는지를 기준으로 평가했습니다.

가능한 정규화의 범위는 버전의 구문 분석 과정의 일부로 쉽게 구현할 수 있는 항목으로 제한했으며, 버전에 적용되는 사전 구문 분석 변환은 제외했습니다. 이는 각 변환의 부작용을 제한하기 위해서였습니다. 단순한 검색 및 치환 방식의 변환은 모호하거나 “쓰레기 같은” 버전이 될 가능성을 높이기 때문입니다.

고려된 다양한 정규화 유형에 대한 자세한 논의는 pip의 PEP 440개념 증명 [5]을 참조하십시오.

정규화에서 밑줄 허용하기

버전 문자열에 _를 사용하는 PyPI 프로젝트는 그리 많지 않습니다. 그러나 이 PEP는 -가 허용되는 모든 곳에서 이 문자를 사용할 수 있도록 합니다. 그 이유는 Wheel 정규화 방식이 파일명 파싱을 더 쉽게 하기 위해 -_로 정규화하도록 지정하고 있기 때문입니다.

PEP 440에 대한 변경 사항 요약

setuptools 8.0과 pip 6.0에서 최초의 참조 구현이 발표된 후 받은 피드백을 바탕으로 이 PEP에 다음과 같은 변경이 이루어졌습니다:

  • 배타적 순서 비교는 !=V.*를 암시하지 않도록 갱신되었는데, 이는 정확하게 설명하기가 너무 어려운, 놀라운 동작으로 여겨졌기 때문입니다. 대신 배타적 순서 비교는 지정된 버전의 프리릴리스, 포스트릴리스, 로컬 버전과의 매칭을 단순히 허용하지 않게 됩니다(지정된 버전 자체가 프리릴리스, 포스트릴리스 또는 로컬 버전인 경우는 예외입니다). 더 자세한 논의는 distutils-sig [6] [7]의 스레드를 참조하십시오.
  • 릴리스 후보의 정규화 형식이 ‘c’에서 ‘rc’로 변경되었습니다. 이 변경은 setuptools 8.0이 PyPI에 패키지를 게시하기 위해 준비할 때 생성되는 릴리스 메타데이터에 정규화를 적용하기 시작했을 때 받은 사용자 피드백을 바탕으로 이루어졌습니다 [8].
  • PEP 본문과 is_canonical 정규식은 숫자 구성 요소가 임의의 유니코드 [Nd] 코드 포인트가 아니라 ASCII 숫자의 시퀀스로 표현되어야 함을 명시적으로 요구한다는 점을 분명히 하도록 갱신되었습니다. 이는 이전에 부록 B의 버전 파싱 정규식에서 암시되었지만, 명시적으로 언급되지는 않았습니다 [10].

참고 문헌

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

부록 A

Metadata v2.0 지침 대 setuptools:

$ invoke check.pep440
Total Version Compatibility:              245806/250521 (98.12%)
Total Sorting Compatibility (Unfiltered): 45441/47114 (96.45%)
Total Sorting Compatibility (Filtered):   47057/47114 (99.88%)
Projects with No Compatible Versions:     498/47114 (1.06%)
Projects with Differing Latest Version:   688/47114 (1.46%)

부록 B: 정규 표현식으로 버전 문자열 파싱하기

앞서 Public version identifiers 절에서 언급했듯이, 공개되는 버전 식별자는 정규 형식(canonical format)을 사용해야 합니다(SHOULD). 이 절에서는 어떤 버전이 이미 그 형식으로 되어 있는지 검사하고, 그렇지 않은 경우 후속 정규화를 위해 각 구성 요소를 추출하는 데 사용할 수 있는 정규 표현식을 제공합니다.

버전 식별자가 정규 형식인지 검사하려면 다음 함수를 사용할 수 있습니다.:

import re
def is_canonical(version):
    return re.match(r'^([1-9][0-9]*!)?(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))*((a|b|rc)(0|[1-9][0-9]*))?(\.post(0|[1-9][0-9]*))?(\.dev(0|[1-9][0-9]*))?$', version) is not None

버전 식별자의 구성 요소를 추출하려면 (packaging프로젝트에서 정의한) 다음 정규 표현식을 사용하십시오.:

VERSION_PATTERN = r"""
    v?
    (?:
        (?:(?P<epoch>[0-9]+)!)?                           # epoch
        (?P<release>[0-9]+(?:\.[0-9]+)*)                  # release segment
        (?P<pre>                                          # pre-release
            [-_\.]?
            (?P<pre_l>alpha|a|beta|b|preview|pre|c|rc)
            [-_\.]?
            (?P<pre_n>[0-9]+)?
        )?
        (?P<post>                                         # post release
            (?:-(?P<post_n1>[0-9]+))
            |
            (?:
                [-_\.]?
                (?P<post_l>post|rev|r)
                [-_\.]?
                (?P<post_n2>[0-9]+)?
            )
        )?
        (?P<dev>                                          # dev release
            [-_\.]?
            (?P<dev_l>dev)
            [-_\.]?
            (?P<dev_n>[0-9]+)?
        )?
    )
    (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))?       # local version
"""

_regex = re.compile(
    r"^\s*" + VERSION_PATTERN + r"\s*$",
    re.VERBOSE | re.IGNORECASE,
)