[Draft] PEP 780 - ABI features as environment markers

원문 링크: PEP 780 - ABI features as environment markers

상태: Draft 유형: Standards Track 작성일: 21-Mar-2025

PEP 780 – 환경 마커로서의 ABI 기능

개요 (Abstract)

이 PEP는 새로운 sys_abi_features 환경 마커를 통해 프로젝트 종속성에 ABI(Application Binary Interface) 기능을 환경 마커로 사용하는 방법을 정의합니다. PEP 508(이후 Dependency specifiers로 이동)은 종속성을 사용해야 하는 시기를 설명하는 규칙에 따라 종속성을 지정하기 위해 환경 마커를 도입했습니다. 이 PEP는 Python 인터프리터의 특정 ABI 기능에 따라 종속성을 지정할 수 있도록 환경 마커를 확장합니다. 이를 위해 일련의 ABI 기능을 정의하고, 새로운 마커 변수인 sys_abi_features로서 환경 마커에서 이러한 기능을 사용할 수 있도록 지정합니다.

동기 (Motivation)

2015년에 PEP 508은 환경 조건에 따라 종속성을 지정하기 위한 환경 마커를 확립했습니다. CPython의 Free-threaded(자유 스레드) 개발은 인터프리터가 빌드된 다양한 ABI 기능을 구별하기 위한 환경 마커의 필요성을 강조했습니다. 예를 들어, 현재 환경 마커를 사용하여 GIL(Global Interpreter Lock)이 활성화된 CPython 인터프리터와 Free-threaded CPython 인터프리터를 구별할 수 있는 방법이 없습니다. 이는 Free-threading의 채택 및 점진적인 배포에 실제적인 문제를 야기합니다.

Python 패키지가 Free-threaded CPython과 호환되도록 만들 때, 모든 빌드 및 런타임 종속성도 호환되어야 합니다. 현재 메타데이터에 호환되는 종속성의 첫 번째 버전을 정확하게 캡처하는 것은 불가능하며, GIL이 활성화된 빌드의 종속성 최소 버전을 높이는 것은 패키지 간의 불필요한 호환성 제한을 야기하므로 일반적으로 바람직하지 않습니다.

이러한 문제에 대한 몇 가지 구체적인 예시는 “Environment marker for free-threading” Discourse 스레드에서 논의되었습니다.

  • Cython: Free-threading에 대한 (실험적) 지원은 master 브랜치에만 있으며, 이미 cp313t 휠을 게시하는 많은 프로젝트에서 사용됩니다. 잘못된 Cython 버전을 선택하면 많은 모호한 빌드 실패 및 런타임 충돌이 발생합니다. 메타데이터가 이를 표현할 수 있다면 도움이 될 것입니다 (예: Free-threaded Python을 위한 Cython Pre-release 요구 사항 참조).
  • CFFI: 아직 Free-threading을 지원하지 않으며, 유지보수자 중 한 명인 Armin Rigo는 cffi를 포크(fork)하고 Free-threading 지원을 구현한 다음, 기능이 “합리적으로 잘 테스트된 (테스트를 통해 또는, 이 경우 더 나은 방법은 다양한 다른 프로젝트에서 사용됨을 통해)” 후에 단일 대규모 PR로 CFFI 프로젝트로 돌아오는 것이 좋은 아이디어일 수 있다고 언급했습니다. cffi에 의존하는 많은 프로젝트가 있습니다. 이들은 Free-threading에 대해서만 포크에 의존하는 것은 괜찮겠지만, >=3.13 또는 모든 Python 버전에 대해 포크에 의존하는 것은 훨씬 더 큰 요구 사항이며, 배포 패키지 관리자에게 더 큰 혼란을 줄 수 있습니다.

이러한 구체적인 예시는 올해 후반에 Cython과 CFFI가 호환 가능한 릴리스를 통해 해결될 수 있지만, 동일한 문제는 스택의 더 높은 곳에서 반복될 것입니다. Free-threading의 배포는 수년이 걸릴 것으로 예상되며, Free-threading을 위한 환경 마커는 이러한 배포를 훨씬 쉽게 만들 것입니다.

환경 마커로 아직 다루지 않는 또 다른 중요한 ABI 기능은 인터프리터의 비트(bitness)입니다. 대부분의 경우 sys_platform 또는 platform_system 마커로 충분합니다. 플랫폼당 단일 비트만 사용되기 때문입니다. 그러나 Windows에서는 그렇지 않습니다. x86-64 Windows에서는 32비트 및 64비트 Python 인터프리터가 모두 널리 사용됩니다. 둘을 구별할 수 없는 것은 컴파일된 확장 기능을 제공하는 패키지와 관련이 있을 수 있습니다. 예를 들어, SciPy는 win32 휠을 제공하지 않습니다 (Fortran 지원이 있는 적합한 32비트 컴파일러 툴체인이 없기 때문에 불가능합니다). 이러한 휠이 없는 것은 특히 SciPy가 선택적 종속성일 뿐인 프로젝트에서 불편할 수 있습니다. 이 경우, SciPy가 Windows의 32비트 인터프리터가 아닌 경우에만 필요하다고 지정할 수 있다면 유용할 것입니다 (예: 32비트 win32가 아닌 경우 SciPy 요구 사항 참조). 이는 휠 누락으로 인한 소스에서 설치 실패를 방지할 수 있습니다.

근거 (Rationale)

이 PEP의 목표는 기존 생태계에 최소한의 영향을 미치면서 핵심 기능을 도입하는 것입니다. PEP 508에서 제안된 기존 문법은 새로운 환경 마커를 포함하도록 간단하게 확장될 수 있습니다.

Free-threaded Python에 대한 미래 지향적 관점 (A Forward Looking View on Free-Threaded Python)

Free-threading에 대한 수락된 제안인 PEP 703은 Free-threaded Python의 배포가 점진적이어야 한다고 명시하고 있으며, 이는 Python Steering Council에 의해 PEP 703 수락 게시물에서 여러 릴리스에 걸친 3단계 프로세스를 의미한다고 명확히 했습니다. 따라서 이 PEP의 메커니즘이 Free-threading 또는 Non-free-threading이 기본 또는 유일한 옵션일 수 있는 Python 인터프리터에 유용하도록 보장하는 것이 중요합니다.

이 문서를 작성하는 시점에 Free-threaded Python은 Phase I: 실험 단계에 있습니다. 이 단계에서는 패키지 작성자가 점진적으로 지원을 추가함에 따라 Free-threaded Python으로의 전환을 돕기 위해 제안된 환경 마커가 절실히 필요합니다.

지원하는 패키지 수가 증가하고 특히 Phase II: 지원되지만 기본값은 아님 단계에서는 전환을 돕기 위한 환경 마커에 대한 강한 필요성이 여전히 예상됩니다.

Free-threaded Python이 Phase III: 기본 단계에 진입하면 환경 마커의 필요성은 감소할 것이지만, 이 시점에서는 GIL이 활성화된 Python이 완전히 단계적으로 폐지될지는 명확하지 않습니다 (비표준 빌드 옵션으로 계속 사용할 수 있습니다). 만약 계속 유지된다면, ABI 기능 감지에 대한 역방향 필요성이 발생할 수 있습니다.

실제로 세 단계 모두에서 패키지 작성자는 ABI 기능에 따라 종속성의 특정 버전을 선택해야 할 수 있으며, 시간이 지남에 따라 기본값이 GIL 활성화에서 Free-threading으로 변경됩니다.

ABI 기능은 변화하는 Python 생태계에서 예측 가능한 미래에 유용성과 단순성을 보장하기 위해 이를 염두에 두고 설계되었습니다.

다른 PEP와의 관계 (Relation to Other PEPs)

이 PEP는 ABI 기능에 대한 집합 의미론(set semantics)으로 환경 마커를 확장합니다. PEP 751은 록 파일(lock file) 특정 환경 마커에 대한 유사한 확장을 포함합니다. 비록 두 PEP가 독립적으로 개발되었지만, 새로운 집합 의미론 측면에서 겹치는 부분에서 호환됩니다.

사양 (Specification)

이 문서에서 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL” 키워드는 RFC 2119에 설명된 대로 해석됩니다.

ABI 기능 (ABI Features)

ABI 기능은 Python 인터프리터의 본질적인 속성으로, 간단하고 이해하기 쉬운 문자열로 표현됩니다. 그러나 모든 기능이 모든 Python 인터프리터 또는 Python 버전에 동등하게 적용되는 것은 아닙니다. 예를 들어, Free-threaded 인터프리터와 GIL 활성화 인터프리터의 구별은 CPython 3.13부터만 관련이 있지만, 인터프리터의 비트는 모든 인터프리터에 관련이 있습니다.

모든 인터프리터는 명시된 대로 다음 ABI 기능을 처리해야 합니다. 특정 인터프리터로 제한되는 ABI 기능은 다른 인터프리터에서 제공되어서는 안 됩니다. 기능은 그룹으로 세분화되며, 각 그룹에는 정확히 하나의 기능이 있어야 합니다. 단, 그룹이 선택 사항으로 표시된 경우에는 최대 하나의 기능만 있어야 합니다.

  • free-threading 또는 gil-enabled (CPython만 해당)
    • Python 인터프리터가 Free-threaded이면 free-threading 기능이 있어야 하고 gil-enabled 기능은 없어야 합니다.
    • 그렇지 않으면 gil-enabled 기능이 있어야 하고 free-threading 기능은 없어야 합니다.
  • debug (CPython만 해당, 선택 사항)
    • 이 ABI 기능은 --with-pydebug CPython 빌드를 위해 예약되어 있습니다.
    • 인터프리터가 Py_DEBUG 기능을 가진 CPython 인터프리터인 경우 debug 기능이 있어야 합니다. POSIX 시스템에서는 이는 sys.abiflags의 Python 표현 “d”에 해당합니다.
  • 32-bit 또는 64-bit (선택 사항)
    • 인터프리터의 비트, 즉 32비트 또는 64비트 빌드인지 여부입니다.
    • 비트를 알 수 없거나 32비트도 64비트도 아닌 경우 이 기능은 없어야 합니다.

sys_abi_features 환경 마커 (The sys_abi_features Environment Marker)

종속성 사양에서 ABI 기능을 사용할 수 있도록 하기 위해 새로운 환경 마커 변수 sys_abi_features가 종속성 지정자 형식에 추가됩니다.

이를 위해 PEP 508에 명시되고 Dependency specifiers에서 유지되는 문법을 확장하고 가능한 값을 문서화해야 합니다.

문법은 env_var의 정의를 다음과 같이 보강하여 sys_abi_features 마커 변수를 포함하도록 확장됩니다.

env_var = ('python_version' | 'python_full_version' | 'os_name' | 'sys_platform' | 'platform_release' | 'platform_system' | 'platform_version' | 'platform_machine' | 'platform_python_implementation' | 'implementation_name' | 'implementation_version' | 'sys_abi_features' | 'extra' # ONLY when defined by a containing layer )

문법과 마찬가지로 Dependency specifiers의 환경 마커 개요 테이블도 다음 행을 추가하여 보강됩니다.

Marker Python equivalent Sample values
sys_abi_features no direct equivalent available {'free-threading', '64-bit'} , {'gil-enabled', 'debug', '32-bit'}

이러한 추가 사항을 통해 ABI 기능은 in 연산자를 사용하여 기능의 존재를 테스트하거나 not in 연산자를 사용하여 기능의 부재를 테스트하여 종속성 사양에서 사용할 수 있습니다.

예시 (Examples)

Free-threaded Python을 위한 Cython Pre-release 요구 (Require Cython Pre-release for Free-Threaded Python)

Free-threaded Python 인터프리터에 대해서만 Cython의 pre-release 버전을 요구하려면 다음 종속성 사양을 사용할 수 있습니다.

cython >3.1.0a1; "free-threading" in sys_abi_features
cython ==3.0.*; "free-threading" not in sys_abi_features

32비트 Windows가 아닌 경우 SciPy 요구 (Require SciPy Unless on 32-bit win32)

Windows의 32비트 인터프리터가 아닌 경우 SciPy를 요구하려면 다음 종속성 사양을 사용할 수 있습니다.

scipy; platform_system != "Windows" or "32-bit" not in sys_abi_features

디버깅 기능이 있는 Free-threaded 인터프리터를 위한 NumPy 요구 (Require NumPy for a Free-Threaded Interpreter With Debugging Capabilities)

디버깅 기능이 있는 Free-threaded 인터프리터에 대해서만 NumPy를 요구하려면 다음 종속성을 사용할 수 있습니다.

numpy; "free-threading" in sys_abi_features and "debug" in sys_abi_features

하위 호환성 (Backwards Compatibility)

이것은 기존 환경 마커에 대한 순수한 확장이며 기존 환경 마커 또는 종속성 사양에 영향을 미치지 않으므로 직접적인 하위 호환성 문제는 없습니다.

그러나 이 기능의 도입은 특히 pyproject.tomlrequirements.txt의 데이터를 검사하려는 많은 생태계 도구에 영향을 미칩니다.

감사 및 업데이트 도구 (Audit and Update Tools)

requirements.txt 파일에 표현된 Python 종속성 데이터를 이해하는 광범위한 도구(예: Dependabot, Tidelift 등)가 있습니다.

이러한 도구는 종속성 데이터를 검사하고, 경우에 따라 도구 지원 또는 완전 자동 업데이트를 제공합니다. 처음에 이러한 도구가 새로운 환경 마커를 지원하지 않을 것이며, 광범위한 생태계 지원이 제공되기까지 수개월 또는 심지어 수년이 걸릴 수 있다고 예상됩니다.

결과적으로 새로운 환경 마커를 사용하는 사용자는 사용을 시작하는 시점에 워크플로우 및 도구 지원의 저하를 경험할 수 있습니다. 이는 종속성 데이터가 인코딩되는 위치 및 방법에 대한 모든 새로운 표준에 해당합니다.

보안 영향 (Security Implications)

이 PEP는 프로젝트에서 종속성 정보를 지정하기 위한 새로운 구문을 도입합니다. 그러나 종속성을 처리하거나 해결하기 위한 새로 지정된 메커니즘을 도입하지는 않습니다.

따라서 종속성을 설치하는 데 이미 사용될 수 있는 모든 도구에 내재된 것 외에는 보안 문제가 없습니다. 즉, 악성 종속성이 requirements.txt 파일에 지정될 수 있는 것과 마찬가지로 여기에 지정될 수 있습니다.

교육 방법 (How to Teach This)

환경 마커의 사용은 Dependency specifiers에서 잘 확립되고 주로 전달됩니다. 새로운 환경 마커는 동일한 문서에 소개될 수 있습니다. 또한 패키지 작성자와 사용자 모두를 위해 Python free-threading 가이드에서 Free-threading 관련 지침을 제공할 수 있습니다.

참조 구현 (Reference Implementation)

환경 마커에 대한 참조 구현은 packaging 라이브러리의 포크인 Environment markers for ABI features에서 사용할 수 있습니다.

데모 패키지도 사용할 수 있습니다.

pip은 내부적으로 packaging의 벤더링된 복사본을 사용하므로, 위에서 링크된 참조 구현으로 벤더링된 packaging을 대체하는 패치된 pip 버전도 제공됩니다.

거부된 아이디어 (Rejected Ideas)

확장 메커니즘 (Extension Mechanism)

주제에 대한 초기 논의(Environment marker for free-threading)에서 환경 마커에 대한 일반적인 확장 메커니즘 아이디어가 제기되었습니다. 미래에 새로운 환경 마커가 필요할 경우 전체 PEP 프로세스를 생략하는 것이 매력적이지만, 두 가지 주요 과제가 있습니다.

첫째, 완전히 동적인 메커니즘은 종속성 사양의 정적 분석에 의존하는 도구에 어려움을 줄 것입니다. 이는 동적인 메커니즘이 채택되더라도 새로운 환경 마커는 여전히 PEP에서 명시되어야 할 가능성이 높다는 것을 의미합니다.

둘째, 동적인 메커니즘의 도입은 packaging 라이브러리에서 더 복잡한 구현을 요구할 것이며, 이는 현재 접근 방식에서 크게 벗어나는 것입니다.

미해결 문제 (Open Issues)

기타 환경 마커 (Other Environment Markers)

지금 당장 다른 환경 마커가 필요한 경우 이 PEP를 확장하여 포함할 수 있습니다.

기타 도구 (Other Tooling)

참조 구현은 packaging 라이브러리 및 pip을 기반으로 합니다. 이를 통해 여러 빌드 백엔드로 패키지를 빌드하고 설치할 수 있음을 확인했습니다. 참조 구현에 다른 도구를 추가해야 할 수도 있습니다.

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

Comments