anciennement pyo3-pack
Créez et publiez des caisses avec les liaisons pyo3, cffi et uniffi ainsi que des binaires Rust sous forme de packages Python avec une configuration minimale. Il prend en charge la création de roues pour Python 3.8+ sur Windows, Linux, Mac et Freebsd, peut les télécharger sur pypi et dispose d'un support de base pour pypy et graalpy.
Consultez le guide de l'utilisateur !
Vous pouvez soit télécharger les binaires de la dernière version, soit les installer avec pipx :
pipx install maturin
Note
pip install maturin
devrait également fonctionner si vous ne souhaitez pas utiliser pipx.
Il existe quatre commandes principales :
maturin new
crée un nouveau projet cargo avec maturin configuré.maturin publish
construit la caisse dans des packages python et les publie sur pypi.maturin build
construit les roues et les stocke dans un dossier ( target/wheels
par défaut), mais ne les télécharge pas. Il est possible de télécharger ceux-ci avec twine ou maturin upload
.maturin develop
construit la caisse et l'installe en tant que module python directement dans le virtualenv actuel. Notez que même si maturin develop
est plus rapide, il ne prend pas en charge toutes les fonctionnalités prises en charge par l'exécution pip install
après maturin build
. Les liaisons pyo3
sont automatiquement détectées. Pour cffi ou les binaires, vous devez passer -b cffi
ou -b bin
. maturin n'a pas besoin de fichiers de configuration supplémentaires et n'entre pas en conflit avec une configuration setuptools-rust ou milksnake existante. Vous pouvez même l'intégrer à des outils de test tels que tox. Il existe des exemples pour les différentes liaisons dans le dossier test-crates
.
Le nom du package sera le nom du projet cargo, c'est à dire le champ name dans la section [package]
de Cargo.toml
. Le nom du module que vous utilisez lors de l'importation sera la valeur name
dans la section [lib]
(qui est par défaut le nom du package). Pour les binaires, c'est simplement le nom du binaire généré par cargo.
Lorsque vous utilisez les commandes maturin build
et maturin develop
, vous pouvez compiler un programme aux performances optimisées en ajoutant l'indicateur -r
ou --release
.
Les packages Python se présentent sous deux formats : Une forme construite appelée distributions wheel et source (sdist), qui sont toutes deux des archives. Une roue peut être compatible avec n'importe quelle version de Python, interpréteur (cpython et pypy, principalement), système d'exploitation et architecture matérielle (pour les roues Python pures), peut être limitée à une plate-forme et une architecture spécifiques (par exemple lors de l'utilisation de ctypes ou cffi) ou à un interpréteur python spécifique et une version sur une architecture et un système d'exploitation spécifiques (par exemple avec pyo3).
Lorsque vous utilisez pip install
sur un package, pip essaie de trouver une roue correspondante et de l'installer. S'il n'en trouve pas, il télécharge la distribution source et crée une roue pour la plate-forme actuelle, ce qui nécessite l'installation des compilateurs appropriés. L'installation d'une roue est beaucoup plus rapide que l'installation d'une distribution source car la construction de roues est généralement lente.
Lorsque vous publiez un package installable avec pip install
, vous le téléchargez sur pypi, le référentiel officiel de packages. Pour les tests, vous pouvez utiliser test pypi à la place, que vous pouvez utiliser avec pip install --index-url https://test.pypi.org/simple/
. Notez que pour publier pour Linux, vous devez utiliser le conteneur docker manylinux, tandis que pour publier à partir de votre référentiel, vous pouvez utiliser l'action github PyO3/maturin-action.
Pour pyo3, maturin ne peut créer des packages que pour les versions python installées. Sous Linux et Mac, toutes les versions de Python dans PATH
sont utilisées. Si vous ne définissez pas vos propres interprètes avec -i
, une heuristique est utilisée pour rechercher les installations Python. Sous Windows, toutes les versions du lanceur python (qui est installé par défaut par le programme d'installation de python.org) et tous les environnements conda à l'exception de la base sont utilisés. Vous pouvez vérifier quelles versions sont récupérées avec la sous-commande list-python
.
pyo3 définira l'interpréteur python utilisé dans la variable d'environnement PYTHON_SYS_EXECUTABLE
, qui peut être utilisée à partir de scripts de construction personnalisés. Maturin peut créer et télécharger des roues pour pypy avec pyo3, même si seul pypy3.7-7.3 sous Linux est testé.
Les roues Cffi sont compatibles avec toutes les versions de Python, y compris pypy. Si cffi
n'est pas installé et que python s'exécute dans un virtualenv, maturin l'installera, sinon vous devrez l'installer vous-même ( pip install cffi
).
maturin utilise cbindgen pour générer un fichier d'en-tête, qui peut être personnalisé en configurant cbindgen via un fichier cbindgen.toml
à la racine de votre projet. Vous pouvez également utiliser un script de construction qui écrit un fichier d'en-tête dans $PROJECT_ROOT/target/header.h
.
Sur la base du fichier d'en-tête, maturin génère un module qui exporte un objet ffi
et 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" ) ) ;
}
Les liaisons uniffi utilisent uniffi-rs pour générer des liaisons Python ctypes
à partir d'un fichier de définition d'interface. Les roues uniffi sont compatibles avec toutes les versions de Python, y compris pypy.
Pour créer un projet mixte rust/python, créez un dossier avec le nom de votre module (c'est-à-dire lib.name
dans Cargo.toml) à côté de votre Cargo.toml et ajoutez-y vos sources python :
my-project
├── Cargo.toml
├── my_project
│ ├── __init__.py
│ └── bar.py
├── pyproject.toml
├── README.md
└── src
└── lib.rs
Vous pouvez spécifier un répertoire source Python différent dans pyproject.toml
en définissant tool.maturin.python-source
, par exemple
pyproject.toml
[ tool . maturin ]
python-source = " python "
module-name = " my_project._lib_name "
alors la structure du projet ressemblerait à ceci :
my-project
├── Cargo.toml
├── python
│ └── my_project
│ ├── __init__.py
│ └── bar.py
├── pyproject.toml
├── README.md
└── src
└── lib.rs
Note
Cette structure est recommandée pour éviter un piège courant ImportError
maturin ajoutera l'extension native en tant que module dans votre dossier python. Lors de l'utilisation de develop, maturin copiera la bibliothèque native et pour cffi également le code de colle dans votre dossier python. Vous devez ajouter ces fichiers à votre gitignore.
Avec cffi, vous pouvez le faire from .my_project import lib
puis utiliser lib.my_native_function
, avec pyo3 vous pouvez directement from .my_project import my_native_function
.
Exemple de mise en page avec pyo3 aprè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
En faisant cela, assurez-vous également de définir le nom du module dans votre code pour qu'il corresponde à la dernière partie du module-name
(n'incluez pas le chemin du package) :
# [ pymodule ] # [ pyo3 ( name= "_lib_name" ) ] fn my_lib_name ( _py : Python < ' _ > , m : & PyModule ) -> PyResult < ( ) > { m . add_class :: < MyPythonRustClass > ( ) ? ; Ok ( ( ) ) }
maturin prend en charge PEP 621, vous pouvez spécifier les métadonnées du package python dans pyproject.toml
. maturin fusionne les métadonnées de Cargo.toml
et pyproject.toml
, pyproject.toml
a priorité sur Cargo.toml
.
Pour spécifier les dépendances Python, ajoutez une liste dependencies
dans une section [project]
du pyproject.toml
. Cette liste est équivalente à install_requires
dans setuptools :
[ project ]
name = " my-project "
dependencies = [ " flask~=1.1.0 " , " toml==0.10.0 " ]
Pip permet d'ajouter des scripts de console, qui sont des commandes shell qui exécutent certaines fonctions de votre programme. Vous pouvez ajouter des scripts de console dans une section [project.scripts]
. Les clés sont les noms du script tandis que les valeurs sont le chemin d'accès à la fonction au format some.module.path:class.function
, où la partie class
est facultative. La fonction est appelée sans argument. Exemple:
[ project . scripts ]
get_42 = " my_project:DummyClass.get_42 "
Vous pouvez également spécifier des classificateurs trove dans votre pyproject.toml
sous project.classifiers
:
[ project ]
name = " my-project "
classifiers = [ " Programming Language :: Python " ]
maturin prend en charge la construction via pyproject.toml
. Pour l'utiliser, créez un pyproject.toml
à côté de votre Cargo.toml
avec le contenu suivant :
[ build-system ]
requires = [ " maturin>=1.0,<2.0 " ]
build-backend = " maturin "
Si un pyproject.toml
avec une entrée [build-system]
est présent, maturin peut créer une distribution source de votre package lorsque --sdist
est spécifié. La distribution source contiendra les mêmes fichiers que cargo package
. Pour créer uniquement une distribution source, transmettez --interpreter
sans aucune valeur.
Vous pouvez ensuite par exemple installer votre package avec pip install .
. Avec pip install . -v
vous pouvez voir la sortie de cargo et maturin.
Vous pouvez utiliser les options compatibility
, skip-auditwheel
, bindings
, strip
et les options de construction Cargo communes telles que features
sous [tool.maturin]
de la même manière que vous le feriez lors de l'exécution directe de maturin. La clé bindings
est requise pour les projets cffi et bin car ceux-ci ne peuvent pas être détectés automatiquement. Actuellement, toutes les versions sont en mode release (voir ce fil pour plus de détails).
Pour une version non-manylinux avec des liaisons cffi, vous pouvez utiliser ce qui suit :
[ build-system ]
requires = [ " maturin>=1.0,<2.0 " ]
build-backend = " maturin "
[ tool . maturin ]
bindings = " cffi "
compatibility = " linux "
L'option manylinux
est également acceptée comme alias de compatibility
pour une compatibilité ascendante avec l'ancienne version de maturin.
Pour inclure des fichiers arbitraires dans la sdist à utiliser lors de la compilation, spécifiez include
sous forme de tableau de path
globs avec format
défini sur sdist
:
[ tool . maturin ]
include = [{ path = " path/**/* " , format = " sdist " }]
Il existe une commande maturin sdist
pour créer uniquement une distribution source comme solution de contournement pour pypa/pip#6041.
Pour des raisons de portabilité, les modules Python natifs sous Linux ne doivent lier dynamiquement qu'un ensemble de très peu de bibliothèques installées pratiquement partout, d'où le nom manylinux. Le pypa propose des images Docker spéciales et un outil appelé auditwheel pour garantir le respect des nombreuses règles Linux. Si vous souhaitez publier des roues largement utilisables pour Linux pypi, vous devez utiliser une multitude d'images Docker Linux .
Le compilateur Rust depuis la version 1.64 nécessite au moins la glibc 2.17, vous devez donc utiliser au moins manylinux2014. Pour la publication, nous vous recommandons d'appliquer la même version manylinux que l'image avec l'indicateur manylinux, par exemple, utilisez --manylinux 2014
si vous construisez dans quay.io/pypa/manylinux2014_x86_64
. L'action github PyO3/maturin-action s'en charge déjà si vous définissez par exemple manylinux: 2014
.
maturin contient une réimplémentation d'auditwheel qui vérifie automatiquement la bibliothèque générée et donne à la roue la balise de plate-forme appropriée. Si la glibc de votre système est trop récente ou si vous liez d'autres bibliothèques partagées, elle attribuera la balise linux
. Vous pouvez également désactiver manuellement ces vérifications et utiliser directement la cible Linux native avec --manylinux off
.
Pour une conformité totale avec Manylinux, vous devez compiler dans un conteneur Docker CentOS. L'image pyo3/maturin est basée sur l'image manylinux2014 et transmet les arguments au binaire maturin
. Vous pouvez l'utiliser comme ceci :
docker run --rm -v $(pwd):/io ghcr.io/pyo3/maturin build --release # or other maturin arguments
Notez que cette image est très basique et ne contient que python, maturin et stable rust. Si vous avez besoin d'outils supplémentaires, vous pouvez exécuter des commandes dans le conteneur manylinux. Voir konstin/complex-manylinux-maturin-docker pour un petit exemple pédagogique ou nanoporetech/fast-ctc-decode pour une configuration du monde réel.
maturin lui-même est compatible avec Manylinux lorsqu'il est compilé pour la cible musl.
Tout le monde est invité à contribuer à Maturin ! Il existe de nombreuses façons de soutenir le projet, telles que :
Nos notes de contribution contiennent plus de ressources si vous souhaitez consacrer du temps à la maturité et cherchez par où commencer.
Si vous n'avez pas le temps de contribuer vous-même mais souhaitez tout de même soutenir le succès futur du projet, certains de nos responsables ont des pages de parrainage GitHub :
Licence sous l'un des titres suivants :
à votre choix.