PEP 608 – 조율된 Python 릴리스
- Author:
- Miro Hrončok <miro at hroncok.cz>, Victor Stinner <vstinner at python.org>
- Status:
- Rejected
- Type:
- Standards Track
- Created:
- 25-Oct-2019
- Python-Version:
- 3.9
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
선정된 프로젝트의 호환 버전이 나올 때까지 Python 릴리스를 보류합니다.
Python 릴리스 관리자는 프로젝트가 충분히 빨리 수정될 것이라고 판단하거나 문제의 심각도가 충분히 낮다고 판단하면, 프로젝트가 호환되지 않더라도 Python을 릴리스하기로 결정할 수 있습니다.
근거
이 PEP는 선정된 프로젝트의 유지 관리자를 Python 릴리스 주기에 참여시킵니다. 여기에는 여러 가지 이점이 있습니다:
- Python 최종 릴리스 전에 더 많은 버그를 발견합니다
- Python 최종 릴리스 전에 호환되지 않는 변경 사항을 논의하고 필요하면 되돌립니다
- 새 Python 최종 버전이 릴리스될 때 호환되는 프로젝트의 수를 늘립니다
Python 베타 단계에 참여하는 프로젝트가 너무 적습니다
현재 Python 베타 버전은 3.x.0 최종 릴리스 4개월 전에 제공됩니다.
베타 단계에서 보고된 버그는 쉽게 수정할 수 있으며, 충분히 심각하다면 릴리스를 보류시킬 수 있습니다.
호환되지 않는 변경 사항은 베타 단계에서 논의됩니다. 이때 코드를 갱신하는 방법을 설명하는 문서를 보강하거나, 해당 변경 사항을 되돌리는 것을 검토합니다.
점점 더 많은 프로젝트가 CI에서 Python의 master 브랜치로 테스트하고 있지만, PyPI 상위 50개 프로젝트 중 너무 많은 프로젝트가 Python 최종 릴리스 후 몇 주, 심지어 몇 달이 지나서야 새 Python과 호환됩니다.
DeprecationWarning이 무시되고 있습니다
Python에는 기능을 폐지하는 잘 정의된 절차가 있습니다. 기능을 제거하려면 그 전에 적어도 한 번의 Python 릴리스 동안 DeprecationWarning을 내보내야 합니다.
실제로는 주요 Python 프로젝트에서 DeprecationWarning 경고가 수년 동안 무시됩니다. 보통 유지 관리자들은 경고가 너무 많아서 그냥 무시한다고 설명합니다. 게다가 DeprecationWarning은 기본적으로 표시되지 않습니다(__main__ 모듈은 예외입니다: PEP 565).
점점 더 많은 프로젝트가 경고를 오류로 취급하는 방식(-Werror)으로 테스트 스위트를 실행하고 있지만, Python 코어 개발자는 여전히 기능을 제거했을 때 얼마나 많은 프로젝트가 깨지는지 알지 못합니다.
조율의 필요성
Python 최종 릴리스 이후에 문제와 호환되지 않는 변경 사항이 발견되고 논의되면, Python을 수정하는 일은 훨씬 더 복잡해지고 비용도 많이 듭니다. 어떤 API가 공식 최종 릴리스에 포함되면, Python은 3.x 릴리스의 전체 수명 동안 하위 호환성을 제공해야 합니다. 일부 운영 체제는 버그가 있는 최종 릴리스를 탑재한 채 배포될 수 있으며, 업데이트되기까지 몇 달이 걸릴 수 있습니다.
너무 많은 프로젝트가 Python 최종 릴리스 이후에야 새 Python에 맞게 업데이트되므로, Python이 릴리스되는 시점에는 이 새 Python 버전으로 대규모 애플리케이션을 실행하기가 거의 불가능합니다.
선정된 모든 프로젝트의 호환 버전이 나올 때까지 Python 릴리스를 보류할 것을 제안합니다.
더 짧은 Python 릴리스 일정
PEP 602: 파이썬의 연간 릴리스 주기와 PEP 605: CPython을 위한 롤링 기능 릴리스 스트림은 새로운 기능을 더 빨리 제공하기 위해 파이썬을 더 자주 릴리스하고자 합니다.
문제는 Python 3.x 릴리스마다 많은 프로젝트가 깨진다는 점입니다.
조율된 Python 릴리스는 깨지는 프로젝트의 수를 줄이고 새 Python 릴리스를 더 쓸모 있게 만듭니다.
명세
기본적으로, 선정된 모든 프로젝트의 호환 버전이 나올 때까지 Python 릴리스는 보류됩니다.
최종 Python 버전을 릴리스하기 전에, Python 릴리스 관리자는 선정된 각 프로젝트의 호환성 상태에 대한 보고서를 보낼 책임이 있습니다. 변화 추이를 확인하고 문제를 가능한 한 빨리 발견할 수 있도록, 이러한 보고서는 베타 릴리스 때마다 보내는 것을 권장합니다.
Python 릴리스 관리자는 어떤 프로젝트가 호환되지 않더라도, 그 프로젝트가 충분히 빨리 수정될 것이라고 판단하거나 문제의 심각도가 충분히 낮다고 판단하면 Python을 릴리스하기로 결정할 수 있습니다.
각 Python 릴리스 후에는 프로젝트 목록을 갱신하여 프로젝트를 제거하고 새 프로젝트를 추가할 수 있습니다. 예를 들어, 더 이상 사용하지 않는 오래된 의존성을 제거하고 새로운 의존성을 추가할 수 있습니다. 전체 과정이 Python 릴리스를 너무 오래 보류시키지 않는다면 목록은 늘어날 수 있습니다.
지연 제한
다음 Python 버전에서의 빌드나 테스트 문제가 프로젝트에 보고되면, 유지 관리자는 한 달 안에 답변해야 합니다. 답변이 없으면 해당 프로젝트는 Python 릴리스를 보류시키는 프로젝트 목록에서 제외될 수 있습니다.
여러 프로젝트가 이미 CI에서 Python의 master 브랜치로 테스트되고 있습니다. 문제는 Python 릴리스 주기의 매우 이른 시점에 발견될 수 있으므로, 이를 처리할 시간이 충분히 확보될 것입니다. 아직 다음 Python 버전으로 테스트되지 않는 프로젝트를 위해 CI를 더 추가할 수 있습니다.
선정된 프로젝트의 문제가 파악되면, Python 릴리스 관리자와 관련 프로젝트 유지 관리자가 사안별로 예외를 논의할 수 있습니다. 모든 문제가 Python 릴리스를 보류시킬 만한 것은 아닙니다.
선정된 프로젝트
Python 릴리스를 보류시키는 프로젝트 목록(총 27개):
- 프로젝트(13개):
- aiohttp
- cryptography
- Cython
- Django
- numpy
- pandas
- pip
- requests
- scipy
- Sphinx (Python 빌드에 필요)
- sqlalchemy
- pytest
- tox
- 직접 및 간접 의존성 (14개):
- certifi (urllib3에 필요)
- cffi (cryptography에 필요)
- chardet (Sphinx에 필요)
- colorama (pip에 필요)
- docutils (Sphinx에 필요)
- idna (Sphinx와 requests에 필요)
- jinja2 (Sphinx에 필요)
- MarkupSafe (Sphinx에 필요)
- psycopg2 (Django에 필요)
- pycparser (cffi에 필요)
- setuptools (pip와 수많은 Python 프로젝트에 필요)
- six (수많은 Python 프로젝트에 필요)
- urllib3 (requests에 필요)
- wheel (pip에 필요)
프로젝트 선정 방식
Sphinx처럼 Python을 빌드하는 데 사용되는 프로젝트도 목록에 포함되어야 합니다.
가장 인기 있는 프로젝트는 PyPI에서 가장 많이 다운로드된 프로젝트 중에서 선정합니다.
호환되지 않는 의존성 하나가 프로젝트 전체를 막을 수 있으므로, 프로젝트 의존성 대부분도 목록에 포함됩니다. 목록의 길이를 줄이기 위해 일부 의존성은 제외됩니다.
pytest와 tox 같은 테스트 의존성도 포함되어야 합니다. 프로젝트를 테스트할 수 없으면 새 버전도 출시할 수 없습니다.
목록은 프로젝트를 다음 Python으로 이식하는 비용을 충분히 가늠할 수 있을 만큼 길어야 하지만, Python 릴리스를 너무 오래 보류하지 않을 만큼 짧아야 합니다.
물론 목록에 포함되지 않은 프로젝트도 다음 Python에서의 문제를 보고하고 다음 Python 버전에서 CI를 실행하기를 권장합니다.
호환되지 않는 변경 사항
여기서의 정의는 넓습니다. 프로젝트를 빌드하거나 테스트할 때 문제를 일으키는 모든 Python 변경 사항이 해당합니다.
호환되지 않는 변경의 더 많은 예시는 PEP 606: Python Compatibility Version도 참고하십시오.
예시
호환되지 않는 변경에는 여러 종류가 있습니다:
- Python 빌드의 변경 사항입니다. 예를 들어 Python 3.8은
sys.abiflags에서'm'(pymalloc을 의미)을 제거했으며, 이는 Linux 배포판 같은 Python 벤더에 영향을 줍니다. - C 확장 빌드의 변경. 예를 들어, Python 3.8은 더 이상 C 확장을 libpython에 링크하지 않으며, Python 3.7은
errno모듈에 대한os.errno별칭을 제거했습니다. - 함수 제거. 예를 들어, ABC 클래스에 대한 collections 별칭이 Python 3.9에서 제거되었습니다.
- 함수 시그니처 변경:
- 이전에 허용되던 타입을 거부합니다(예:
int만 허용하고float는 거부). - 새로운 필수 매개변수를 추가합니다.
- 위치-또는-키워드 매개변수를 위치 전용 매개변수로 변환합니다.
- 이전에 허용되던 타입을 거부합니다(예:
- 동작 변경. 예를 들어, Python 3.8은 이제 XML 속성을 이름순으로 정렬하지 않고 삽입된 순서대로 직렬화합니다.
- 새로운 경고. 모든 경고를 오류로 취급하여 테스트하는 프로젝트가 점점 늘어나고 있으므로, 새로운 경고는 어떤 것이든 프로젝트 테스트를 실패하게 만들 수 있습니다.
- C API에서 함수 제거.
- C API에서 구조체가 불투명해짐. 예를 들어, Python 3.8에서 PyInterpreterState가 불투명해지면서
interp->modules에 접근하던 프로젝트가 동작하지 않게 되었습니다(대신PyImport_GetModuleDict()를 사용해야 합니다).
Python 정리와 DeprecationWarning
Zen of Python (PEP 20)의 모토 중 하나는 다음과 같습니다:
어떤 일을 하는 명확한 방법이 하나, 가급적이면 오직 하나만 있어야 합니다.
Python이 발전하면 새로운 방법이 필연적으로 등장합니다. 새로운 방법을 사용하도록 권하기 위해 DeprecationWarning이 발생하지만, 많은 개발자가 기본적으로 표시되지 않는 이 경고를 무시합니다.
때로는 두 방법을 모두 지원하는 데 드는 유지 보수 비용이 크지 않지만, Python 코어 개발자들은 Python 코드 베이스와 표준 라이브러리를 정리하기 위해 이전 방법을 제거하는 쪽을 선호합니다. 이러한 종류의 변경은 하위 호환성을 깨뜨립니다.
Python 2 지원 종료는 오래된 Python 코드를 정리할 좋은 기회이므로, 이에 따라 평소보다 더 많은 호환되지 않는 변경이 있을 것으로 예상해야 합니다.
분산 CI
선택된 프로젝트가 Python의 master 브랜치와 호환되는지 확인하는 작업은 분산 CI를 사용하여 자동화할 수 있습니다.
기존 CI를 재사용할 수 있습니다.
아직 다음 Python에서 테스트되지 않는 프로젝트에는 새로운 CI를 추가할 수 있습니다.
다음 Python에서 테스트할 때는 DeprecationWarning 경고를 오류로 취급할 것을 권장합니다.
다음 Python에서 프로젝트를 테스트하는 작업이 “필수”(전체 CI를 차단)일 필요는 없습니다. Python 릴리스의 베타 단계 동안에는 실패가 있어도 괜찮습니다. 이 작업은 Python 최종 릴리스에서만 통과하면 됩니다.
Copyright
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.