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

Python 개선 제안 한국어 번역

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

Author:
Klaus Zimmermann <klaus_zimmermann at gmx.de>, Ralf Gommers <ralf.gommers at gmail.com>
Sponsor:
Lysandros Nikolaou <lisandrosnik at gmail.com>
Discussions-To:
Discourse thread
Status:
Draft
Type:
Standards Track
Topic:
Packaging
Created:
21-Mar-2025
Python-Version:
3.14
Post-History:
05-Aug-2024, 26-Mar-2025

Table of Contents

번역·라이선스 안내

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

초록

이 PEP는 새로운 sys_abi_features 환경 마커를 통해 프로젝트 의존성에 ABI 기능을 환경 마커로 사용하는 방법을 정의합니다. PEP 508 (이후 Dependency specifiers로 이동됨)는 의존성을 사용해야 하는 시점을 설명하는 규칙에 기반하여 의존성을 지정할 수 있도록 환경 마커를 도입했습니다. 이 PEP는 Python 인터프리터의 특정 ABI 기능을 기반으로 의존성을 지정할 수 있도록 환경 마커를 확장합니다. 이를 위해 ABI Features 집합을 정의하고, 새로운 마커 변수인 sys_abi_features로서 environment markers에 사용할 수 있도록 제공하는 방법을 지정합니다.

동기

2015년에 PEP 508은 환경 조건을 기반으로 의존성을 지정할 수 있도록 환경 마커를 확립했습니다. free-threaded CPython의 개발 [1]은 인터프리터가 빌드된 서로 다른 ABI 기능을 구별할 수 있는 환경 마커의 필요성을 부각했습니다. 예를 들어 현재는 환경 마커를 사용하여 GIL이 활성화된 CPython 인터프리터와 free-threaded CPython 인터프리터를 구별할 방법이 없습니다. 이로 인해 free-threading의 도입과 점진적 배포에 실제 문제가 발생합니다. Python 패키지를 free-threaded CPython과 호환되도록 만들 때는 해당 패키지의 모든 빌드 및 런타임 의존성도 호환되어야 합니다. 정확히 호환되는 의존성의 최초 버전을 메타데이터에 현재 기록할 수 없으며, GIL이 활성화된 빌드에 대해서도 의존성의 최소 버전을 높이는 것은 패키지 간 호환성을 불필요하게 제한하므로 일반적으로 바람직하지 않습니다.

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

  • Cython은 현재 master 브랜치에서만 free-threading을 (실험적으로) 지원하며, 이미 cp313t 휠을 게시하는 많은 프로젝트에서 사용되고 있습니다. 잘못된 Cython 버전을 선택하면 원인을 파악하기 어려운 빌드 실패와 런타임 충돌이 많이 발생합니다. 메타데이터에서 이를 표현할 수 있다면 유용할 것입니다(c.f. Require Cython Pre-release for Free-Threaded Python).
  • CFFI는 아직 free-threading을 지원하지 않으며, 유지 관리자 중 한 명인 Armin Rigo가에서 free-threading을 구현하기 위해 cffi를 포크하고, 해당 기능이 “합리적으로 충분히 테스트된(테스트로 검증되었거나, 이 경우에는 더 좋게는 다른 여러 프로젝트에서 사용되어 검증된)” 후 단 하나의 대규모 PR로 지원을 추가하여 CFFI 프로젝트에 돌아오는 것이 좋은 생각일 수 있다고 밝혔습니다. cffi에 의존하는 프로젝트가 많습니다. 이러한 프로젝트는 free-threading에 대해서만 포크에 의존하기 시작하는 것은 괜찮을 가능성이 높지만, >=3.13 또는 모든 Python 버전에 대해 포크에 의존하는 것은 훨씬 더 큰 요구 사항으로 보이며 배포 패키지 관리자에게 더 큰 부담이 됩니다.

이러한 구체적인 사례는 Cython과 CFFI가 호환 릴리스를 내놓음으로써 올해 후반에 해결될 수 있지만, 같은 문제가 스택의 더 상위 계층에서 반복될 것입니다. free-threading의 배포에는 수년이 걸릴 것으로 예상되며, free-threading을 위한 환경 마커가 있으면 이러한 배포가 훨씬 쉬워질 것입니다.

환경 마커에서 아직 다루지 않는 또 다른 중요한 ABI 기능은 인터프리터의 비트 수입니다. 대부분의 경우 sys_platform 또는 platform_system 마커로 충분합니다. 플랫폼별로 사용되는 비트 수가 하나뿐이기 때문입니다. 그러나 Windows에서는 그렇지 않습니다. x86-64 Windows에서는 32비트와 64비트 Python 인터프리터가 모두 널리 사용됩니다. 두 비트 수를 구별할 수 없는 점은 컴파일된 확장을 제공하는 패키지와 관련이 있을 수 있습니다. 예를 들어 SciPy는 win32 휠을 제공하지 않습니다(Fortran을 지원하는 적절한 32비트 컴파일러 도구 모음이 부족하여 제공할 수 없습니다). 이러한 휠이 없으면 특히 SciPy가 선택적 의존성일 뿐인 프로젝트에서 곤란할 수 있습니다. 이 경우 Windows에서 인터프리터가 32비트인 경우를 제외하면 SciPy가 필요하다고 지정할 수 있다면, 휠이 없어 소스에서 설치하려다 실패하는 일을 피하는 데 유용할 것입니다(c.f. Require SciPy Unless on 32-bit win32).

근거

이 PEP의 목적은 기존 생태계에 미치는 영향을 최소화하면서 핵심 기능을 도입하는 것입니다. 기존 문법은 PEP 508에서 제안되었으며, 새로운 환경 마커를 포함하도록 손쉽게 확장할 수 있습니다.

Free-Threaded Python에 대한 미래 지향적 관점

PEP 703은 프리 스레딩을 위한 승인된 제안으로서, 프리 스레드 Python의 도입은 점진적으로 이루어져야 한다고 명시하며, Python Steering Council은 이를 the PEP 703 acceptance post에서 여러 릴리스에 걸친 3단계 프로세스를 의미한다고 명확히 했습니다. 따라서 이 PEP의 메커니즘이 프리 스레딩 또는 비프리 스레딩 중 하나가 기본 옵션이거나 유일한 옵션일 수 있는 Python 인터프리터에서 사용 가능하도록 보장하는 것이 중요합니다.

이 글을 작성하는 시점에 프리 스레드 Python은 1단계인 실험 단계에 있습니다. 이 단계에서는 패키지 작성자가 점진적으로 지원을 추가함에 따라 프리 스레드 Python으로의 전환을 지원하기 위해 제안된 환경 마커가 절실히 필요합니다.

지원하는 패키지의 수가 증가함에 따라, 특히 2단계인 지원되지만 기본값은 아닌 단계에서도 전환을 지원하기 위한 환경 마커의 필요성이 여전히 클 것으로 예상합니다.

프리 스레드 Python이 3단계인 기본값 단계에 진입하면 환경 마커의 필요성은 감소하겠지만, 이 시점에는 GIL 활성화 Python이 완전히 단계적으로 폐기될지는 명확하지 않습니다(비표준 빌드 옵션으로 계속 제공될 수도 있습니다). 이것이 지속된다면 ABI 기능 감지에 대한 반대 방향의 필요성이 발생할 수 있습니다.

실제로 세 단계 모두에서 패키지 작성자가 ABI 기능을 기반으로 종속성의 특정 버전을 선택해야 할 수 있으며, 시간이 지남에 따라 기본값이 GIL 활성화에서 프리 스레딩으로 전환될 것입니다.

ABI 기능은 변화하는 Python 생태계에서 예측 가능한 미래에도 유용성과 단순성을 보장하도록 이러한 점을 고려하여 설계되었습니다.

다른 PEP와의 관계

이 PEP는 ABI 기능에 대한 집합 의미론으로 환경 마커를 확장합니다. PEP 751에는 잠금 파일 전용 환경 마커에 대한 유사한 확장이 포함되어 있습니다. 두 확장은 독립적으로 개발되었지만 새로운 집합 의미론 측면에서 겹치는 부분에서는 서로 호환됩니다.

명세

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

ABI 기능

ABI 기능은 Python 인터프리터의 고유한 속성이며, 단순하고 이해하기 쉬운 문자열로 표현됩니다. 그러나 모든 기능이 모든 Python 인터프리터 또는 Python 버전에 동일하게 적용되는 것은 아닙니다. 예를 들어 프리 스레드 인터프리터와 GIL 활성화 인터프리터의 구분은 CPython 3.13 이상에서만 관련되지만, 인터프리터의 비트 수는 모든 인터프리터에서 관련됩니다.

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

free-threading 또는 gil-enabled (CPython에서만)
Python 인터프리터가 프리 스레드인 경우 free-threading기능이 있어야 하며 gil-enabled기능은 없어야 합니다. 그렇지 않은 경우 gil-enabled기능이 있어야 하며 free-threading기능은 없어야 합니다.
debug (CPython에서만, 선택 사항)
이 ABI 기능은 CPython의 --with-pydebug 빌드 전용으로 예약되어 있습니다. 인터프리터가 Py_DEBUG 기능을 갖춘 CPython 인터프리터인 경우 debug기능이 있어야 합니다. POSIX 시스템에서는 이것이 Python 표현식 "d" in sys.abiflags에 해당합니다.
32-bit 또는 64-bit (선택 사항)
인터프리터의 비트 수, 즉 32비트 또는 64비트 빌드인지 여부입니다 [2]. 비트 수를 알 수 없거나 32비트도 64비트도 아닌 경우 이 기능이 있어서는 안 됩니다.

sys_abi_features 환경 마커

종속성 지정에서 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'}

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

예제

자유 스레드 Python에 Cython 프리릴리스 요구

자유 스레드 Python 인터프리터에서만 Cython의 프리릴리스를 요구하려면 다음 의존성 사양을 사용할 수 있습니다.:

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

32비트 win32가 아닌 경우 SciPy 요구

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

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

디버깅 기능이 있는 자유 스레드 인터프리터에 NumPy 요구

디버깅 기능이 있는 자유 스레드 인터프리터에서만 NumPy를 요구하려면 다음 의존성을 사용할 수 있습니다.:

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

하위 호환성

이는 기존 환경 마커의 순수한 확장이며 기존 환경 마커나 의존성 사양에 영향을 주지 않으므로 직접적인 하위 호환성 문제는 없습니다.

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

감사 및 업데이트 도구

광범위한 도구가 requirements.txt파일에 표현된 Python 의존성 데이터를 이해합니다. (예: Dependabot, Tidelift 등)

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

그 결과 새로운 환경 마커의 사용자는 이를 사용하기 시작하는 시점에 작업 흐름과 도구 지원의 저하를 경험하게 됩니다. 이는 의존성 데이터가 어디에서 어떻게 인코딩되는지를 규정하는 모든 새로운 표준에 해당합니다.

보안 관련 사항

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

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

이 내용을 가르치는 방법

환경 마커의 사용은 잘 정립되어 있으며 주로 Dependency specifiers에서 설명됩니다. 새로운 환경 마커는 동일한 문서에서 소개할 수 있습니다. 또한 패키지 작성자와 사용자 모두를 위해 Python free-threading guide에서 자유 스레딩 관련 지침을 제공할 수 있습니다.

참조 구현

환경 마커의 참조 구현은 Environment markers for ABI features에서 packaging라이브러리의 포크로 제공됩니다.

A demonstration package도 제공됩니다.

pip는 내부적으로 packaging의 벤더링된 사본을 사용하므로, 위에서 링크한 참조 구현으로 벤더링된 packaging을 대체하는 a patched version of pip도 제공합니다.

거부된 아이디어

확장 메커니즘

이 주제에 관한 초기 논의(Environment marker for free-threading)에서 환경 마커를 위한 일반적인 확장 메커니즘이라는 아이디어가 제기되었습니다. 앞으로 새로운 환경 마커가 필요해질 경우 전체 PEP 절차를 거치지 않아도 된다는 점은 매력적이지만, 두 가지 주요 문제가 있습니다.

첫째, 완전히 동적인 메커니즘은 의존성 명세의 정적 분석에 의존하는 도구에 어려움을 초래할 수 있습니다.

이는 동적 메커니즘을 채택하더라도 새로운 환경 마커를 PEP에 명시해야 할 가능성이 높다는 뜻입니다.

둘째, 동적 메커니즘을 도입하려면 패키징 라이브러리에서 더 복잡한 구현이 필요하며, 이는 현재 접근 방식에서 크게 벗어나는 일이 됩니다.

미해결 문제

기타 환경 마커

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

기타 도구

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

각주

감사의 말

abi_features 속성을 제안해 주신 Filipe Laíns와 PEP 735의 하위 호환성 섹션을 작성해 주신 Stephen Rosen에게 감사드립니다. 해당 섹션은 이 PEP의 대응 섹션을 작성하는 데 템플릿으로 사용되었습니다.