Liaisons Rust pour Python, y compris des outils pour créer des modules d'extension Python natifs. L'exécution et l'interaction avec le code Python à partir d'un binaire Rust sont également prises en charge.
Guide de l'utilisateur : stable | principal
Documentation API : stable | principal
Nécessite Rust 1.63 ou supérieur.
PyO3 prend en charge les distributions Python suivantes :
Vous pouvez utiliser PyO3 pour écrire un module Python natif dans Rust ou pour intégrer Python dans un binaire Rust. Les sections suivantes expliquent chacun d’eux tour à tour.
PyO3 peut être utilisé pour générer un module Python natif. Le moyen le plus simple d’essayer ceci pour la première fois est d’utiliser maturin
. maturin
est un outil permettant de créer et de publier des packages Python basés sur Rust avec une configuration minimale. Les étapes suivantes installent maturin
, l'utilisent pour générer et créer un nouveau package Python, puis lancent Python pour importer et exécuter une fonction à partir du package.
Tout d'abord, suivez les commandes ci-dessous pour créer un nouveau répertoire contenant un nouveau virtualenv
Python et installez maturin
dans le virtualenv à l'aide du gestionnaire de packages de Python, pip
:
# (replace string_sum with the desired package name)
$ mkdir string_sum
$ cd string_sum
$ python -m venv .env
$ source .env/bin/activate
$ pip install maturin
Toujours dans ce répertoire string_sum
, exécutez maintenant maturin init
. Cela générera la nouvelle source du package. Lorsque vous avez le choix des liaisons à utiliser, sélectionnez les liaisons pyo3 :
$ maturin init
✔ ? What kind of bindings to use ? · pyo3
Done ! New project created string_sum
Les fichiers les plus importants générés par cette commande sont Cargo.toml
et lib.rs
, qui ressembleront à peu près à ce qui suit :
Cargo.toml
[ package ]
name = " string_sum "
version = " 0.1.0 "
edition = " 2021 "
[ lib ]
# The name of the native library. This is the name which will be used in Python to import the
# library (i.e. `import string_sum`). If you change this, you must also change the name of the
# `#[pymodule]` in `src/lib.rs`.
name = " string_sum "
# "cdylib" is necessary to produce a shared library for Python to import from.
#
# Downstream Rust code (including code in `bin/`, `examples/`, and `tests/`) will not be able
# to `use string_sum;` unless the "rlib" or "lib" crate type is also included, e.g.:
# crate-type = ["cdylib", "rlib"]
crate-type = [ " cdylib " ]
[ dependencies ]
pyo3 = { version = " 0.23.3 " , features = [ " extension-module " ] }
src/lib.rs
use pyo3 :: prelude :: * ;
/// Formats the sum of two numbers as string.
# [ pyfunction ]
fn sum_as_string ( a : usize , b : usize ) -> PyResult < String > {
Ok ( ( a + b ) . to_string ( ) )
}
/// A Python module implemented in Rust. The name of this function must match
/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to
/// import the module.
# [ pymodule ]
fn string_sum ( m : & Bound < ' _ , PyModule > ) -> PyResult < ( ) > {
m . add_function ( wrap_pyfunction ! ( sum_as_string , m ) ? ) ? ;
Ok ( ( ) )
}
Enfin, exécutez maturin develop
. Cela construira le package et l'installera dans le virtualenv Python précédemment créé et activé. Le package est alors prêt à être utilisé depuis python
:
$ maturin develop
# lots of progress output as maturin runs the compilation...
$ python
>>> import string_sum
>>> string_sum.sum_as_string(5, 20)
' 25 '
Pour apporter des modifications au package, modifiez simplement le code source de Rust, puis réexécutez maturin develop
pour recompiler.
Pour exécuter tout cela en un seul copier-coller, utilisez le script bash ci-dessous (remplacez string_sum
dans la première commande par le nom du package souhaité) :
mkdir string_sum && cd " $_ "
python -m venv .env
source .env/bin/activate
pip install maturin
maturin init --bindings pyo3
maturin develop
Si vous souhaitez pouvoir exécuter cargo test
ou utiliser ce projet dans un espace de travail Cargo et que vous rencontrez des problèmes d'éditeur de liens, il existe quelques solutions de contournement dans la FAQ.
De même qu'avec maturin
, il est possible de construire en utilisant setuptools-rust
ou manuellement. Les deux offrent plus de flexibilité que maturin
mais nécessitent plus de configuration pour démarrer.
Pour intégrer Python dans un binaire Rust, vous devez vous assurer que votre installation Python contient une bibliothèque partagée. Les étapes suivantes montrent comment garantir cela (pour Ubuntu), puis donnent un exemple de code qui exécute un interpréteur Python intégré.
Pour installer la bibliothèque partagée Python sur Ubuntu :
sudo apt install python3-dev
Pour installer la bibliothèque partagée Python sur des distributions basées sur RPM (par exemple Fedora, Red Hat, SuSE), installez le package python3-devel
.
Démarrez un nouveau projet avec cargo new
et ajoutez pyo3
au Cargo.toml
comme ceci :
[ dependencies . pyo3 ]
version = " 0.23.3 "
features = [ " auto-initialize " ]
Exemple de programme affichant la valeur de sys.version
et le nom d'utilisateur actuel :
use pyo3 :: prelude :: * ;
use pyo3 :: types :: IntoPyDict ;
use pyo3 :: ffi :: c_str ;
fn main ( ) -> PyResult < ( ) > {
Python :: with_gil ( |py| {
let sys = py . import ( "sys" ) ? ;
let version : String = sys . getattr ( "version" ) ? . extract ( ) ? ;
let locals = [ ( "os" , py . import ( "os" ) ? ) ] . into_py_dict ( py ) ? ;
let code = c_str ! ( "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'" ) ;
let user : String = py . eval ( code , None , Some ( & locals ) ) ? . extract ( ) ? ;
println ! ( "Hello {}, I'm Python {}" , user , version ) ;
Ok ( ( ) )
} )
}
Le guide comporte une section avec de nombreux exemples sur ce sujet.
built
en tant que PyDict
Tout le monde est invité à contribuer à PyO3 ! Il existe de nombreuses façons de soutenir le projet, telles que :
Nos notes de contribution et notre guide d'architecture contiennent plus de ressources si vous souhaitez consacrer du temps à PyO3 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 :
PyO3 est sous licence Apache-2.0 ou sous licence MIT, à votre choix.
Python est sous licence Python.
Sauf indication contraire explicite de votre part, toute contribution que vous soumettez intentionnellement pour inclusion dans PyO3, telle que définie dans la licence Apache, bénéficiera d'une double licence comme ci-dessus, sans termes ou conditions supplémentaires.