HeadlinesBriefing favicon HeadlinesBriefing.com

PyO3でPython上でRust JSONパーサーを実行する

Hacker News •
×

Pydantic v2でデータを検証するたびに——ほとんどのPythonアプリが利用するデータ検証ライブラリ——Rust拡張が実際の処理を行います。そのコアであるpydantic-coreはPyO3で構築されており、本記事でも同じツールチェーンを用いて小さなRust JSONパーサーをPythonパッケージとして公開しています。

RustコードをPythonに組み込むには4ステップ: 通常のRustモジュールを書き、PyO3マクロでアノテートし、maturinでコンパイル・インストールし、結果をインポートします。#[pyfunction]と#[pymodule]がグルーコード、型変換、参照カウントを追加します。Maturinはクレートを共有ライブラリとしてコンパイルし、仮想環境に配置します。

パーサーはプレーンなRust列挙型を生成します: Null、Boolean(bool)、Number(f64)、String(String)、Array(Vec<Json Value>)、Object(Hash Map<String, Json Value>)。Rustの属性マクロは、それが付与された関数を書き換えます。これはPythonのデコレータに似ています。我々のPythonからRustへのコホートでは、学生が6週間かけてRustでJSONパーサーをスクラッチから書きます。手書きのトークナイザと再帰下降パーサーでserdeは使いません。その後PyO3経由でPythonに公開します。Joshのバージョンは実世界のフィクスチャでCPythonのC jsonモジュールを上回り、JochenのバージョンはPython版の最大3.5倍高速でした。

公開されているリファレンス実装は、学生が開始地点とするクリーンなバージョンです。parse_json<'py>(py: Python<'py>, input: &str) -> Py Result<Bound<'py, Py Any>>は値を返すかPython例外を送出します。従来のPythonビルドでは、このアクセスはGILの保持に関連付けられます。PyO3がそれを渡し、Pythonオブジェクトに触れる場所すべてでそれを渡します。

主要エンティティ: 人物: Josh、Jochen