- HPy es una nueva API para extender Python con C
- Usa
#include <hpy.h> en lugar de #include <Python.h>
Ventajas de HPy
- Cero sobrecarga en CPython: las extensiones escritas con HPy se ejecutan a la misma velocidad que las extensiones "normales"
- Más rápido en implementaciones alternativas: se ejecuta más rápido en PyPy, GraalPy y otras
- Binario universal: las extensiones compiladas con el ABI universal de HPy pueden cargarse sin modificaciones en CPython, PyPy, GraalPython y otros
- Ruta de migración para mezclarlo con la C-API anterior: se pueden mezclar llamadas de la C-API legada con llamadas a la API de HPy. Cuando todo el código haya sido migrado, podrá compilarse como un binario universal que funcione en todas las versiones de CPython, además de PyPy o GraalPy
- Modo de depuración: permite identificar fácilmente fugas de memoria, ciclos de vida incorrectos de objetos, usos indebidos de la API y más
- Una API mejor: supera las limitaciones de la API estándar de Python/C, produce extensiones más consistentes y de mayor calidad, y está diseñada para que sea más difícil introducir errores
- Capacidad de evolución: como se resume bien en PEP 620, la API estándar de Python/C expone muchos detalles internos de implementación, lo que dificulta la evolución de la API de C. HPy evita este problema al ocultar todos los detalles internos de implementación
Estado actual
- HPy sigue en desarrollo activo. La versión 0.9.0 es la alfa más reciente, pero pronto dejará esa fase y el proyecto está trabajando para una versión estable
- Consideran que el ABI de HPy ya es lo bastante estable como para poder cumplir la promesa de compatibilidad binaria hacia atrás y hacia adelante en las próximas versiones
- Piensan que la API ya cubre suficientes casos de uso como para migrar paquetes importantes (en particular, revisar el port de numpy)
- También ofrece una guía de portabilidad y documentación extensa, especialmente la referencia de la API
- Siempre están abiertos a discusiones de diseño y a nuevos requisitos
Extensiones compatibles con HPy
- ultrajson-hpy: el primer módulo real portado a HPy
- piconumpy: como su nombre indica, un módulo mínimo similar a numpy que define tipos personalizados
- numpy: uno de los objetivos ambiciosos es portar numpy a HPy y usar esa experiencia para entender mejor cómo diseñar la API. Este port está a punto de pasar la suite de pruebas
- matplotlib: como también depende de NumPy, la migración al modo universal todavía no está completamente terminada. HPy ofrece una API de compatibilidad legada para poder seguir llamando funciones de la C API antigua y ejecutar con éxito la suite de pruebas
- kiwi-solver: una dependencia de Matplotlib totalmente portada al modo universal
Opinión de GN⁺
- HPy es un proyecto muy prometedor que supera las limitaciones de la API Python/C y ofrece mejor extensibilidad y portabilidad
- Resulta especialmente atractivo por su gran potencial de mejora de rendimiento en implementaciones alternativas de Python como PyPy y GraalPy
- Migrar desde la C API legada puede ser difícil, pero HPy ofrece una ruta de migración gradual que vuelve este proceso mucho más manejable
- Al adoptar HPy, hay que considerar la integración con los sistemas de compilación y pipelines de distribución existentes, la aceptación de los proyectos upstream y la madurez y estabilidad del propio HPy
- Otros proyectos con objetivos similares a HPy incluyen Cython y PyO3 de Rust. Se diferencian de HPy en que usan lenguajes de más alto nivel en lugar de la API de C de bajo nivel
1 comentarios
Comentarios de Hacker News
La parte más molesta al trabajar con la API de C es configurar las banderas de compilación/enlazado.
python3-configsolo funciona a nivel del sistema operativo, y es difícil de usar para acceder a paquetes instalados con pip.python3 -m venvno genera estos scripts, y anaconda/miniconda también es un problema. Cada paquete contamina los scripts de compilación con llamadas hardcodeadas apython3 -c "import sys: print...". Abrí un PR para agregar una banderapython3 -m sysconfig --jsona CPythonQue el lenguaje Python esté demasiado concentrado en una sola implementación podría ser una amenaza para su éxito a largo plazo. Los servidores web, los programas de línea de comandos y los dispositivos embebidos tienen requisitos distintos. Si este proyecto logra reemplazar la API de C de Python por una que no exponga detalles de implementación, podría ser más fácil mantener implementaciones alternativas y experimentar con nuevas tecnologías
Me pregunto si este proyecto ofrece bindings de Python independientes de la versión. Actualmente estamos compilando bindings por separado para cada versión, y eso consume mucho tiempo de CI/CD
Sería interesante ver benchmarks que comparen una extensión HPy con implementaciones en Cython/pybind11 en términos de rendimiento y tiempo de desarrollo
No está claro cómo encaja este proyecto con bibliotecas como PyBind11 o nanobind. Parece que habría que reescribirlas para usarlas de la misma manera
Me pregunto cuántas extensiones nuevas escritas en C se hacen hoy en día. Yo pensaba que la mayoría eran cosas como Boost Python, pybind y PyO3
Publico con frecuencia sobre implementar bindings de CPython con la menor sobrecarga posible, y quiero compartir algunas recomendaciones, preguntas y preocupaciones. Sería bueno reestructurar la landing page y el README del repositorio del proyecto HPy. Si hubiera estadísticas de adopción para PyPy, GraalPython y otros runtimes de Python, sería más convincente
Usar un objeto de contexto encapsulado como
HPyContextes útil para un futuro Python multihilo o en entornos complejos. Pero siHPyContextse redirige al singleton de CPython, entonces no se resuelve el problemaEl benchmark de 2019 menciona la convención de llamadas
METH_FASTCALLde CPython, pero no la compara. Si te importa el rendimiento, conviene parsear los argumentos directamente desde la tupla sin usar un formateador de cadenasMe pregunto si en Python existe algo simple como el ffi de luajit, donde le das headers de C y cargas una biblioteca compartida para poder usar structs y llamar funciones
Me interesa llamar a Go desde Python, y gopy genera bindings de Python para cgo. HPy<->cgo podría tener menos sobrecarga
Imaginen cuánto habría cambiado el ecosistema de Python si este trabajo se hubiera completado hace 20 años