問題タブ [pyo3]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
python-3.x - PyO3 で作成された Python バインディングを介して複数の Rust ライブラリ間で型を使用できない
いくつかのライブラリを使用して Rust プロジェクトを作成しています。一部のライブラリは、ワークスペース内の他のライブラリによって使用されるタイプをエクスポートします。Rust クレートに加えて、いくつかのライブラリを Python に公開し、pyo3クレートを使用してPython バインディングを生成したいと考えていますが、ここで問題が発生しています。
問題は次のとおりです。
2 つの Rust ライブラリ クレート とproducerがあるとしconsumerます。には、一般に公開されproducerている単純な型があり、Python モジュールの一部になっています。MyClassクレートにはconsumer、 type のオブジェクトを受け取りMyClass、それらに対していくつかの操作を実行する関数がいくつかあります。これらの関数は Rust で利用でき、2 つ目の Python モジュールにもバインドされています。
MyClassPython と Rust の両方でオブジェクトを作成できます。のオブジェクトを受け入れる Rust コードの関数を (たとえば、別のアプリケーションから) 正しく呼び出すことができますMyClass。しかし、タイプ のオブジェクトを受け入れるconsumerモジュール内の関数をPython から呼び出すことはできませんMyClass。つまり、Rust または Python で型のオブジェクトを作成MyClassして Rustconsumerクレートで使用することはできますが、オブジェクトをPython モジュールから Python モジュールに渡すことはできませんproducerconsumer。そうすることTypeErrorで、オブジェクト自体が type を持っていると宣伝しているにもかかわらず、が生成されますMyClass。なんで?
編集:さらに調査するには、質問の下部を参照してください。
MCVE を作成しました。これはGitHub から入手できます。Rust と Python のコードも以下に含まれています。
再現:
リポジトリを複製した後、次の出力を生成できます。
君は見るべきだ:
プラットフォームの詳細:
- macOS 10.14.6
- 貨物 1.44.0 (05d080faa 2020-05-06)
- rustc 1.44.0 (49cae5576 2020-06-01)
- パイソン 3.7.7
- pyo3 v0.11.1
コード:
この小さな Python スクリプトは、この問題を示しています。最初の機能は、構築されたクレートがスクリプトによってインポートできるようにすることです。
アップデート:
私はこれをさらに掘り下げてきました.Rustライブラリの構築方法から問題が何らかの形で発生するのではないかと疑い始めています. 私はライブラリ全般に精通していますが、Rust 固有のものにはあまり詳しくありません。ただし、Rust は、マングルされたすべてのシンボル名にハッシュをエンコードしているようです。私の現在の推測では、これらのハッシュはconsumer共有ライブラリと の間でわずかに異なるため、同じテキスト表現を持つproducer型にもかかわらず、関数で期待される実際の型はわずかに異なります。MyClassconsumer
これを具体化するための詳細を次に示します。各クレートのシンボルを一覧表示し、それらをデマングルすると、次のようになりrustfiltます。
クレートtype_obect_rawのシンボルに1 つ追加があることがわかります。consumerこれを確認する方法はわかりませんが、これは、consumerクレートで失敗した関数に渡されたオブジェクトを変換するために使用される型情報であると思われます。この型オブジェクトは同じ名前ですが、ハッシュが異なるため、何らかの形で異なる必要があります。
pyo3docsを見ると、このメソッドは、オブジェクトの型を表すtype_object_raw実際の値を返すために使用されます。モジュールから のインスタンスを構築するとき、型オブジェクトがシンボルから返されることはPyTypeObject私にはもっともらしいようです。しかし、 のような関数が渡された のインスタンスを変換しようとすると、シンボルを使用してオブジェクトの型を取得します。これらは異なるものと考えられます。MyClassproducertype_object_raw::h115c96004643f7dfconsumer::print_dataMyClasstype_object_raw::h0e4c5c91a2345444
だから今私の質問は、インスタンスの型を返すために2つの異なるシンボルがあるのはなぜMyClassですか?