[Active] PEP 387 - Backwards Compatibility Policy

원문 링크: PEP 387 - Backwards Compatibility Policy

상태: Active 유형: Process 작성일: 18-Jun-2009

PEP 387 – 하위 호환성 정책 (Backwards Compatibility Policy)

  • 작성자: Benjamin Peterson
  • PEP 담당자: Brett Cannon
  • 상태: Active (활성)
  • 유형: Process (절차)
  • 생성일: 2009년 6월 18일
  • 대체: PEP 291

초록 (Abstract)

이 PEP는 Python의 하위 호환성 정책을 설명합니다.

배경 (Rationale)

오늘날 가장 많이 사용되는 프로그래밍 언어 중 하나인 Python의 핵심 언어와 표준 라이브러리는 수백만 개의 애플리케이션과 라이브러리에서 중요한 역할을 합니다. 이는 매우 훌륭한 일이지만, 동시에 개발팀이 새 릴리스를 통해 기존 서드파티 코드를 손상시키지 않도록 매우 신중해야 함을 의미합니다.

이 PEP는 “하위 호환성 파괴(backwards incompatibility)”를 변경 후 기존 코드가 이전과 비교하여 제대로 작동하지 않는 것으로 정의합니다. 이는 구체적인 정의는 아니지만, 일반적으로 “하위 호환성 파괴”가 무엇을 의미하는지 사람들이 이해하고 있으며, 불확실한 경우 Python 개발팀 및/또는 스티어링 위원회(steering council)에 지침을 요청할 수 있다는 기대를 가지고 있습니다.

하위 호환성 규칙 (Backwards Compatibility Rules)

이 정책은 모든 공개(public) API에 적용됩니다. 여기에는 다음이 포함됩니다:

  • 참조 매뉴얼에 정의된 구문(Syntax) 및 구조의 동작.
  • C-API.
  • 함수, 클래스, 모듈, 속성(attribute), 메서드 이름 및 유형.
  • 주어진 인자 집합에 대한 함수의 반환 값, 부작용(side effects), 발생시키는 예외. 이는 합리적인 버그 수정으로 인한 변경을 배제하지 않습니다.
  • 인자 및 반환 값의 위치와 예상 유형.
  • 서브클래스(subclasses)와 관련하여 클래스의 동작: 오버라이드(overridden)된 메서드가 호출되는 조건.
  • 문서화된 예외(exceptions)와 해당 예외가 발생하는 시맨틱(semantics).
  • EAFP (Easier to Ask Forgiveness than Permission) 시나리오에서 일반적으로 발생하는 예외.

다른 것들은 명시적으로 공개 API의 일부가 아닙니다. 이들은 언제든지 어떤 방식으로든 변경되거나 제거될 수 있습니다:

  • _로 시작하는 함수, 클래스, 모듈, 속성, 메서드 및 C-API 이름과 유형 (특수 이름 제외).
  • 공개적으로 비공개(private)로 문서화된 모든 것. 어떤 것도 문서화되지 않은 경우 자동으로 비공개로 간주되지 않습니다.
  • 임포트된 모듈 (명시적으로 공개 API의 일부로 문서화되지 않은 경우; 예: spam 모듈에서 bacon 모듈을 임포트했다고 해서 spam.bacon이 문서화되지 않는 한 자동으로 공개 API의 일부가 되는 것은 아닙니다).
  • 내부 클래스의 상속 패턴.
  • 테스트 스위트 (Lib/test 디렉토리 또는 패키지의 test 서브디렉토리에 있는 모든 것).
  • PEP 411에 따라 임시(Provisional)로 명시적으로 문서화된 모듈 또는 API에는 하위 호환성 규칙이 적용되지 않습니다.

하위 호환성을 위한 기본 정책 (Basic policy for backwards compatibility)

일반적으로 비호환적인 변경은 파급 효과(breakage) 대비 큰 이점을 가져야 하며, 영향을 받는 코드에서 해결하기 쉬워야 합니다. 예를 들어, 서드파티 패키지와 이름이 같은 stdlib 모듈을 추가하는 것은 일반적으로 허용되지 않습니다. 그러나 상속을 통해 서드파티 코드와 충돌하는 메서드나 속성을 추가하는 것은 합리적일 수 있습니다.

아래의 폐기(deprecation) 프로세스를 거치지 않는 한, API의 동작은 두 연속 릴리스(consecutive releases) 사이에서 비호환적인 방식으로 변경되어서는 안 됩니다. Python의 연간 릴리스 프로세스 (PEP 602)는 폐기 기간이 최소 2년 동안 지속되어야 함을 의미합니다. 마찬가지로, 기능은 두 연속 릴리스 사이에서 공지 없이 제거될 수 없습니다. 폐기 경고(deprecation warning)를 발생시킬 수 없는 변경 사항에 대해서는 스티어링 위원회와 상의해야 합니다.

스티어링 위원회는 이 정책에 대한 예외를 허용할 수 있습니다. 특히, 기능에 필요한 폐기 기간을 단축할 수 있습니다. 예외는 위험하게 손상되었거나(dangerously broken) 안전하지 않은 기능, 또는 누구도 합리적으로 의존할 수 없는 기능(예: 완전히 구식 플랫폼 지원)과 같은 극단적인 상황에만 허용됩니다.

소프트 폐기 (Soft Deprecation)

소프트 폐기(soft deprecation)는 더 이상 새 코드를 작성하는 데 사용해서는 안 되지만, 기존 코드에서 계속 사용하는 것이 안전한 API에 적용될 수 있습니다. 이 API는 계속 문서화되고 테스트되지만, 더 이상 개발되지 않습니다 (기능 개선 없음).

“소프트” 폐기와 일반적인 “하드” 폐기의 주요 차이점은 소프트 폐기는 폐기된 API의 제거 일정을 의미하지 않는다는 것입니다.

또 다른 차이점은 소프트 폐기는 경고를 발생시키지 않는다는 것입니다. 이는 문서에만 언급되며, 일반적으로 “하드” 폐기는 런타임에 DeprecationWarning 경고를 발생시킵니다. 소프트 폐기 문서에는 API를 피해야 하는 이유를 설명하고, 가능하다면 대체 방안을 제안해야 합니다.

현재 소프트 폐기된 기능을 (일반적인 의미로) 폐기하기로 결정된 경우, 폐기는 하위 호환성 규칙을 따라야 합니다 (즉, 해당 기능이 이미 소프트 폐기되었다는 이유로 예외는 없습니다).

비호환적 변경 수행 (Making Incompatible Changes)

비호환적인 변경을 수행하는 것은 여러 릴리스에 걸쳐 점진적으로 이루어지는 과정입니다:

  1. 변경 논의: 비호환성의 정도에 따라, 버그 트래커, python-dev, python-list 또는 적절한 SIG(Special Interest Group)에서 논의될 수 있습니다. PEP 또는 유사한 문서가 작성될 수 있습니다. 영향을 받는 API 사용자들이 의견을 제시하기를 바랍니다.
  2. 현재 main 브랜치에 경고 추가: 동작이 변경되는 경우, API는 새로운 동작을 수행하는 새 함수나 메서드를 얻을 수 있으며; 이전 사용법은 경고를 발생시켜야 합니다. API가 제거되는 경우, 진입 시마다 경고를 발생시키기만 하면 됩니다. DeprecationWarning이 일반적으로 사용되는 경고 범주이지만, 이전 버전과 새 버전의 API가 여러 릴리스 동안 공존할 특별한 경우에는 PendingDeprecationWarning이 사용될 수 있습니다. 경고 메시지에는 비호환성이 기본값으로 예상되는 릴리스와 사용자가 피드백을 게시할 수 있는 이슈(issue) 링크가 포함되어야 합니다. 가능한 경우, 정적 타입 체커(static type checker) 사용자가 폐기에 대해 알 수 있는 또 다른 방법을 제공하기 위해 typeshed에 @deprecated 데코레이터(PEP 702 참조)를 추가하여 폐기된 API를 표시해야 합니다. C API의 경우, Py_DEPRECATED 매크로(macro)에 의해 생성된 컴파일러 경고도 허용됩니다.
  3. 경고가 최소 두 개의 동일한 주 버전(major version)의 마이너 Python 버전(minor Python versions)에서 나타날 때까지 기다리거나, 또는 이전 주 버전에서 하나의 마이너 버전에서 나타날 때까지 기다립니다. (예: Python 3.10.0에서 경고가 발생하면 Python 3.12 이상 또는 Python 4.0까지 기다려야 변경할 수 있습니다). 그러나 제거 전에 5년을 기다리는 것이 선호됩니다 (예: Python 3.10부터 경고, 3.15에서 제거; 이는 현재 Python 마이너 릴리스의 수명과 일치합니다). 폐기된 동작의 예상 유지 보수 오버헤드와 보안 위험이 작다면 (예: 오래된 함수가 새롭고 더 일반적인 함수로 재구현되는 경우), 영구적으로 유지될 수 있습니다 (또는 상황이 변경될 때까지). 폐기된 기능이 새 기능으로 대체되는 경우, 일반적으로 새 기능이 없는 마지막 Python 버전이 지원 종료(end of support)에 도달한 후에만 제거되어야 합니다.
  4. 피드백 확인: 초기 논의에 참여하지 않았던 사용자들이 경고를 본 후 의견을 제시할 수 있습니다. 재고할 수도 있습니다.
  5. 변경 사항 적용: 선언된 버전에 도달하면 동작 변경 또는 기능 제거가 이제 기본값 또는 영구적으로 적용될 수 있습니다.
  6. 이전 버전 및 경고 제거: 사용자에게 경고를 제공할 수 없는 경우, 스티어링 위원회와 상의해야 합니다.

변경 로그 (Changelog)

  • 2025년 1월 27일: 제거 전 5년의 폐기 기간을 선호하도록 업데이트됨.
  • 2023년 11월 14일: PEP 702에 따라 @deprecated 데코레이터 추가됨.
  • 2023년 7월 3일: https://discuss.python.org/t/27957에서 논의된 바와 같이 소프트 폐기 섹션 추가됨.
  • 2023년 6월 26일: https://discuss.python.org/t/22042에서 논의된 여러 작은 업데이트 및 명확화.
  • 2022년 4월 4일: 몇 가지 예외적인 경우에 스티어링 위원회에 문의하도록 명시적인 메모 추가됨.
  • 2021년 4월 16일: 변경이 이루어지기 전에 경고가 얼마나 오랫동안 발행되어야 하는지 명확화.
  • 2020년 7월 20일: 초기 승인 버전.

참고 자료 (References)

TIOBE Programming Community Index: https://www.tiobe.com/tiobe-index/ The warnings module: http://docs.python.org/library/warnings.html

이 문서는 공개 도메인(public domain)에 배포되었습니다.


⚠️ 알림: 이 문서는 AI를 활용하여 번역되었으며, 기술적 정확성을 보장하지 않습니다. 정확한 내용은 반드시 원문을 확인하시기 바랍니다.

Comments