본문 바로가기
목차
Python

[Etc] SW Version: Semantic Versioning + packaging.version

by ds31x 2024. 9. 19.
728x90
반응형

1. Semantic Versioning System

Semantic Versioning (SemVer) 시스템에 따라,

소프트웨어에서 major와 minor, patch (or micro) 버전을 구분하여 버전을 매김.

Python에서는 PEP 440 에서 버전 표기 방식을 지정하고 있으며 SemVer와 거의 유사함.

이는 버전 번호를 MAJOR.MINOR.PATCH 형식으로 표현.

  1. MAJOR 버전:
    • 이전 버전과 호환되지 않는 API 변경이 있을 때 증가.
    • 큰 기능 변경이나 구조적 변화가 있을 때 증가.
  2. MINOR 버전:
    • 이전 버전과 호환되는 새로운 기능을 추가할 때 증가.
    • 기존 기능의 개선이나 작은 변경사항이 있을 때 증가.

3. PATCH 버전 (or Micro 버전):

  • 버그 수정이나 성능 개선과 같은 작은 변경사항이 있을 때 증가.
  • 기능 변경이 아닌 버그 및 오류 수정이나 성능 개선(기능 및 API는 유지)만 허용.

예를 들어, 버전 2.1.3에서:

  • 2는 MAJOR 버전
  • 1은 MINOR 버전
  • 3은 PATCH 버전

2. Python의 package.version

Python의 경우 version 의 문자열을 parse하여

  • 대소비교,
  • 정렬,
  • 유효성 검사,
  • 또는 각 속성을 쉽게 접근케 해주는
  • package.version 모듈을 제공.

2-1. 버전 형식

Python Enhancement Proposal 440의 일반 버전 형식.

pep440_regex = r"""
^
(?:(?P<epoch>[0-9]+)!)?                          # epoch (optional)
(?P<release>[0-9]+(?:\.[0-9]+)*)                 # release segment (e.g., 1.2 or 1.2.3)
(?P<pre>
    (?P<pre_l>(a|b|rc))
    (?P<pre_n>[0-9]+)
)?                                               # pre-release (e.g., a1, rc2) (optional)
(?P<post>
    (?:\.post(?P<post_n>[0-9]+))
)?                                               # post-release (optional)
(?P<dev>
    (?:\.dev(?P<dev_n>[0-9]+))
)?                                               # dev-release (optional)
(?P<local>
    \+
    (?P<local_ver>[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*)
)?                                               # local version (optional)
$
"""

import re

pattern = re.compile(pep440_regex, re.VERBOSE)
match = pattern.match("1!2.0.0rc1.post2.dev3+gpu.1")

print(match.groupdict())


# {
#  'epoch': '1',
#  'release': '2.0.0',
#  'pre': 'rc1',
#  'pre_l': 'rc',
#  'pre_n': '1',
#  'post': '.post2',
#  'post_n': '2',
#  'dev': '.dev3',
#  'dev_n': '3',
#  'local': '+gpu.1',
#  'local_ver': 'gpu.1'
# }

Regular Expression의 meta character를 이용하여 표현됨.

 

1!2.0.0rc1.post2.dev3+gpu.1

  • 1! : epoch = 1 임
  • 2.0.0 : major=2, minor=0, patch=0
  • rc1 : release candidate (릴리즈 직전의 테스트 버전임을 의미) 이며 그 중 1번째 후보임.
  • .post2 : rc1이 이후, 문서나 메타데이터 수정 등의 마이너 업데이트가 가해진 2번째 포스트 릴리즈 (두번째 보완 버전)
  • .dev3 : 개발 단계에서 작업중인 3번째 내부 개발 버전 (development release)으로 이게 없는 .post2 보다도 낮은 우선순위임.
  • +gpu.1 : local version으로 배포자(회사, 개발그룹, 개발자)가 붙이는 내부 버전 (GPU지원 관련 빌드임을 의미)
epoch 1, 버전 2.0.0의 첫 번째 릴리스 후보(rc1)에 대해 두 번째 수정(post2)을 반영한 버전이며, 이 버전은 아직 정식 릴리스되지 않은 상태로 릴리스를 위한 세 번째 개발 단계(dev3)에 해당함. 추가적으로, 해당 버전은 GPU 특화 로컬 빌드(+gpu.1)임.

 


2-2. 주요 Attributes

packaging.version 모듈의 Version 객체에 대해 주요 Attributes (PEP 440 기준):

  1. major: base_version의 메이저 버전 번호 (int)
  2. minor: base_version의 마이너 버전 번호 (int)
  3. micro: base_version의 마이크로(패치) 버전 번호 (int)
  4. pre: 프리릴리즈 정보 (tuple 또는 None)
    • SemVersion에선 - 하이픈 기호 뒤에 기재되지만, PEP 440에서 base_version 정보 뒤에 a,b,rc로 시작하는 형태임.
      • a: alpha (PEP 440에선 a와 alpha 둘 다 허용)
      • b: beta (PEP 440에선 b와 beta 둘 다 허용)
      • rc: release candidate
      • dev보다는 높은 우선순위로 a<b<rc 순임.
    • 아직 완전히 테스트되지 않았거나 불안정할 수 있는 버전 으로 동일한 base_version 만을 가지는 정식 릴리스 버전보다 낮은 우선순위를 가짐.
      • 정식 릴리스 전의 버전: 정식 릴리즈는 a,b,rc등의 postfix 없으며 pre-release보다 높은 우선순위를 가짐.
    • 예: 1.0.0a1, 2.3.0b2, 3.1.0rc1
  5. post: 포스트릴리즈 번호 (tuple 또는 None)
    • 앞에 기재된 버전의 공개 이후의 minor 수정본임을 나타냄:
      • 1!2.0.0rc1.post2 이라면 1!2.0.0rc1 버전의 공개 이후 2번째 수정본이라는 뜻임.
    • base_version 또는 프리릴리즈 뒤에 놓이며, period `.` 로 시작됨. 
      • 주로 버그 수정이나 문서 업데이트 등 작은 변경사항에 사용.
      • 기능적으로는 원래 버전과 동일.
      • 앞에 기재된 버전 보다 높은 우선순위를 가짐 (최신).
    • 예: 1.0.0.post1 , 2.3.0.post2
  6. dev: 개발 릴리스 번호 (int 또는 None)
    • 개발 중인 버전을 나타내며 가장 낮은 우선순위를 가짐.
    • base_version 또는 프리릴리즈, 포스트릴리즈 뒤에 놓이며, period `.` 로 시작됨. 
      • 주로 다음 버전을 위해 개발 진행 중인 작업을 표시.
      • 매우 불안정하고 자주 변경될 수 있습니다.
    • 예: 1.1.0.dev1, 2.0.0.dev20
  7. local: 로컬 버전 식별자 (str 또는 None)
    • SemVer의 빌드메타데이터처럼, + 기호 뒤에 나타나며, 버전 비교에서 주요 우선순위에 영향을 주지 않음.
      • 버전의 핵심 기능이나 API호환성에 영향을 주지않는 추가적인 정보를 제공하는 역할.
      • 빌드 정보나 환경별 변경 사항이 기재됨.
    • 뒤에 번호가 올 수 있으나 문자열과 사이에 period `.`가 놓임.
    • 예: 1.1.0+abc.1
  8. public: 공개 버전 식별자 (str)
    • base_version에 pre,post, dev 등의 정보 포함.
    • 버전 비교에 영향을 주는 버전 문자열임.
  9. base_version: 기본 버전 (메이저.마이너.마이크로)
  10. epoch: 버전의 에포크 (int)
    • Epoch는 주로 버전 번호 체계를 변경해야 할 때 사용.
    • 생략되면 0이라고 보면 됨.
    • 이전에 잘못된 버전 넘버를 썼을 때, 강제로 새 버전을 더 높게 만들고 싶을 때 사용
    • 맨 앞에 놓이며 !로 끝남.
    • 높은 epoch의 버전은 항상 낮은 epoch의 버전보다 우선시 됨 (가장 높은 우선순위로 정식버전보다도 우선순위가 높음)
      • 1!1.0.0 > 3.0.0 이 성립 (클수로 최신 버전을 의미함).
    • 일반 개발자들은 그리 많이 볼 일은 없음.
    • 예: 2!1.0.0은 두 번째 버전 체계의 1.0.0 버전을 의미

2-3. 예제0:

from packaging import version

v = version.parse("1.2.3rc1+build.4")

print(f"Major: {v.major}")
print(f"Minor: {v.minor}")
print(f"Micro: {v.micro}")
print(f"Pre-release: {v.pre}")
print(f"Post-release: {v.post}")
print(f"Dev release: {v.dev}")
print(f"Local: {v.local}")
print(f"Public: {v.public}")
print(f"Base version: {v.base_version}")
print(f"Epoch: {v.epoch}")

 

이 코드의 출력은 다음과 같음:

Major: 1
Minor: 2
Micro: 3
Pre-release: ('rc', 1)
Post-release: None
Dev release: None
Local: build.4
Public: 1.2.3rc1
Base version: 1.2.3
Epoch: 0

2-4. Version Precedence

버전이 최신일수록 크다고 판정(우선순위를 가짐)한다.

 

다음을 참고:

1.0.0.dev1 < 1.0.0a1 < 1.0.0b1 < 1.0.0rc1 < 1.0.0 < 1.0.0.post1

2-5. 예제1

from packaging import version

v1 = version.parse("1.2.3")
v2 = version.parse("2.0.0")

# 비교 연산자 사용
print(v1 < v2)  # True
print(v1 == v2)  # False
print(v1 > v2)  # False

# 버전 간 대소 비교
print(version.parse("1.2.3") < version.parse("1.3.0"))  # True

# 버전 정렬
versions = ["1.0.0", "2.0.0", "1.2.3", "1.2.0", "1.0.1"]
sorted_versions = sorted(versions, key=version.parse)
print(sorted_versions)
# ['1.0.0', '1.0.1', '1.2.0', '1.2.3', '2.0.0']

# 버전 유효성 검사
try:
    version.parse("invalid.version")
except version.InvalidVersion:
    print("Invalid version string")

2-6. 참고

  • rc : release candidate 의 약자. alpha, beta 이후의 단계로 release 직전인 상태. 큰 에러가 없다면 release가 됨.
  • local version identifier: "1.2.3rc1+build.4"에서 "+" 기호
    • 의미:
      • 공식 릴리스 버전에 영향을 주지 않는 추가 정보를 제공.
      • 빌드 정보, 날짜 스탬프, 또는 기타 메타데이터를 포함할 수 있음.
      • PEP 440 (Python 버전 규격)에 정의되어 있습니다.
    • 구조:
      • + 기호 이후의 모든 것이 로컬 버전 식별자.
      • 이 예에서는 build.4가 로컬 버전 식별자임.
    • 특징:
      • 로컬 버전은 버전 비교에 영향을 주지 않음.
      • 동일한 공식 버전의 다른 빌드나 변형을 구분하는 데 사용됨.

같이 보면 좋은 자료들

2024.05.20 - [utils/git and github] - Git : 소개

 

Git : 소개

Git은 코드의 변경 이력을 효율적으로 관리하고 협업을 가능하게 해주는 분산 버전 관리 시스템(distributed version control system, DVCS)1. Git은 분산형 버전 관리 시스템다양한 환경에서 소스코드를 버전

ds31x.tistory.com


 

728x90

'Python' 카테고리의 다른 글

[Py] assert 구문 (statement)  (1) 2024.09.24
[CV] cv2.calibrateCamera  (1) 2024.09.22
[Summary] NumPy(Numerical Python)  (3) 2024.09.12
[Py] sys.exit()  (1) 2024.09.11
[Py] Namespace Package  (0) 2024.09.11