anteriormente pyo3-pack
Cree y publique cajas con enlaces pyo3, cffi y uniffi, así como binarios oxidados como paquetes de Python con una configuración mínima. Admite la creación de ruedas para Python 3.8+ en Windows, Linux, Mac y FreeBSD, puede cargarlas en pypi y tiene soporte básico para pypy y graalpy.
¡Consulta la Guía del usuario!
Puede descargar archivos binarios de la última versión o instalarlos con pipx:
pipx install maturin
Nota
pip install maturin
también debería funcionar si no desea utilizar pipx.
Hay cuatro comandos principales:
maturin new
crea un nuevo proyecto de carga con maturin configurado.maturin publish
construye la caja en paquetes de Python y los publica en pypi.maturin build
construye las ruedas y las almacena en una carpeta ( target/wheels
por defecto), pero no las carga. Es posible subirlos con cordel o maturin upload
.maturin develop
construye la caja y la instala como un módulo de Python directamente en el virtualenv actual. Tenga en cuenta que, si bien maturin develop
es más rápido, no admite todas las funciones que admite la ejecución pip install
después de maturin build
. Los enlaces de pyo3
se detectan automáticamente. Para cffi o binarios, debe pasar -b cffi
o -b bin
. maturin no necesita archivos de configuración adicionales y no choca con una configuración existente de setuptools-rust o milksnake. Incluso puedes integrarlo con herramientas de prueba como tox. Hay ejemplos de los diferentes enlaces en la carpeta test-crates
.
El nombre del paquete será el nombre del proyecto de carga, es decir, el campo de nombre en la sección [package]
de Cargo.toml
. El nombre del módulo que está utilizando al importar será el valor name
en la sección [lib]
(que por defecto es el nombre del paquete). Para los binarios, es simplemente el nombre del binario generado por la carga.
Al utilizar los comandos maturin build
y maturin develop
, puede compilar un programa de rendimiento optimizado agregando el indicador -r
o --release
.
Los paquetes de Python vienen en dos formatos: un formulario integrado llamado rueda y distribuciones de origen (sdist), los cuales son archivos. Una rueda puede ser compatible con cualquier versión de Python, intérprete (cpython y pypy, principalmente), sistema operativo y arquitectura de hardware (para ruedas de Python puras), puede limitarse a una plataforma y arquitectura específicas (por ejemplo, cuando se usan ctypes o cffi) o a un intérprete de Python específico y una versión en una arquitectura y sistema operativo específicos (por ejemplo, con pyo3).
Cuando se utiliza pip install
en un paquete, pip intenta encontrar una rueda coincidente e instalarla. Si no encuentra ninguno, descarga la distribución fuente y construye una rueda para la plataforma actual, lo que requiere la instalación de los compiladores adecuados. Instalar una rueda es mucho más rápido que instalar una distribución fuente, ya que la creación de ruedas generalmente es lenta.
Cuando publicas un paquete para que sea instalable con pip install
, lo subes a pypi, el repositorio oficial de paquetes. Para realizar pruebas, puede usar test pypi en su lugar, que puede usar con pip install --index-url https://test.pypi.org/simple/
. Tenga en cuenta que para publicar para Linux, necesita usar el contenedor acoplable manylinux, mientras que para publicar desde su repositorio puede usar la acción de github PyO3/maturin-action.
Para pyo3, maturin solo puede crear paquetes para las versiones de Python instaladas. En Linux y Mac, se utilizan todas las versiones de Python en PATH
. Si no configura sus propios intérpretes con -i
, se utiliza una heurística para buscar instalaciones de Python. En Windows, se utilizan todas las versiones del iniciador de Python (que el instalador de python.org instala de forma predeterminada) y todos los entornos conda excepto el base. Puede comprobar qué versiones se seleccionan con el subcomando list-python
.
pyo3 configurará el intérprete de Python usado en la variable de entorno PYTHON_SYS_EXECUTABLE
, que se puede usar desde scripts de compilación personalizados. Maturin puede construir y cargar ruedas para pypy con pyo3, aunque solo se prueba pypy3.7-7.3 en Linux.
Las ruedas Cffi son compatibles con todas las versiones de Python, incluido pypy. Si cffi
no está instalado y Python se está ejecutando dentro de un virtualenv, maturin lo instalará; de lo contrario, tendrá que instalarlo usted mismo ( pip install cffi
).
maturin usa cbindgen para generar un archivo de encabezado, que se puede personalizar configurando cbindgen a través de un archivo cbindgen.toml
dentro de la raíz de su proyecto. Alternativamente, puede utilizar un script de compilación que escriba un archivo de encabezado en $PROJECT_ROOT/target/header.h
.
Basado en el archivo de encabezado, maturin genera un módulo que exporta un objeto ffi
y lib
.
use cbindgen ;
use std :: env ;
use std :: path :: Path ;
fn main ( ) {
let crate_dir = env :: var ( "CARGO_MANIFEST_DIR" ) . unwrap ( ) ;
let bindings = cbindgen :: Builder :: new ( )
. with_no_includes ( )
. with_language ( cbindgen :: Language :: C )
. with_crate ( crate_dir )
. generate ( )
. unwrap ( ) ;
bindings . write_to_file ( Path :: new ( "target" ) . join ( "header.h" ) ) ;
}
Los enlaces uniffi utilizan uniffi-rs para generar enlaces ctypes
de Python a partir de un archivo de definición de interfaz. Las ruedas uniffi son compatibles con todas las versiones de Python, incluido pypy.
Para crear un proyecto mixto de Rust/python, cree una carpeta con el nombre de su módulo (es decir, lib.name
en Cargo.toml) al lado de Cargo.toml y agregue sus fuentes de Python allí:
my-project
├── Cargo.toml
├── my_project
│ ├── __init__.py
│ └── bar.py
├── pyproject.toml
├── README.md
└── src
└── lib.rs
Puede especificar un directorio de origen de Python diferente en pyproject.toml
configurando tool.maturin.python-source
, por ejemplo
pyproject.toml
[ tool . maturin ]
python-source = " python "
module-name = " my_project._lib_name "
entonces la estructura del proyecto se vería así:
my-project
├── Cargo.toml
├── python
│ └── my_project
│ ├── __init__.py
│ └── bar.py
├── pyproject.toml
├── README.md
└── src
└── lib.rs
Nota
Se recomienda esta estructura para evitar un error común ImportError
maturin agregará la extensión nativa como un módulo en su carpeta de Python. Al usar desarrollar, maturin copiará la biblioteca nativa y, para cffi, también el código adhesivo a su carpeta de Python. Deberías agregar esos archivos a tu gitignore.
Con cffi puedes hacerlo from .my_project import lib
y luego usar lib.my_native_function
, con pyo3 puedes directamente from .my_project import my_native_function
.
Diseño de ejemplo con pyo3 después maturin develop
:
my-project
├── Cargo.toml
├── my_project
│ ├── __init__.py
│ ├── bar.py
│ └── _lib_name.cpython-36m-x86_64-linux-gnu.so
├── README.md
└── src
└── lib.rs
Al hacer esto, también asegúrese de configurar el nombre del módulo en su código para que coincida con la última parte del module-name
(no incluya la ruta del paquete):
# [ pymodule ] # [ pyo3 ( name= "_lib_name" ) ] fn my_lib_name ( _py : Python < ' _ > , m : & PyModule ) -> PyResult < ( ) > { m . add_class :: < MyPythonRustClass > ( ) ? ; Ok ( ( ) ) }
maturin admite PEP 621, puede especificar los metadatos del paquete Python en pyproject.toml
. maturin fusiona metadatos de Cargo.toml
y pyproject.toml
, pyproject.toml
tiene prioridad sobre Cargo.toml
.
Para especificar las dependencias de Python, agregue una lista dependencies
en una sección [project]
en pyproject.toml
. Esta lista es equivalente a install_requires
en setuptools:
[ project ]
name = " my-project "
dependencies = [ " flask~=1.1.0 " , " toml==0.10.0 " ]
Pip permite agregar los llamados scripts de consola, que son comandos de shell que ejecutan alguna función en su programa. Puede agregar scripts de consola en una sección [project.scripts]
. Las claves son los nombres de los scripts, mientras que los valores son la ruta a la función en el formato some.module.path:class.function
, donde la parte class
es opcional. La función se llama sin argumentos. Ejemplo:
[ project . scripts ]
get_42 = " my_project:DummyClass.get_42 "
También puede especificar clasificadores de tesoros en su pyproject.toml
en project.classifiers
:
[ project ]
name = " my-project "
classifiers = [ " Programming Language :: Python " ]
maturin admite la construcción a través de pyproject.toml
. Para usarlo, cree un pyproject.toml
junto a su Cargo.toml
con el siguiente contenido:
[ build-system ]
requires = [ " maturin>=1.0,<2.0 " ]
build-backend = " maturin "
Si está presente un pyproject.toml
con una entrada [build-system]
, maturin puede crear una distribución fuente de su paquete cuando se especifica --sdist
. La distribución fuente contendrá los mismos archivos que cargo package
. Para crear solo una distribución fuente, pase --interpreter
sin ningún valor.
Luego puede, por ejemplo, instalar su paquete con pip install .
. Con pip install . -v
puedes ver la salida de cargo y maturin.
Puede usar las opciones compatibility
, skip-auditwheel
, bindings
, strip
y opciones comunes de compilación de Cargo, como features
en [tool.maturin]
de la misma manera que lo haría cuando ejecuta maturin directamente. La clave bindings
es necesaria para los proyectos cffi y bin, ya que no se pueden detectar automáticamente. Actualmente, todas las compilaciones están en modo de lanzamiento (consulte este hilo para obtener más detalles).
Para una compilación que no sea de manylinux con enlaces cffi, puede usar lo siguiente:
[ build-system ]
requires = [ " maturin>=1.0,<2.0 " ]
build-backend = " maturin "
[ tool . maturin ]
bindings = " cffi "
compatibility = " linux "
La opción manylinux
también se acepta como alias de compatibility
para compatibilidad con versiones anteriores de maturin.
Para incluir archivos arbitrarios en sdist para su uso durante la compilación, especifique include
como una matriz de path
globales con format
establecido en sdist
:
[ tool . maturin ]
include = [{ path = " path/**/* " , format = " sdist " }]
Hay un comando maturin sdist
solo para crear una distribución fuente como solución alternativa para pypa/pip#6041.
Por razones de portabilidad, los módulos nativos de Python en Linux solo deben vincular dinámicamente un conjunto de muy pocas bibliotecas que se instalan básicamente en todas partes, de ahí el nombre manylinux. Pypa ofrece imágenes acoplables especiales y una herramienta llamada auditwheel para garantizar el cumplimiento de las reglas de manylinux. Si desea publicar ruedas ampliamente utilizables para Linux pypi, debe utilizar una imagen acoplable de manylinux .
El compilador Rust desde la versión 1.64 requiere al menos glibc 2.17, por lo que debes usar al menos manylinux2014. Para la publicación, recomendamos aplicar la misma versión de manylinux que la imagen con el indicador manylinux, por ejemplo, use --manylinux 2014
si está compilando en quay.io/pypa/manylinux2014_x86_64
. La acción de github PyO3/maturin-action ya se encarga de esto si configura, por ejemplo, manylinux: 2014
.
maturin contiene una reimplementación de auditwheel que verifica automáticamente la biblioteca generada y le da a la rueda la etiqueta de plataforma adecuada. Si el glibc de su sistema es demasiado nuevo o vincula otras bibliotecas compartidas, le asignará la etiqueta linux
. También puede deshabilitar manualmente esas comprobaciones y usar directamente el destino nativo de Linux con --manylinux off
.
Para cumplir plenamente con manylinux, debe compilar en un contenedor acoplable de CentOS. La imagen pyo3/maturin se basa en la imagen manylinux2014 y pasa argumentos al binario maturin
. Puedes usarlo así:
docker run --rm -v $(pwd):/io ghcr.io/pyo3/maturin build --release # or other maturin arguments
Tenga en cuenta que esta imagen es muy básica y solo contiene Python, Maturin y Rust estable. Si necesita herramientas adicionales, puede ejecutar comandos dentro del contenedor manylinux. Consulte konstin/complex-manylinux-maturin-docker para ver un pequeño ejemplo educativo o nanoporetech/fast-ctc-decode para una configuración del mundo real.
maturin en sí es compatible con manylinux cuando se compila para el objetivo musl.
¡Todos son bienvenidos a contribuir a maturin! Hay muchas formas de apoyar el proyecto, tales como:
Nuestras notas de contribución tienen más recursos si desea ofrecer tiempo como voluntario para maturin y está buscando por dónde empezar.
Si no tiene tiempo para contribuir pero aún desea apoyar el éxito futuro del proyecto, algunos de nuestros mantenedores tienen páginas de patrocinio de GitHub:
Licenciado bajo cualquiera de:
a tu elección.