9P by neo 2달전 | favorite | 댓글 1개
  • HPy는 C로 Python을 확장하기 위한 새로운 API
  • #include <Python.h> 대신 #include <hpy.h>를 사용

HPy의 장점

  • CPython에서의 제로 오버헤드: HPy로 작성된 확장은 "일반" 확장과 동일한 속도로 실행됨
  • 대체 구현에서 더 빠름: PyPy, GraalPy 등에서 더 빠르게 실행됨
  • 범용 바이너리: HPy Universal ABI로 빌드된 확장은 CPython, PyPy, GraalPython 등에서 수정 없이 로드 가능함
  • 이전 C-API와의 혼합을 위한 마이그레이션 경로: 레거시 C-API 호출과 HPy API 호출을 혼합할 수 있음. 모든 코드가 마이그레이션되면 모든 CPython 버전, PyPy 또는 GraalPy에서 작동하는 범용 바이너리로 컴파일될 수 있음
  • 디버그 모드: 메모리 누수, 객체의 잘못된 수명, API의 잘못된 사용 등을 쉽게 식별 가능함
  • 더 나은 API: 표준 Python/C API의 한계를 극복하고, 더 일관성 있고, 더 나은 품질의 확장을 생성하며, 버그가 생기기 어렵게 설계됨
  • 진화 가능성: PEP 620에서 잘 요약된 바와 같이, 표준 Python/C API는 많은 내부 구현 세부사항을 노출하여 C API의 진화를 어렵게 함. HPy는 모든 내부 구현 세부사항을 숨겨 이러한 문제가 없음

현재 상태

  • HPy는 활발히 개발 중임. 0.9.0이 최신 알파 릴리스이지만 곧 알파 상태를 벗어날 것이며 안정적인 릴리스를 위해 노력하고 있음
  • HPy ABI가 이제 충분히 안정적이어서 다가오는 릴리스에서 이전 및 이후 이진 호환성 약속을 이행할 수 있다고 느낌
  • 중요한 패키지를 마이그레이션하기에 충분한 사용 사례를 API가 이제 다룰 수 있다고 생각함(특히 numpy 포트 확인)
  • 포팅 가이드와 광범위한 문서(특히 API 참조)도 제공함
  • 디자인 논의와 새로운 요구 사항에 대해 항상 열려 있음

HPy 호환 확장

  • ultrajson-hpy: HPy로 포팅된 첫 번째 실제 모듈
  • piconumpy: 이름에서 알 수 있듯이 사용자 정의 유형을 정의하는 최소한의 numpy와 유사한 모듈
  • numpy: 야심 찬 목표 중 하나는 numpy를 HPy로 포팅하고 이 경험을 사용하여 API 설계 방법을 더 잘 이해하는 것. 이 포트는 테스트 스위트를 통과하기 직전
  • matplotlib: NumPy에 대한 종속성도 있기 때문에 범용 모드로의 마이그레이션이 완전히 완료되지 않음. HPy에서 레거시 C API 함수를 계속 호출하고 테스트 스위트를 성공적으로 실행할 수 있도록 HPy는 레거시 호환성 API를 제공함
  • kiwi-solver: Matplotlib의 종속성으로 범용 모드로 완전히 포팅됨

GN⁺의 의견

  • HPy는 Python/C API의 한계를 극복하고 더 나은 확장성과 이식성을 제공하는 매우 유망한 프로젝트임
  • 특히 PyPy, GraalPy와 같은 대체 Python 구현에서 성능 향상의 잠재력이 크다는 점이 매력적임
  • 레거시 C API에서 마이그레이션하는 것이 어려울 수 있지만, HPy는 점진적인 마이그레이션 경로를 제공하여 이 과정을 훨씬 더 관리하기 쉽게 만듦
  • HPy를 채택할 때는 기존 빌드 시스템 및 배포 파이프라인과의 통합, 업스트림 프로젝트의 수용, 그리고 HPy 자체의 성숙도와 안정성을 고려해야 함
  • HPy와 유사한 목표를 가진 다른 프로젝트로는 Cython과 Rust의 PyO3 같은 것들이 있음. 이들은 저수준 C API 대신 고수준 언어를 사용한다는 점에서 HPy와 다름
Hacker News 의견
  • C API 작업에서 가장 번거로운 부분은 컴파일/링크 플래그 설정임. python3-config는 OS 수준에서만 작동하며, pip로 설치한 패키지에 접근하기 위해서는 사용하기 어려움. python3 -m venv는 이러한 스크립트를 생성하지 않으며, anaconda/miniconda도 문제임. 각 패키지가 하드코딩된 python3 -c "import sys: print..." 호출로 빌드 스크립트를 오염시킴. CPython에 python3 -m sysconfig --json 플래그를 추가하는 PR을 열었음

  • Python 언어가 하나의 구현에 너무 집중되어 있는 것은 장기적으로 성공에 위협이 될 수 있음. 웹 서버, 명령줄 프로그램, 임베디드 장치는 서로 다른 요구 사항을 가짐. 이 프로젝트가 Python의 C API를 구현 세부 사항을 노출하지 않는 것으로 대체하는 데 성공한다면, 대체 구현을 유지 관리하고 새로운 기술을 실험하는 것이 더 쉬워질 수 있음

  • 이 프로젝트가 버전 독립적인 Python 바인딩을 제공하는 것인지 궁금함. 현재 각 버전에 대해 별도로 바인딩을 빌드하고 있으며, 이는 CI/CD 시간을 많이 소모하게 함

  • HPy 확장과 Cython/pybind11 구현을 성능 및 개발 시간 측면에서 비교하는 벤치마크가 흥미로울 것임

  • 이 프로젝트가 PyBind11이나 nanobind 같은 라이브러리와 어떻게 맞물리는지 명확하지 않음. 이러한 라이브러리를 동일한 방식으로 사용하려면 다시 작성해야 할 것 같음

  • 요즘 C로 작성된 새로운 확장이 얼마나 많은지 궁금함. 주로 Boost Python, pybind, PyO3 같은 것들이라고 생각했음

  • CPython 바인딩을 최소한의 오버헤드로 구현하는 것에 대해 자주 게시하며, 몇 가지 추천, 질문, 우려 사항을 공유하고 싶음. HPy 프로젝트의 랜딩 페이지와 리포지토리의 README를 재구성하면 좋겠음. PyPy, GraalPython, 다른 Python 런타임에 대한 지지 통계가 있으면 더 설득력이 있을 것임

  • HPyContext 같은 캡슐화된 컨텍스트 객체를 사용하는 것은 멀티스레드 Python 미래나 복잡한 환경에서 유용함. 하지만 HPyContext가 CPython의 싱글톤으로 리디렉션된다면 문제 해결이 되지 않음

  • 2019년의 벤치마크는 CPython의 METH_FASTCALL 호출 규칙을 언급하지만 비교되지 않음. 성능에 관심이 있다면 문자열 포맷터 없이 튜플에서 직접 인수를 파싱하는 것이 좋음

  • Python에서 C 헤더를 주고 공유 라이브러리를 로드하여 구조체를 사용 가능하게 하고 함수를 호출할 수 있는 luajit의 ffi와 같은 간단한 것이 있는지 궁금함

  • Python에서 Go를 호출하는 것에 관심이 있으며, gopy는 cgo에 대한 Python 바인딩을 생성함. HPy<->cgo가 더 적은 오버헤드를 가질 수 있을 것임

  • 20년 전에 이 작업이 완료되었다면 Python 생태계가 얼마나 달라졌을지 상상해보길 바람