はじめに
備忘用。②以降も書くかもしれない。
勉強し始めの初心者のため、何か指摘や気づきがあれば是非コメントお願いします。
→(追記)②を書きました。
実行環境
Windows 11
uv 0.5.24
python 3.12.1
rustup 1.27.1
rustc 1.79.0
cargo 1.79.0
maturin 1.5.1
pyo3 0.22.4
プロジェクト作成
参考:https://docs.astral.sh/uv/concepts/projects/init/#projects-with-extension-modules
公式docの通り、以下を実行すると、プロジェクトが作成されます。
> uv init --build-backend maturin example-ext
ディレクトリ構成は以下の通り。
> tree /f example-ext
example-ext
│ .gitignore
│ .python-version
│ Cargo.toml
│ pyproject.toml
│ README.md
│
└─src
│ lib.rs
│
└─example_ext
_core.pyi
__init__.py
主要なファイルの内容は以下の通り。
use pyo3::prelude::*;
#[pyfunction]
fn hello_from_bin() -> String {
"Hello from example-ext!".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 _core(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(hello_from_bin, m)?)?;
Ok(())
}
from example_ext._core import hello_from_bin
def main() -> None:
print(hello_from_bin())
上記のコードでは、Hello from example-ext!
という文字列を返すRustのhello_from_bin()
関数を、Pythonの__init__.py
のmain
関数で呼び出し、返り値の文字列をPrint出力しています。
hello_from_bin()
のインポート文はfrom example_ext._core import hello_from_bin
ですが、この_core
の部分を変更したい場合は、lib.rs
の他にCargo.toml
も修正する必要があります。
[package]
name = "example_ext"
version = "0.1.0"
edition = "2021"
[lib]
name = "_core" # => ここを変える
# "cdylib" is necessary to produce a shared library for Python to import from.
crate-type = ["cdylib"]
[dependencies]
# "extension-module" tells pyo3 we want to build an extension module (skips linking against libpython.so)
# "abi3-py39" tells pyo3 (and maturin) to build using the stable ABI with minimum Python version 3.9
pyo3 = { version = "0.22.4", features = ["extension-module", "abi3-py39"] }
Hello World 実行
以下でビルドとsrc/__init__.py
のmain
関数の実行を同時に行います。
この時、プロジェクト用の仮想環境が.venv
配下に作成されます。また、src/example_ext
配下にRustのバイナリ(_core.pyd
)が作成されます。
>uv run --directory src/example_ext example-ext
Using CPython 3.12.1 interpreter at: C:\Python312\python.exe
Creating virtual environment at: C:\path\example-ext\.venv
Built example-ext @ file:///C:/path/example-ext
Installed 1 package in 21ms
Hello from example-ext!
ビルドは初回のみで、2回目の実行以降はHello ...
のみ出力されます。
>uv run --directory src/example_ext example-ext
Hello from example-ext!
なお、lib.rs
の内容を変更し、再ビルドする場合はuv run
実行時に--reinstall
オプションを加える必要があります。以下は、Hello from example-ext!
という文字列をHello World!
に変更した例です。
> xuv run --reinstall --directory src/example_ext example-ext
Built example-ext @ file:///C:/path/example-ext
Uninstalled 1 package in 2ms
Installed 1 package in 18ms
Hello World!