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

Python 개선 제안 한국어 번역

PEP 783 – Emscripten 패키징

Author:
Hood Chatham <roberthoodchatham at gmail.com>
Sponsor:
Łukasz Langa <lukasz at python.org>
Discussions-To:
Discourse thread
Status:
Accepted
Type:
Standards Track
Topic:
Packaging
Created:
28-Mar-2025
Post-History:
02-Apr-2025, 18-Mar-2025
Resolution:
06-Apr-2026

Table of Contents

번역·라이선스 안내

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

초록

이 PEP는 Pyodide Python 런타임용 바이너리 Python 패키지 배포판을 위한 새로운 플랫폼 태그 계열인 pyemscripten을 제안합니다.

Emscripten은 완전한 오픈 소스 컴파일러 툴체인입니다. Emscripten은 C/C++ 코드를 WebAssembly/JavaScript 실행 파일로 컴파일하며, 이 실행 파일은 브라우저와 Node.js를 포함한 JavaScript 런타임에서 사용됩니다. Rust 언어도 Emscripten 타깃을 유지 관리합니다. PEP 776은 Python의 Emscripten 지원을 명시합니다.

동기

Pyodide는 브라우저에서 사용하기 위한 CPython 배포판입니다. 웹 브라우저는 Windows, macOS, Linux 및 모든 스마트폰에서 사용할 수 있는 범용 컴퓨팅 플랫폼입니다. 수십만 명의 학생이 Capytale 및 PyodideU 같은 프로젝트를 통해 Pyodide로 Python을 배웠습니다. 또한 Python 패키지가 대화형 문서를 제공하기 위해 Pyodide를 사용하는 경우가 점점 늘어나고 있습니다.

이 글을 쓰는 시점에 Pyodide는 255개의 서로 다른 패키지의 포트를 유지 관리하고 있으며, 여기에는 NumPy, SciPy, pandas, Polars, scikit-learn, OpenCV, PyArrow, Pillow 같은 주요 과학용 Python 패키지뿐만 아니라 aiohttp, Requests, Pydantic, cryptography, orjson 같은 범용 패키지도 포함됩니다.

또한 NumPy, pandas, awkward-cpp, scikit-image, statsmodels, PyArrow, Hypothesis, PyO3를 포함한 약 60개의 패키지가 CI에서 Pyodide를 대상으로 테스트하고 있습니다.

Python 패키지 프로젝트는 Pyodide용 바이너리 배포판을 PyPI에 배포할 수 없습니다. 대신 anaconda.org 또는 jsdelivr.com 같은 다른 선택지를 사용해야 합니다. 이는 패키지 유지 관리자와 사용자 모두에게 불편을 초래합니다.

근거

Emscripten은 애플리케이션을 빌드할 때 운영 체제 전체를 포함하는 독립 실행형 프로그램으로 빌드합니다. Emscripten은 주로 완전히 정적인 프로그램이라는 사용 사례를 대상으로 합니다. 동적 링킹을 사용하는 경우 주요 대상 사용 사례는 번들 분할과 지연 로딩이며, 이때 동적 라이브러리는 애플리케이션과 동시에 빌드됩니다.

그 결과 Emscripten 컴파일러는 버전 간 ABI 안정성을 전혀 보장하지 않습니다. 많은 Emscripten 업데이트는 우연히 ABI 호환이 되며, Rust Emscripten 타깃은 ABI가 안정적인 것처럼 동작하는데 그로 인해 가끔 부정적인 결과가 생기는 정도에 그칩니다.

Emscripten ABI 또는 시스템 라이브러리를 조정하는 링커 플래그가 여러 개 있습니다. Emscripten에서 실행되도록 빌드된 Python 패키지는 로드 시점 또는 실행 시점 오류를 피하기 위해 인터프리터를 컴파일하는 데 사용된 ABI에 민감한 링커 플래그와 반드시 일치시켜야 합니다. Emscripten 컴파일러는 지속적으로 버그를 수정하고 새로운 웹 플랫폼 기능에 대한 지원을 추가합니다. 따라서 ABI를 업데이트할 수 있다는 것에는 상당한 이점이 있습니다.

패키지 유지 관리자의 ABI 안정성 요구와 플랫폼의 발전을 가능하게 하는 ABI 유연성 사이의 균형을 맞추기 위해, Pyodide는 Python의 기능 릴리스마다 pyemscripten_${YEAR}_${PATCH}라고 부르는 새로운 Emscripten 플랫폼을 채택할 계획입니다.

또한 Pyodide 팀은 널리 사용되는 많은 Rust 패키지를 확실히 지원할 수 있도록, Pyodide가 사용하는 ABI 플래그를 Rust가 지원하는 Emscripten ABI와 조율합니다. 지금까지 이와 관련된 작업의 대부분은 언와인딩 ABI와 관련된 것이었습니다. 예를 들어 이 Rust 주요 변경 제안을 참고하십시오.

pyemscripten 플랫폼은 Python과 특별히 관련된 것이 아니며, 실제로 적절한 버전의 Emscripten과 적절한 링크 플래그를 사용하는 모든 프로그램에서 사용할 수 있습니다. 특히 pyemscripten 플랫폼 태그는 지정된 버전의 Emscripten과 지정된 ABI에 민감한 플래그로 컴파일 및 링크된 Python 인터프리터에서 사용할 수 있습니다.

명세

플랫폼 태그는 다음과 같은 형식을 가집니다:

pyemscripten_${YEAR}_${PATCH}_wasm32

각 태그는 지정된 Python 버전과 함께 사용됩니다. 예를 들어, 플랫폼 태그 pyemscripten_2026_0은 Python 3.14와 함께 사용됩니다.

PyEmscripten 플랫폼

pyemscripten_${YEAR}_${PATCH} 플랫폼의 명세에는 다음이 포함됩니다:

  • 어떤 버전의 Emscripten 컴파일러를 사용하는지
  • 어떤 라이브러리가 애플리케이션에 정적으로 링크되는지
  • 어떤 스택 되감기(stack unwinding) ABI를 사용해야 하는지
  • 로더가 의존성 조회를 어떻게 처리하는지
  • 라이브러리가 -pthread를 사용할 수 없다는 점
  • 라이브러리를 -sWASM_BIGINT와 함께 링크해야 한다는 점

플랫폼은 적절한 버전의 Emscripten 컴파일러를 고르고 적절한 컴파일러 및 링커 플래그를 전달하는 방식으로 선택됩니다.

플랫폼 정의에는 Python에 관한 내용이 전혀 포함되지 않으며, 특히 함께 사용하려는 Python 버전과 무관합니다. 다만 명확성을 위해, 각 플랫폼을 어떤 Python 버전과 함께 사용할 계획인지 플랫폼 문서에 기록할 것입니다.

PyEmscripten 플랫폼은 PyEmscripten 플랫폼에 관한 Pyodide 문서에 완전히 명세되어 있습니다.

플랫폼을 정의하려면 메인 애플리케이션을 어떻게 컴파일하고 링크하는지만 명시하면 됩니다. 이로부터 호환되는 공유 라이브러리를 빌드하는 방법도 정해집니다. 그러나 대부분의 사람들이 공유 라이브러리를 빌드할 것이라고 가정하므로, 저희 문서에는 호환되는 공유 라이브러리를 빌드하는 방법에 대한 자세한 지침이 포함되어 있습니다.

pyodide build 도구는 PyEmscripten 플랫폼과 호환되는 휠을 만드는 방법을 알고 있습니다. manylinux 휠과 달리, pyemscripten 휠을 빌드하는 데에는 Docker 컨테이너가 필요하지 않습니다. Linux 머신과 적절한 버전의 Python, Node.js, Emscripten만 있으면 됩니다.

휠을 적절한 버전의 Pyodide 런타임에 설치하고 임포트하여 해당 휠이 PyEmscripten 플랫폼과 호환되는지 검증할 수 있습니다. Pyodide는 강력한 샌드박싱이 보장되는 환경에서 실행될 수 있으므로, 이렇게 해도 보안 위험이 발생하지 않습니다.

PyEmscripten 플랫폼 버전 확인하기

PyEmscripten 플랫폼 버전은 PYEMSCRIPTEN_PLATFORM_VERSION 설정 변수에 저장되며, 다음과 같이 확인할 수 있습니다:

pyemscripten_platform_version = sysconfig.get_config_var("PYEMSCRIPTEN_PLATFORM_VERSION")

호환되는 태그 목록을 생성하려면 다음 코드를 사용할 수 있습니다:

from packaging.tags import cpython_tags, _generic_platforms

def _emscripten_platforms() -> Iterator[str]:
    pyemscripten_platform_version = sysconfig.get_config_var("PYEMSCRIPTEN_PLATFORM_VERSION")
    if pyemscripten_platform_version:
        yield f"pyemscripten_{pyemscripten_platform_version}_wasm32"
    yield from _generic_platforms()

emscripten_tags = cpython_tags(platforms=_emscripten_platforms())

이 코드는 pypa/packaging에 추가될 예정입니다.

패키지 설치 프로그램

설치 프로그램은 위에 제시된 _emscripten_platforms() 함수를 사용하여 CPython의 Emscripten 빌드와 호환되는 플랫폼을 판단해야 합니다. 특히 PyEmscripten 플랫폼 버전은 sysconfig.get_config_var("PYEMSCRIPTEN_PLATFORM_VERSION")를 통해 노출됩니다.

패키지 색인

패키지 색인은 플랫폼 태그가 정규 표현식 pyemscripten_[0-9]+_[0-9]+_wasm32와 일치하는 모든 휠을 받아들여야 합니다(SHOULD).

의존성 지정자 마커

PEP 776에 따르면, Emscripten Python에서 sys.platform은 "emscripten"을 반환합니다. 의존성 지정자에서 Emscripten 플랫폼인지 확인하려면 sys_platform == "emscripten" (또는 그 부정)을 사용할 수 있습니다.

Trove 분류자

Emscripten 휠을 빌드하고 테스트하는 패키지는 Environment :: WebAssembly :: Emscripten 분류자를 추가하여 이를 선언할 수 있습니다. PyPI는 이미 이 분류자가 있는 패키지의 업로드를 받아들이고 있습니다.

하위 호환성

이 PEP에는 하위 호환성 문제가 없습니다.

보안 영향

이 PEP에는 보안상의 영향이 없습니다.

기각된 아이디어

Pyodide를 위한 사용자 정의 인터프리터 태그

Pyodide는 CPython이므로 Pyodide를 위한 사용자 정의 인터프리터 태그는 필요하지 않습니다. 몇 가지 사소한 패치를 적용하기는 하지만, 이 패치들은 인터프리터 ABI에 아무런 영향을 주지 않으며 우리의 장기적인 목표는 모든 것을 업스트림에 반영하는 것입니다.

플랫폼 태그의 대안

emscripten_${EMSCRIPTEN_VERSION}
pyemscripten 플랫폼은 특별히 Python과 관련된 것이 없으며, 실제로 적절한 버전의 Emscripten과 적절한 링크 플래그를 사용하는 어떤 프로그램에서도 사용할 수 있으므로 emscripten을 플랫폼 태그로 사용하고 싶어질 수 있습니다. 하지만 플랫폼은 다양한 링커 플래그에도 의존하므로 emscripten_${EMSCRIPTEN_VERSION}만으로는 너무 모호합니다.

비슷한 문제를 겪고 있으며, 생태계 전체가 사용할 수 있는 “장기 지원(Long Term Service)” Emscripten 플랫폼에 대한 중앙 집중식 표준이 있으면 마찬가지로 혜택을 볼 다른 커뮤니티들도 있습니다. 그러나 Emscripten 팀은 동적 링킹을 드문 사용 사례로 여기기 때문에 지금까지 이러한 표준을 제공할 의향을 보이지 않았습니다. 따라서 이 문제는 우리 생태계가 스스로 해결해야 할 몫으로 남아 있습니다. 플랫폼 태그에는 이 점을 어느 정도 나타내는 표시가 포함되어야 합니다.

pyemscripten_${PYTHON_MAJOR_MINOR}_${PATCH}
이렇게 하면 각 플랫폼에서 어떤 Python 버전을 사용해야 하는지가 더 명확해지겠지만, 플랫폼은 Python과 아무런 관련이 없으므로 개념적인 혼란을 초래합니다.
pyodide_...
현재로서는 Pyodide가 플랫폼을 정의하므로, 플랫폼 이름을 pyodide로 하면 이 연결 관계가 더 분명해질 것입니다. 하지만 플랫폼의 기능은 Pyodide가 지원하는 것이 아니라 Emscripten이 지원하는 것에 달려 있으므로, 플랫폼 태그는 Emscripten에 초점을 맞춰야 합니다. 또한 pyemscripten 태그는 플랫폼의 정의가 Pyodide의 업스트림으로 옮겨 가는 미래에 대해서도 상위 호환성이 더 좋습니다.
패치 버전 없음
패치 버전이 결코 필요하지 않기를 바라지만, 예상치 못한 문제에 대비해 두는 것이 좋습니다.

교육 방법

Pyodide 사용자를 위한 안내

패키지 설치에 관한 Pyodide 문서를 참고하시기를 권장합니다. 각 Pyodide 버전이 어떤 pyemscripten 플랫폼 버전과 호환되는지 보여 주는 표를 만들 예정입니다.

패키지 유지 관리자를 위한 안내

패키지 빌드 및 테스트에 관한 Pyodide 문서를 참고하시기를 권장합니다. Scientific Python 커뮤니티에서도 Emscripten 기반 Python으로 웹 기반 대화형 문서를 유지 관리하는 방법을 패키지 유지 관리자에게 설명하는 명세를 작성하고 있습니다.

일반적으로 Pyodide에서 사용할 패키지를 빌드하고 테스트하는 가장 쉬운 방법은 cibuildwheel입니다. 유지 관리자는 pyodide-build를 직접 사용하여 패키지를 빌드할 수도 있습니다. Maturin을 빌드 시스템으로 사용하는 Rust 패키지는 Maturin이 크로스 빌드를 기본적으로 지원하므로 Maturin으로 직접 빌드할 수 있습니다.

참조 구현

패키지 빌드에는 pyodide build와 cibuildwheel이 있습니다.

설치 프로그램이 wheel 태그가 Pyodide 인터프리터와 호환되는지 판단하는 방법은 pypa/packaging#804를 참고하십시오.