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

Python 개선 제안 한국어 번역

PEP 413 – Python 표준 라이브러리의 더 빠른 발전

Author:
Alyssa Coghlan <ncoghlan at gmail.com>
Status:
Withdrawn
Type:
Process
Created:
24-Feb-2012
Post-History:
24-Feb-2012, 25-Feb-2012

Table of Contents

번역·라이선스 안내

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

PEP 철회

pip이 대부분의 신규 Python 사용자에게 기본적으로 제공된다는 PEP 453의 수용으로, 모듈이 충분히 성숙하기 전에 표준 라이브러리에 새 모듈을 추가해야 한다는 압력이 줄어들 것으로 기대합니다.

지난 몇 년 동안에는 표준 라이브러리 패키지에 해당하는 패키지가 Python 패키지 색인에도 제공되며 이전 버전의 Python도 지원하는 모델의 사용이 증가했습니다.

이러한 두 가지 발전과 Python 3.4 릴리스 주기 전반의 참여 수준을 고려할 때, PEP 작성자는 더 이상 표준 라이브러리 개발 프로세스에 이처럼 근본적인 변경을 가하는 것이 적절하다고 생각하지 않습니다.

초록

이 PEP는 표준 라이브러리에 대해 기존 언어 버전 관리 체계와는 별개이면서도 연계된 별도의 버전 관리 체계를 채택하여 Python 표준 라이브러리의 릴리스를 가속화하는 한편, 핵심 언어 정의의 현재 변경 속도는 유지하거나 오히려 늦추는 방안을 제안합니다.

이 PEP는 PEP 407과 마찬가지로, 더 넓은 커뮤니티가 적응할 시간을 제공하는 점진적인 변화와 현재 릴리스 주기로는 따라가기 어려울 정도로 빠르게 발전하는 외부 영향에 보조를 맞출 수 있는 능력 사이의 현재 균형을 조정하는 것을 목표로 합니다(이 문제는 웹 기술과 관련된 표준 라이브러리 요소에서 특히 두드러집니다).

그러나 PEP 407보다 목표가 더 보수적이며, 언어 구문과 버전 번호 지정뿐 아니라 CPython 바이너리 API 및 바이트코드 형식과 같은 다른 요소의 변경 속도에는 영향을 주지 않고, 개발 속도의 증가를 내장 인터페이스와 표준 라이브러리 인터페이스로 제한하고자 합니다.

근거

다음은 PEP 407의 초록에서 인용한 내용입니다.

오픈 소스 프로젝트의 릴리스 주기를 정하는 일은 개발자 인력, 릴리스 관리 자원봉사자의 가용성, 사용자와 서드파티 패키지 관리자를 위한 유지 관리의 용이성, 새로운 기능과 동작 변경을 신속하게 이용할 수 있는 가능성, 새로운 기능이나 동작 변경을 포함하지 않고 버그 수정을 이용할 수 있는 가능성처럼 서로 모순되는 제약 조건을 관리해야 하는 섬세한 작업입니다.

현재 릴리스 주기는 보수적인 쪽으로 치우쳐 있습니다. 안정성을 반응성보다 중시하는 사람들에게는 적절합니다. 이 PEP는 장기 지원 버전이라는 개념을 도입하여, Python의 상징이 된 안정성을 유지하면서 더욱 유연하게 기능을 릴리스하려는 시도입니다.

일부 주요 프로그래밍 영역(구체적으로는 데이터베이스, 템플릿 및 직렬화 형식을 비롯한 웹 프로토콜과 관련 기술)의 변화 속도에 효과적으로 대응하기에는 표준 라이브러리의 현재 릴리스 주기가 너무 느리다는 PEP 407 작성자들의 의견에 동의합니다.

그러나 PEP 407에서 제안한 6개월마다 완전하고 잠재적으로 바이너리 호환성이 없는 CPython 릴리스를 제공하는 접근 방식이 더 넓은 Python 생태계에 지나치게 큰 부담을 준다고 생각하기 때문에 이 경쟁 PEP를 작성했습니다.

현재 CPython 릴리스 주기에서는 주요 바이너리 확장 기능의 배포자들이 CPython 브랜치가 “보안 수정만” 모드에 들어간 후에도 Python 릴리스를 지원하는 경우가 많습니다. 예를 들어 Twisted는 현재 2.5, 2.6 및 2.7용 바이너리를 제공하고, NumPy와 SciPy는 이 세 버전과 함께 3.1 및 3.2도 지원하며, PyGame은 2.4 바이너리 릴리스를 추가하고, wxPython은 2.6 및 2.7용 32비트와 64비트 바이너리를 모두 제공하는 식입니다.

CPython의 릴리스 속도가 세 배 이상 빨라진다면, 해당 라이브러리의 개발자들(그중 다수는 CPython보다도 자원이 부족합니다)은 달갑지 않은 선택에 직면하게 됩니다. 즉, 더 빠른 릴리스 주기를 스스로 채택하거나(PyGame의 경우 동시에 최대 18개의 바이너리 릴리스가 필요합니다!), 이전 Python 버전을 더 빠르게 중단하거나, 사용자에게 CPython LTS 릴리스를 계속 사용하라고 말해야 합니다. 이는 애초에 CPython 릴리스 주기를 가속하는 전체 목적을 무력화합니다.

마찬가지로 Python을 위한 많은 지원 도구(예: 구문 강조 도구)는 언어 수준의 변경을 따라잡는 데 상당한 시간이 걸릴 수 있습니다.

문화적 측면에서도 Python 커뮤니티는 Python 버전 번호에 특정한 의미가 있다는 데 익숙합니다. 버전 번호는 사용 중단 기간, 지원 기간 등 온갖 것과 연결되어 있습니다. PEP 407은 그러한 집단적 지식을 모두 쓸어버리자고 제안하면서, 다른 모든 사람을 희생해 CPython 핵심 개발자들의 일을 조금 더 쉽게 만드는 것 외에는 왜 그러한 조치가 실제로 필요한지에 대한 설득력 있는 근거를 제시하지 않습니다.

그러나 변경 속도를 높이는 주요 근거(즉, 웹 프로토콜과 관련 기술에 대한 보다 시의적절한 지원)로 돌아가 보면, 그러한 지원에는 표준 라이브러리 변경만 필요하다는 점을 알 수 있습니다. 따라서 새 릴리스 주기의 영향을 받는 CPython의 부분을 명시적으로 제한하고 다른 부분은 현재의 더욱 완만한 속도로 발전하도록 허용하면, 더 넓은 커뮤니티에 미치는 부정적인 영향의 상당 부분(어쩌면 대부분)을 피할 수 있습니다.

제안

이 PEP는 새로운 종류의 CPython 릴리스인 “표준 라이브러리 릴리스”의 도입을 제안합니다. 이 PEP는 PEP 407과 마찬가지로 CPython에 세 가지 릴리스 유형을 제공합니다:

  • 언어 릴리스: “x.y.0”
  • 유지 관리 릴리스: “x.y.z”(z > 0인 경우)
  • 표준 라이브러리 릴리스: “x.y (xy.z)”(z > 0인 경우)

이 체계에서 한정되지 않은 버전 참조(예: “3.3”)는 항상 해당하는 최신 언어 릴리스 또는 유지 관리 릴리스를 가리킵니다. 표준 라이브러리 릴리스를 가리키는 데 한정 없이 사용되는 일은 절대 없습니다(적어도 python-dev에서는 그렇습니다. 물론 우리는 본보기를 보일 수 있을 뿐이며, 나머지 Python 생태계가 따르도록 강제할 수는 없습니다).

언어 릴리스는 현재와 마찬가지로 Python 언어 정의의 새 버전과 CPython 인터프리터 및 Python 표준 라이브러리의 새 버전으로 계속 제공됩니다. 따라서 언어 릴리스에는 다음 변경 사항이 일부 또는 전부 포함될 수 있습니다:

  • 새로운 언어 구문
  • 새로운 표준 라이브러리 변경 사항(아래 참조)
  • 새로운 사용 중단 경고
  • 이전에 사용 중단된 기능의 제거
  • 생성되는 바이트코드의 변경
  • AST의 변경
  • 컴파일 도구 체인의 그 밖의 중요한 변경 사항
  • 핵심 인터프리터 평가 루프의 변경
  • C ABI의 바이너리 비호환 변경(단, PEP 384의 안정 ABI는 계속 유지되어야 합니다)
  • 버그 수정

유지보수 릴리스도 현재와 마찬가지로 계속 제공되며, 해당 언어 릴리스의 버그 수정으로 엄격히 제한됩니다. 새로운 기능이나 급격한 내부 변경은 허용되지 않습니다.

새로운 표준 라이브러리 릴리스는 각 유지보수 릴리스와 병행하여 제공되며, 표준 라이브러리 버전을 명시하는 새 버전 식별자가 부여됩니다. 표준 라이브러리 릴리스에는 다음 변경 사항이 포함될 수 있습니다:

  • 순수 Python 모듈의 새로운 기능
  • C 확장 모듈의 새로운 기능(PEP 399의 호환성 요구 사항 적용)
  • 언어 내장 기능의 새로운 기능(C ABI가 영향을 받지 않는 경우)
  • 해당 유지보수 릴리스의 버그 수정

표준 라이브러리 버전 식별자는 Python 언어 릴리스의 주 버전 번호와 부 버전 번호를 결합하여 두 자리 숫자로 만든 다음, 순차적인 표준 라이브러리 버전 식별자를 덧붙여 구성합니다.

릴리스 주기

유지보수 릴리스가 생성되면 실제로는 Python의 가지 새 버전이 python.org에 게시됩니다(2013년 2월로 예정된 첫 번째 3.3 유지보수 릴리스를 예로 들 수 있습니다).:

3.3.1       # Maintenance release
3.3 (33.1)  # Standard library release

그로부터 6개월 후에는 다음 3.3 유지보수 릴리스에 다시 새로운 표준 라이브러리 릴리스가 함께 제공됩니다.:

3.3.2       # Maintenance release
3.3 (33.2)  # Standard library release

다시 말해 표준 라이브러리 릴리스는 이전 언어 릴리스와 바이너리 호환성을 유지하면서 Python 수준에서 추가 기능만 제공합니다.

마지막으로 3.3 릴리스 후 18개월이 지나면 최종 3.3 유지보수 릴리스 및 표준 라이브러리 릴리스와 거의 같은 시기에 새로운 언어 릴리스가 제공됩니다.:

3.3.3       # Maintenance release
3.3 (33.3)  # Standard library release
3.4.0       # Language release

그러면 3.4 릴리스 주기는 3.3의 릴리스 주기와 유사한 패턴을 따릅니다.:

3.4.1       # Maintenance release
3.4 (34.1)  # Standard library release

3.4.2       # Maintenance release
3.4 (34.2)  # Standard library release

3.4.3       # Maintenance release
3.4 (34.3)  # Standard library release
3.5.0       # Language release

프로그래밍 방식의 버전 식별

새 버전 세부 정보를 프로그래밍 방식으로 노출하기 위해, 이 PEP에서는 기반 인터프리터 버전을 넘어 새로운 표준 라이브러리 버전을 기록하는 새 sys.stdlib_info속성을 추가할 것을 제안합니다. 초기 Python 3.3 릴리스를 예로 들면:

sys.stdlib_info(python=33, version=0, releaselevel='final', serial=0)

이 정보는 sys.version문자열에도 포함됩니다.:

Python 3.3.0 (33.0, default, Feb 17 2012, 23:03:41)
[GCC 4.6.1]

보안 수정 및 그 밖의 “주기 외” 릴리스

유지보수 릴리스의 경우, 보안 문제를 수정하거나 새 릴리스의 치명적인 버그를 해결하기 위한 예외적인 릴리스를 처리하는 과정은 현재와 동일하게 유지됩니다. 마이너 버전 번호를 증가시키고, 필요한 버그 수정과 이전 릴리스 이후 커밋된 다른 모든 버그 수정을 포함하는 새 릴리스를 만듭니다.

표준 라이브러리 릴리스의 경우에도 과정은 본질적으로 동일하지만, 표준 라이브러리 릴리스에는 버그 수정뿐만 아니라 새로운 기능도 포함될 수 있으므로 해당 릴리스에 맞게 관련 “What’s New?” 문서를 약간 정리해야 할 수 있습니다.

사용자 시나리오

위에서 제안한 버전 관리 체계는 이 체계를 채택할 경우 접하게 될 가능성이 높은 여러 사용자 시나리오를 기반으로 합니다. 각 경우에 대해 현 상태(즉, 느린 릴리스 주기), 이 PEP의 버전 관리 체계, 그리고 PEP 407에서 제안된 자유로운 마이너 버전 번호 체계에 대한 시나리오를 설명합니다.

결말을 미리 말하자면, 별도의 버전 번호를 사용하는 핵심 이유는 거의 모든 시나리오에서 중요한 번호가 표준 라이브러리 버전이 아니라 language 버전이기 때문입니다. 대부분의 사용자는 표준 라이브러리 버전 번호가 존재한다는 사실조차 신경 쓸 필요가 없습니다. 그것이 중요한 두 가지 확인된 경우에는 두 종류의 번호를 하나의 시퀀스에 삽입한 다음 통합된 시퀀스의 일부 번호를 특별한 것으로 표시하는 것보다 별도의 번호로 제공하는 편이 실제로 더 명확하고 구체적입니다.

2013년 3월 python.org에서 Python을 내려받는 초보 사용자

현 상태: 3.3과 2.7 중에서 선택해야 합니다.

이 PEP: 3.3 (33.1), 3.3, 2.7 중에서 선택해야 합니다.

PEP 407: 3.4, 3.3 (LTS), 2.7 중에서 선택해야 합니다.

판정: 장기 지원 릴리스의 의미를 설명하는 일은 제안된 표준 라이브러리 릴리스 버전 번호의 의미를 설명하는 일만큼이나 복잡합니다. 동률이라고 판단합니다.

서드파티 문서의 최신성을 판단하려는 초보 사용자

현 상태: 마이너 버전 차이는 18~24개월의 언어 발전을 나타냅니다.

이 PEP: 언어 코어에 대해서는 현 상태와 동일하고, 표준 라이브러리 버전 번호는 6개월의 표준 라이브러리 발전을 나타냅니다.

PEP 407: 마이너 버전 차이는 3.3까지는 18~24개월의 언어 발전을, 그 이후에는 6개월의 언어 발전을 나타냅니다.

판정: 언어 변경과 사용 중단 예정 처리는 표준 라이브러리에 새로운 기능을 추가하는 것보다 서드파티 문서의 정확성에 훨씬 큰 영향을 미칠 수 있으므로, 이 PEP의 체계가 승리했다고 판단합니다.

확장 모듈 바이너리 릴리스를 찾는 초보 사용자

현 상태: 현재 실행 중인 Python 버전에 해당하는 바이너리를 찾습니다.

이 PEP: 현 상태와 동일합니다.

PEP 407 (전체 릴리스): 현 상태와 동일하지만, 해당 바이너리 버전이 누락될 가능성이 더 높습니다. 존재하더라도 훨씬 더 많은 대안 목록에서 찾아야 합니다.

PEP 407 (LTS 릴리스로 제한된 ABI 업데이트): 모든 바이너리 릴리스 페이지에서 Python 3.3, 3.4, 3.5에는 모두 3.3 바이너리가 필요하다고 사용자에게 알려야 합니다.

판정: 이 PEP의 체계가 명백히 우세하다고 판단합니다. 이 경우 표준 라이브러리 버전은 실제로 중요하지 않고 바이너리 확장 호환성만 중요하므로, 현재 상황에서 전혀 달라지는 것이 없습니다.

바이너리 릴리스를 만들지 결정하는 확장 모듈 작성자

현 상태: PEP 384안정 ABI를 사용하지 않는 한, 마이너 버전 번호가 변경될 때마다 새 바이너리 릴리스가 필요합니다.

이 PEP: 현 상태와 동일합니다.

PEP 407 (전체 릴리스): 현 상태와 동일하지만, 이러한 일이 훨씬 더 자주 발생합니다.

PEP 407 (LTS 릴리스로 제한된 ABI 업데이트): 결정하기 전에 먼저 새 릴리스가 LTS 릴리스인지 중간 릴리스인지 조회해야 합니다. LTS 릴리스라면 새 빌드가 필요합니다.

판정: 이 PEP의 방안이 이번에도 명백한 승리라고 판단합니다. 이 문제의 최종 사용자 대면 측면과 마찬가지로, 이 경우에는 표준 라이브러리 버전이 실제로 무관합니다. 해당 정보를 별도의 번호로 분리하면 불필요한 혼란을 피할 수 있습니다.

Deprecation Warning 제거의 우선순위를 결정하는 Python 개발자

현 상태: 사용 중단 경고를 발생시키는 코드가 더 높은 마이너 버전 번호의 Python 버전에서 실행된다고 보장되지 않습니다.

이 PEP: 현 상태와 동일합니다.

PEP 407: 이 PEP가 현재 이를 명시적으로 설명하지 않으므로 불명확합니다. 사용 중단 주기가 LTS 릴리스와 연계된다고 가정하면, 비 LTS 릴리스로 업그레이드하는 것은 안전하지만 다음 LTS 릴리스로 업그레이드하려면 사용 중단된 구문을 피해야 할 수 있습니다.

판정: 다시 한번 이 시나리오에서는 표준 라이브러리 버전이 무관하므로, 이 PEP의 방안이 또 하나의 명백한 승리라고 판단합니다.

새로운 기능으로 업데이트하는 대체 인터프리터 구현자

현 상태: 새로운 Python 버전은 드물게 출시되지만, 표준 라이브러리 업데이트와 핵심 언어 정의 및 인터프리터 변경이 뒤섞여 있습니다.

이 PEP: 통합하기 더 쉬운 표준 라이브러리 업데이트가 이전 버전의 언어 정의와 명백하고 명시적으로 호환되는 형태로 더 자주 제공됩니다. 이는 대체 구현이 Python 3.3을 따라잡고 나면 표준 라이브러리 기능이 추가되는 즉시 이를 통합하기가 훨씬 쉬워진다는 의미입니다(특히 순수 Python 변경 사항의 경우). 그 결과 마이너 버전 번호 업데이트가 핵심 컴파일 및 실행 구성 요소의 업데이트를 필요로 하는 유일한 작업으로 남습니다.

PEP 407(전체 릴리스): 현 상태와 동일하지만, 훨씬 더 자주 발생합니다.

PEP 407(LTS 릴리스로 제한된 언어 업데이트): 이 PEP가 현재 구체적인 개발 전략을 명시하지 않으므로 불명확합니다. (이 PEP에서 제안한 대로) 3.3 호환성 브랜치를 채택한다고 가정하면 결과는 거의 동일하지만, 특정 릴리스가 LTS 릴리스인지 확인해야 하므로 버전 번호의 표시는 약간 덜 명확해집니다.

판정: 앞선 일부 시나리오만큼 명확하지는 않지만, 이번에도 이 PEP의 방안에 유리하다고 판단합니다. 명시적인 것이 암묵적인 것보다 낫고, 이 PEP의 방안은 평범한 릴리스 번호에 별도의 “LTS” 태그를 추가하는 대신 서로 다른 두 종류의 업데이트를 명확히 구분합니다. 특정 버전을 특별한 것으로 태그하는 것은 버전 관리 시스템 및 관련 자동화 도구와 정보를 주고받는 데는 훌륭하지만, 다른 사람에게 정보를 전달하는 방법으로는 형편없습니다.

최소 버전 의존성을 결정하는 Python 개발자

현 상태: 문서에서 “추가된 버전” 또는 “변경된 버전” 표시를 찾고, sys.version_info를 기준으로 확인합니다.

이 PEP: 문서에서 “추가된 버전” 또는 “변경된 버전” 표시를 찾습니다. “3.3”과 같이 Python 버전만 단독으로 적혀 있으면 sys.version_info를 기준으로 확인합니다. “3.3 (33.1)”과 같이 표준 라이브러리 버전이 함께 적혀 있으면 sys.stdlib_info를 기준으로 확인합니다.

PEP 407: 현 상태와 동일합니다.

판정: 이 PEP의 방안은 실제로 서드파티 라이브러리가 표준 라이브러리 기능을 채택하는 속도를 더 명시적으로 나타낼 수 있도록 합니다. 더 보수적인 프로젝트는 언어 버전에 의존성을 고정하고 표준 라이브러리 릴리스에 추가된 기능을 피할 가능성이 큽니다. 더 빠르게 움직이는 프로젝트는 대신 특정 표준 라이브러리 버전에 대한 의존성을 선언할 수 있습니다. 그러나 PEP 407은 현 상태를 유지한다는 장점이 있으므로, 근소한 차이이기는 하지만 이번에는 PEP 407을 지지한다고 판단합니다.

트래커 이슈를 재현하려는 Python 개발자

현 상태: 아직 제공되지 않았다면, 제보자에게 어떤 Python 버전을 사용하고 있는지 질문합니다. 대화형 프롬프트에 표시되는 처음 두 줄 또는 sys.version의 값을 요청하는 방식이 자주 사용됩니다.

이 PEP: 표준 라이브러리 버전도 포함하도록 sys.version이 업데이트되므로 현재 상태와 동일하지만, 추가적인 경우에도 필요할 수 있습니다(사용자가 자신의 Python 버전을 명시할 만큼 충분히 알고 있었지만, 그것만으로는 문제를 재현하기에 부족한 경우입니다).

PEP 407: 현재 상태와 동일합니다.

평가: PEP 407의 또 다른 근소한 승리입니다. 새로운 표준 라이브러리 버전은 Python 라이브러리(또는 자체 추적 시스템에서 Python 자체)의 문제를 보고할 때 사용자가 개발자에게 전달해야 할 수 있는 추가 정보입니다. 그러나 이를 sys.version에 포함하면 많은 문제 보고에 이미 해당 정보가 포함되며, 필요한 경우 요청하기도 쉽습니다.

보안 수정 사항을 처리하는 CPython 릴리스 관리자

현재 상태: 보안 수정 사항과 소스 관리하의 다른 버그 수정 사항을 포함하는 새 유지 보수 릴리스를 생성합니다. 보안 수정 사항만을 위해 열려 있는 모든 브랜치에 대해서도 소스 릴리스를 생성합니다.

이 PEP: 유지 보수 브랜치에 대해서는 현재 상태와 동일합니다. 또한 새 표준 라이브러리 릴리스를 생성합니다(보안 수정 사항과 함께 새로운 기능을 포함할 수도 있습니다). 보안 브랜치의 경우, 이전 유지 보수 브랜치와 표준 라이브러리 업데이트 브랜치 모두에 대해 소스 릴리스를 생성합니다.

PEP 407: 유지 보수 및 보안 브랜치에 대해서는 현재 상태와 동일하지만, 비 LTS 릴리스의 보안 수정 사항을 처리하는 방법은 현재 미해결 문제입니다.

평가: PEP 407이 이 시나리오를 실제로 처리하도록 업데이트되기 전까지는 이 PEP가 명백한 승리입니다.

영향

개발 주기에 미치는 영향

이 PEP는 PEP 407과 유사하게 새로운 기능의 제공을 더 세분화된 단위로 나눕니다. 언어 릴리스에 변경 사항을 한꺼번에 대량으로 반영하는 대신, 각 언어 릴리스에는 6개월 분량의 표준 라이브러리 변경 사항과 새로운 구문에 수반되는 변경 사항만 포함됩니다.

작업 흐름에 미치는 영향

이 PEP는 일반적인 작업 흐름에서 사용할 추가 브랜치를 하나 생성할 것을 제안합니다. 3.3 릴리스 후에는 다음 브랜치가 사용됩니다.:

2.7         # Maintenance branch, no change
3.3         # Maintenance branch, as for 3.2
3.3-compat  # New branch, backwards compatible changes
default     # Language changes, standard library updates that depend on them

새로운 기능을 작업할 때 개발자는 해당 기능이 표준 라이브러리 릴리스에 허용되는 변경 사항인지 결정해야 합니다. 허용된다면 3.3-compat에 체크인한 다음 default에 병합해야 합니다. 그렇지 않다면 default에 직접 체크인해야 합니다.

3.3-compat브랜치에서 이루어진 모든 변경 사항의 “version added” 및 “version changed” 표시는 언어 버전과 표준 라이브러리 버전을 모두 사용하여 표시해야 합니다. 예를 들면 “3.3 (33.1)”입니다.

default브랜치에서 직접 이루어진 변경 사항은 평소처럼 “3.4”로만 표시합니다.

3.3-compat브랜치는 3.3유지 보수 브랜치와 동시에 일반 개발이 종료됩니다. 3.3-compat브랜치는 3.3유지 보수 브랜치와 동일한 기간 동안 보안 수정 사항을 위해 계속 열려 있습니다.

버그 수정 주기에 미치는 영향

버그 수정 작업 흐름에 미치는 영향은 새로운 기능의 작업 흐름과 본질적으로 동일합니다. 변경 사항이 default브랜치에 도달하기 전에 거쳐야 하는 추가 브랜치가 하나 있습니다.

유지 보수 릴리스에서 치명적인 버그가 발견되면 문제를 해결하기 위해 새로운 유지 보수 릴리스와 표준 라이브러리 릴리스를 생성합니다. 버전 번호의 마지막 부분은 언어 버전과 표준 라이브러리 버전 모두에서 증가합니다.

표준 라이브러리 릴리스에는 중대한 버그가 발견되었지만 관련 유지보수 릴리스에는 영향을 주지 않는 경우, 새로운 표준 라이브러리 릴리스만 생성하고 표준 라이브러리의 버전 번호만 증가시킵니다.

이러한 상황에서는 표준 라이브러리 릴리스에 버그 수정만 포함되는 것이 아니라 추가 기능도 포함될 수도 있습니다. 새로운 기능이 섞이지 않은 only 버그 수정만 받는 데 관심이 있는 사람은 누구나 이미 새로운 표준 라이브러리 릴리스를 사용하는 대신 유지 보수 릴리스에 엄격히 의존하고 있다고 가정합니다.

커뮤니티에 미치는 영향

PEP 407은 커뮤니티에 미치는 영향에 대해 다음과 같이 말합니다.

안정성을 중시하는 사람들은 LTS 릴리스에 맞춰 동기화하기만 하면 되며, 제안된 수치를 적용할 경우 기간과 안정성 모두에서 유사한 지원 주기를 제공하게 됩니다.

저는 이 설명이 완전히 잘못되었다고 생각합니다. 세상은 그렇게 단순하지 않습니다. 대신 서드파티 모듈과 프레임워크 개발자들은 바이너리 업데이트를 통해 새로운 릴리스 주기의 전체 속도를 지원하라는 압박을 받게 되고, 교사와 책 저자들은 자신들이 Python의 “오래된” 버전만 다룬다는 불평을 듣게 될 것입니다(“3.3만 사용하고 있군요. 최신 버전은 3.5입니다!”) 등 여러 문제가 발생할 것입니다.

마이너 버전 번호가 과거보다 3배 빠르게 증가하기 시작하면, 그러한 인식이 정당한지 여부와 관계없이 언어의 안정성에 대한 인식도 하락할 것이라고 생각합니다.

변경 속도의 증가를 표준 라이브러리에 한정하고 이를 별도의 버전 번호로 명확히 구분하면, 우리가 갑자기 커뮤니티 구성원들에게 자체 개발 속도를 3배로 높이라고 요구하는 것이 아니라는 점을 커뮤니티의 나머지 구성원들에게 크게 안심시킬 수 있다고 생각합니다. 대신 이전에 릴리스된 Python 버전과 하위 호환되는 변경 사항까지도 모두 다음 언어 정의 업데이트 때까지 미루는 것이 아니라, 다음 언어 릴리스용 표준 라이브러리 업데이트를 6개월마다 분할하여 제공할 뿐입니다.

표준 라이브러리에 관한 한, PEP 407에 열거된 커뮤니티의 이점은 이 PEP에도 동일하게 적용됩니다.

알파 버전이나 Mercurial 스냅샷을 설치할 위험을 감수하지 않고도 새로운 기능에 신속하게 접근하기를 원하는 사람들은 현재보다 새로운 릴리스 주기에서 훨씬 더 많은 가치를 얻게 될 것입니다.

새로운 기능이나 개선 사항을 기여하려는 사람들은 자신의 기여가 일반 사용자에게 더 빠르게 제공된다는 사실을 알게 되므로 더욱 적극적으로 참여하게 될 것입니다.

더 빠른 릴리스 주기로 인해 더 많은 사람이 언어 정의에 대한 변경을 제안하기보다 표준 라이브러리에 기여하는 데 집중하게 된다면, 저는 그것을 나쁜 일이라고 생각하지 않습니다.

뉴스 업데이트 처리

새로운 내용은 무엇입니까?

“What’s New” 문서는 표준 라이브러리 릴리스와 언어 릴리스를 위한 별도의 문서로 분리됩니다. 따라서 3.3 릴리스 주기 동안에는 다음과 같은 문서를 보게 됩니다.

  • Python 3.3의 새로운 내용
  • Python 표준 라이브러리 33.1의 새로운 내용
  • Python 표준 라이브러리 33.2의 새로운 내용
  • Python 표준 라이브러리 33.3의 새로운 내용

그리고 마지막으로 다음 언어 릴리스를 보게 됩니다.

  • Python 3.4의 새로운 내용

표준 라이브러리 릴리스를 무시하는 사용자들을 위해 3.4의 “What’s New” 문서에서는 3.3 시리즈의 각 표준 라이브러리 릴리스에 대한 “What’s New” 문서로 연결되는 링크를 제공합니다.

NEWS

NEWS 파일의 병합 충돌은 이미 성가신 문제입니다. 이 PEP는 일반적인 작업 흐름에 추가 브랜치를 도입할 것을 제안하므로, 이 문제를 해결하는 일은 더욱 중요해집니다. Mercurial 단계가 어느 정도 도움이 될 수는 있지만, 문제를 완전히 제거하는 것이 바람직합니다.

Barry Warsaw가 제안한 한 가지 방법은 Twisted [2]에서 사용하는 방식과 유사한, 충돌이 발생하지 않는 변경 사항별 별도 파일 방식을 채택하는 것입니다.

현재 수동으로 업데이트되는 NEWS 파일이 3.3.0 릴리스에 사용된다는 점을 고려하면, 이러한 접근 방식의 한 가지 가능한 배치는 다음과 같을 수 있습니다.:

Misc/
  NEWS  # Now autogenerated from news_entries
  news_entries/
    3.3/
      NEWS # Original 3.3 NEWS file
      maint.1/ # Maintenance branch changes
        core/
          <news entries>
        builtins/
          <news entries>
        extensions/
          <news entries>
        library/
          <news entries>
        documentation/
          <news entries>
        tests/
          <news entries>
      compat.1/ # Compatibility branch changes
        builtins/
          <news entries>
        extensions/
          <news entries>
        library/
          <news entries>
        documentation/
          <news entries>
        tests/
          <news entries>
      # Add maint.2, compat.2 etc as releases are made
    3.4/
      core/
        <news entries>
      builtins/
        <news entries>
      extensions/
        <news entries>
      library/
        <news entries>
      documentation/
        <news entries>
      tests/
        <news entries>
      # Add maint.1, compat.1 etc as releases are made

버전 정보를 디렉터리 계층 구조에 배치하는 것은 엄밀히 말해 필요하지 않습니다(NEWS 파일 제너레이터가 버전 기록에서 이를 알아낼 수 있기 때문입니다). 그러나 서로 다른 버전을 사람들이 순서대로 정리하기는 더 쉬워집니다.

버전 결합을 줄임으로써 얻는 기타 이점

언어 릴리스 주기 늦추기

현재 릴리스 주기는 핵심 언어 정의와 C 확장 ABI의 안정성을 유지하려는 요구와 새로운 기능(특히 표준 라이브러리 업데이트)을 사용자에게 더 신속하게 제공하려는 요구 사이의 절충안입니다.

표준 라이브러리 릴리스 주기를 핵심 언어 정의의 릴리스 주기와 어느 정도 분리하면, 언어 정의의 변경 속도를 실제로 늦출 기회가 생깁니다. Python 3.2의 언어 변경 유예 조치는 중대한 문제나 불만을 일으키지 않으면서 해당 주기를 사실상 3년 넘게 늦췄습니다(3.1: 2009년 6월, 3.3: 2012년 8월).

위에서 설명한 NEWS 파일 관리 방식은 표준 라이브러리 릴리스가 더 빈번해지는 동시에 언어 릴리스를 늦출 수 있는 유연성을 제공하도록 실제로 설계되었습니다.

간단한 예로 3.3과 3.4 사이에 2년을 온전히 허용한다면, 3.3 릴리스 주기는 다음과 같은 모습이 됩니다.:

3.2.4       # Maintenance release
3.3.0       # Language release

3.3.1       # Maintenance release
3.3 (33.1)  # Standard library release

3.3.2       # Maintenance release
3.3 (33.2)  # Standard library release

3.3.3       # Maintenance release
3.3 (33.3)  # Standard library release

3.3.4       # Maintenance release
3.3 (33.4)  # Standard library release
3.4.0       # Language release

제안된 브랜치 구조와 NEWS 항목 배치의 장점은 이 결정을 예정된 3.4 릴리스 날짜 직전까지 실제로 내릴 필요가 없다는 점입니다. 그 시점에 3.4 릴리스를 연기하고 3.3.3 유지보수 릴리스와 3.3(33.3) 표준 라이브러리 릴리스 이후에도 3.33.3-compat 브랜치를 열어 두어, 주기에 표준 라이브러리 릴리스를 하나 더 추가하기로 결정할 수 있습니다. 그 이후에는 6개월마다 추가 표준 라이브러리 릴리스와 전체 언어 릴리스 중 하나를 선택할 수 있습니다.

표준 라이브러리 개발 속도를 더욱 높이기

앞 절에서 언급했듯이, 이 PEP에서 제안한 방식의 한 가지 이점은 언어 릴리스 주기와 표준 라이브러리 릴리스 주기를 대부분 분리한다는 점입니다. 핵심 언어의 안정성이 인식되는 정도나 언어 버전 번호 매기기에 아무런 연쇄 영향을 주지 않으면서 표준 라이브러리를 3개월마다 또는 심지어 매월 업데이트할 수 있습니다.

Windows 및 Mac OS X용 바이너리 설치 프로그램을 만들 때 여러 수동 단계(수동 테스트 포함)가 필요하고, 안정적인 빌드봇이 양호하다고 표시한 버전만 받는 별도의 “<branch>-release” 트리도 아직 없는 동안에는 이러한 개발 속도를 실현하기 어렵지만, 새로운 버전 관리 체계를 제안할 때 염두에 둘 유용한 기준은 여전히 됩니다. 결국 표준 라이브러리 릴리스를 6개월마다보다 더 빠르게 만들고 싶어진다면 어떻게 하겠습니까?

실무적인 문제가 해결된다면 이 PEP의 별도 표준 라이브러리 버전 관리 체계로 이를 처리할 수 있습니다. 관련 PEP 407에서 제안한 태그가 지정된 버전 번호 접근 방식으로는 처리할 수 없습니다(적어도 사용자에게 큰 혼란과 불확실성을 초래하지 않고서는 불가능합니다).

기타 질문

메이저 버전 번호를 사용하지 않는 이유는 무엇입니까?

가장 단순하고 논리적인 해결책은 실제로 major.minor.micro 버전 번호를 각각 언어 버전, 표준 라이브러리 버전 및 유지보수 릴리스 버전에 매핑하는 것입니다.

Python 3.3.0을 릴리스하는 대신 Python 4.0.0을 릴리스하며, 릴리스 주기는 다음과 같은 모습이 됩니다.:

4.0.0  # Language release

4.0.1  # Maintenance release
4.1.0  # Standard library release

4.0.2  # Maintenance release
4.2.0  # Standard library release

4.0.3  # Maintenance release
4.3.0  # Standard library release
5.0.0  # Language release

그러나 Python 2 -> Python 3 전환으로 인한 지속적인 어려움(원하는 릴리스 계열을 직접 가리키기 위한 python3python2 심볼릭 링크와 같은 관련 우회책을 포함함) 때문에, 역사적인 이유로 이 단순한 선택지는 실현 가능하지 않습니다.

이 간단한 접근 방식을 작동하게 만들 수 있는 한 가지 방법은 현재 주 버전 번호와 부 버전 번호를 2자리 주 버전 번호에 직접 병합하는 것입니다.:

33.0.0  # Language release

33.0.1  # Maintenance release
33.1.0  # Standard library release

33.0.2  # Maintenance release
33.2.0  # Standard library release

33.0.3  # Maintenance release
33.3.0  # Standard library release
34.0.0  # Language release

네 부분으로 된 버전 번호를 사용하지 않는 이유는 무엇입니까?

또 다른 단순한 버전 관리 체계는 기존 버전 관리 체계에 “표준 라이브러리” 버전을 추가하는 것입니다.:

3.3.0.0  # Language release

3.3.0.1  # Maintenance release
3.3.1.0  # Standard library release

3.3.0.2  # Maintenance release
3.3.2.0  # Standard library release

3.3.0.3  # Maintenance release
3.3.3.0  # Standard library release
3.4.0.0  # Language release

그러나 sys.version_info 구조체의 하위 호환성 제약으로 인해 이 체계는 실현 가능하지 않습니다.

날짜 기반 버전 관리 체계를 사용하지 않는 이유는 무엇입니까?

이 PEP의 이전 버전에서는 표준 라이브러리에 날짜 기반 버전 관리 체계를 제안했습니다. 그러나 이러한 체계에서는 표준 라이브러리 릴리스에서 보안 문제 및 기타 중대한 버그를 수정하기 위한 주기 외 릴리스를 처리하기가 매우 어려웠는데, 다음 단계를 요구했기 때문입니다.

  1. 릴리스 버전 번호를 현재 월의 날짜로 변경합니다.
  2. What’s New, NEWS 및 문서를 새 릴리스 번호를 참조하도록 업데이트합니다.
  3. 새 릴리스를 만드십시오.

현재 제안된 순차적 체계를 따르면, 이러한 릴리스는 릴리스하기 전에 What’s New 문서를 기껏해야 약간 다듬는 작업만 필요로 합니다.

PEP 384로는 왜 충분하지 않습니까?

PEP 384는 CPython을 위한 “Stable ABI” 개념을 도입했으며, 이는 안정적으로 유지된다는 보장이 있는 전체 C ABI의 제한된 부분 집합입니다. 안정 ABI에 맞춰 빌드된 확장 기능은 동일한 바이너리로 이후의 모든 Python 버전을 지원할 수 있어야 합니다.

이를 통해 새 프로젝트는 C 확장 모듈을 특정 CPython 버전에 지나치게 결합하는 일을 피할 수 있습니다. 그러나 기존 모듈의 경우 안정 ABI로 마이그레이션하려면 상당히 많은 작업이 필요할 수 있습니다(특히 많은 클래스를 정의하는 확장 모듈의 경우 그렇습니다). 개발 리소스가 제한된 상황에서 이러한 변경에 소요되는 시간은 최종 사용자에게 더 직접적인 이점을 제공하는 기능을 작업하는 데 대신 사용할 수도 있었던 시간입니다.

또한 제3자 C 확장 기능과의 바이너리 호환성 문제와 직접 관련되지 않은, 위에서 설명한 버전 분리의 다른 이점도 있습니다.

표준 라이브러리 릴리스에서 C ABI에 바이너리 호환 가능한 추가 사항을 허용하지 않는 이유는 무엇입니까?

CPython C ABI에 추가 사항을 표준 라이브러리 릴리스에서 합리적으로 허용할 수 있다는 주장이 가능합니다. 이를 통해 C 확장 작성자는 다른 패키지 또는 모듈 작성자와 동일하게 특정 언어 버전이나 표준 라이브러리 버전에 의존할 수 있는 자유를 얻게 됩니다.

이 PEP는 현재 인터프리터 버전을 언어 버전과 연계하므로, 주요 인터프리터 변경 사항(C ABI 추가 사항 포함)을 언어 릴리스로 제한합니다.

일관성을 갖춘 또 다른 접근 방식은 인터프리터 버전을 표준 라이브러리 버전과 연계하고, 하위 호환성에 영향을 줄 수 있는 변경 사항만 언어 릴리스로 제한하는 것입니다.

이러한 체계에서는 다음 변경 사항을 표준 라이브러리 릴리스에서 허용할 수 있습니다.

  • 표준 라이브러리 업데이트
    • 순수 Python 모듈의 새로운 기능
    • C 확장 모듈의 새로운 기능 (PEP 399 호환성 요구 사항을 따름)
    • 언어 내장 기능의 새로운 기능
  • 인터프리터 구현 업데이트
    • C ABI에 대한 바이너리 호환 가능한 추가 사항
    • AST에 영향을 주거나 바이트코드 매직 넘버를 변경하지 않는 컴파일 도구체인의 변경 사항
    • 핵심 인터프리터 평가 루프의 변경 사항
  • 해당 유지보수 릴리스의 버그 수정 사항

그리고 다음 변경 사항은 언어 릴리스에서 허용할 수 있습니다.

  • 새로운 언어 구문
  • 표준 라이브러리 릴리스에서 허용되는 모든 업데이트
  • 새로운 사용 중단 경고
  • 이전에 사용 중단된 기능의 제거
  • AST의 변경 사항
  • 매직 넘버를 변경해야 하는 방출된 바이트코드의 변경 사항
  • C ABI의 바이너리 비호환 변경 사항(단, PEP 384 안정 ABI는 여전히 보존해야 합니다)

이러한 접근 방식이 아마 동작하도록 만들어질 수는 있겠지만, 그것을 뒷받침할 만한 설득력 있는 근거는 없어 보이며, PEP에서 현재 설명하는 접근 방식이 더 단순하고 설명하기 쉽습니다.

표준 라이브러리를 완전히 분리하지 않는 이유는 무엇입니까?

이따금 논의되는 개념으로, 표준 라이브러리를 CPython 참조 구현으로부터 진정으로 독립시키자는 아이디어가 있습니다.

필자 개인의 의견으로는, 실제로 그러한 변경을 하는 것은 많은 작업을 필요로 하는 데 비해 얻는 이득은 거의 없습니다. 표준 라이브러리가 없는 CPython은 쓸모가 없습니다(테스트 스위트는 고사하고 빌드 체인조차 실행되지 않습니다). 또한 독립적인 순수 파이썬 표준 라이브러리를 만드는 것도 불가능한데, 너무 많은 “표준 라이브러리 모듈”이 실제로는 각 인터프리터의 내부 세부 사항과 밀접하게 연결되어 있기 때문입니다(예를 들어, 빌트인, weakref, gc, sys, inspect, ast가 그렇습니다).

이전 언어 릴리스와의 호환성을 유지하는 별도의 CPython 개발 브랜치를 만들고, 그 브랜치에서 별도의 표준 라이브러리 버전 번호로 식별되는 릴리스를 만드는 방식은, 별도의 표준 라이브러리 저장소가 주는 이점의 대부분을 그보다 훨씬 적은 수고로 제공할 것입니다.

감사의 말

이 논의를 시작해 준 PEP 407 저자들과, 이 PEP에서 제안된 내용에 대한 초기 논의를 함께해 준 그 저자들 및 Larry Hastings에게 감사드립니다.

참고 문헌