ネイティブ Python 拡張モジュールを作成するためのツールを含む、Python 用の Rust バインディング。 Rust バイナリからの Python コードの実行と対話もサポートされています。
ユーザーガイド: 安定版 |主要
API ドキュメント: 安定版 |主要
Rust 1.63 以降が必要です。
PyO3 は次の Python ディストリビューションをサポートしています。
PyO3 を使用して、Rust でネイティブ Python モジュールを作成したり、Rust バイナリに Python を埋め込んだりできます。次のセクションでは、これらのそれぞれについて順番に説明します。
PyO3 を使用してネイティブ Python モジュールを生成できます。これを初めて試す最も簡単な方法は、 maturin
使用することです。 maturin
、最小限の構成で Rust ベースの Python パッケージを構築および公開するためのツールです。次の手順では、 maturin
インストールし、それを使用して新しい Python パッケージを生成および構築し、Python を起動してパッケージから関数をインポートして実行します。
まず、以下のコマンドに従って、新しい Python virtualenv
含む新しいディレクトリを作成し、Python のパッケージ マネージャーpip
使用してmaturin
virtualenv にインストールします。
# (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
まだこのstring_sum
ディレクトリ内にあるので、 maturin init
を実行します。これにより、新しいパッケージ ソースが生成されます。使用するバインディングを選択する場合は、pyo3 バインディングを選択します。
$ maturin init
✔ ? What kind of bindings to use ? · pyo3
Done ! New project created string_sum
このコマンドによって生成される最も重要なファイルはCargo.toml
とlib.rs
で、おおよそ次のようになります。
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 ( ( ) )
}
最後に、 maturin develop
実行します。これにより、パッケージがビルドされ、以前に作成されアクティブ化された Python virtualenv にインストールされます。これで、パッケージをpython
から使用できるようになります。
$ maturin develop
# lots of progress output as maturin runs the compilation...
$ python
>>> import string_sum
>>> string_sum.sum_as_string(5, 20)
' 25 '
パッケージに変更を加えるには、Rust ソース コードを編集し、 maturin develop
再実行して再コンパイルするだけです。
これをすべて 1 回のコピーアンドペーストとして実行するには、以下の bash スクリプトを使用します (最初のコマンドのstring_sum
目的のパッケージ名に置き換えます)。
mkdir string_sum && cd " $_ "
python -m venv .env
source .env/bin/activate
pip install maturin
maturin init --bindings pyo3
maturin develop
cargo test
実行したり、Cargo ワークスペースでこのプロジェクトを使用したりする必要があり、リンカーの問題が発生した場合は、FAQ にいくつかの回避策があります。
maturin
と同様に、 setuptools-rust
使用するか手動でビルドすることも可能です。どちらもmaturin
よりも柔軟性が高くなりますが、開始するにはより多くの構成が必要です。
Python を Rust バイナリに埋め込むには、Python インストールに共有ライブラリが含まれていることを確認する必要があります。次の手順では、これを確実に行う方法 (Ubuntu の場合) を示し、埋め込み Python インタープリターを実行するコード例を示します。
Python 共有ライブラリを Ubuntu にインストールするには:
sudo apt install python3-dev
RPM ベースのディストリビューション (Fedora、Red Hat、SuSE など) に Python 共有ライブラリをインストールするには、 python3-devel
パッケージをインストールします。
cargo new
で新しいプロジェクトを開始し、次のようにpyo3
Cargo.toml
に追加します。
[ dependencies . pyo3 ]
version = " 0.23.3 "
features = [ " auto-initialize " ]
sys.version
の値と現在のユーザー名を表示するプログラム例:
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 ( ( ) )
} )
}
このガイドには、このトピックに関する多くの例が記載されたセクションがあります。
built
クレートで取得したメタデータをPyDict
として公開する単純なマクロ誰でも PyO3 に貢献することを歓迎します。プロジェクトをサポートするには、次のようなさまざまな方法があります。
PyO3 のボランティア活動を希望していて、どこから始めればよいかを探している場合は、私たちの寄稿ノートとアーキテクチャ ガイドにさらに多くのリソースがあります。
自分で貢献する時間がないが、プロジェクトの将来の成功をサポートしたい場合は、一部のメンテナーが GitHub スポンサーシップ ページを持っています。
PyO3 は、オプションで Apache-2.0 ライセンスまたは MIT ライセンスに基づいてライセンスされます。
Python は Python License に基づいてライセンスされています。
あなたが明示的に別段の定めをしない限り、Apache ライセンスに定義されているように、あなたが PyO3 に含めるために意図的に提出した投稿は、追加の条項や条件なしで上記のように二重ライセンスされるものとします。