问题标签 [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.

0 投票
0 回答
413 浏览

rust - 使用 PyAny 将 Rust 创建的对象从 Python 传递回 Rust

我在 Rust 中有一个 struct + 实现,我返回 Python。这个对象也可以传Rust 做进一步的工作。(在我的实际代码中,我使用的是 a HashMap<String, MyStruct>,但即使直接使用 struct 似乎也会导致相同的问题,因此我的示例使用struct Person简单。)

看来我需要impl FromPyObject for Person但 Rust 找不到方法PyAnydowncast

这是将 Rust 对象从 Python 传回 Rust 的正确方法吗?如果是这样,在这里使用的正确方法是PyAny什么?

0 投票
0 回答
452 浏览

python - Rust Pyo3 绑定:如何在通用 rust 类型上重用 python 方法

我有一个比这更复杂的问题。但我认为这打破了它。我有一些通用结构,它有三个构造函数来获得一个具体的类型结构。除了构造函数之外,它们都具有相同的泛型方法。我想要的是这样的:

当我尝试编译这个。pyo3警告我它不能使用泛型。error: #[pyclass] cannot have generic parameters.

是否可以创建某种通用基础class来继承具体类型?

完成;这是我的Cargo.toml

0 投票
1 回答
183 浏览

python - 如何使用 PyO3 解组 PyCodeObject?

我正在阅读 .pyc 文件,并且需要能够解组代码对象。当我尝试将未编组的内容向下转换PyAny为 时PyCodeObject,我收到以下错误消息:

这样做的正确方法是什么?

MCVE

创建测试文件:

  1. 创建一个 .py 文件
  2. 在 Python 中导入模块(例如python(3) -c 'import ...'
  3. __pycache__文件夹中应该有一个 .pyc 文件
  4. 将调用中代码中的路径替换为include_bytes!实际路径

版本信息

  • 生锈 2018
  • rustc 1.43.0-nightly (564758c4c 2020-03-08)
  • 货物 1.43.0-nightly (bda50510d 2020-03-02)
  • CPython 3.7.3
  • PyO3 0.9.1
0 投票
0 回答
470 浏览

python - 如何有效地将 Python 结构转换为 serde_json::Value?

语境

我为 JSON Schema 验证实现了一个 Rust 库,它与serde_json::Value实例一起运行。现在我想从 Python 中使用它并考虑PyO3作为连接它们的主要选择。Python 值应该serde_json::Value在传递到库时转换为 Python 值,并且serde_json::Value应该在 Rust 部分返回的验证错误内转换回 Python。

一种可能的方法是实现serde::se::Serialize一个新类型的包装器pyo3::types::PyAny,然后将其传递给serde_json::to_value,但我不确定它的效率如何。有哪些选择以及有哪些取舍?

在 Python 方面,我最感兴趣的是内置类型,它们可以由 序列化json.dumps,目前没有自定义类。

生锈方面的例子:

即有一个函数接受两个引用serde_json::Value,我想将它公开给 Python。从 Python 方面来看,可能有两个用例:

  1. 该实例是一个 JSON 编码的字符串:
  1. 该实例是一个 Python 结构(不是 JSON 编码的字符串):

可能的用例

  1. Web 应用程序请求/响应结构验证。

    • 当一个请求进入时,它的主体被原样验证,而不根据模式进行解析。
    • 返回响应时,在序列化为 JSON 之前,根据 schema 验证此结构;

将来,这两个步骤可能会与 Rust 支持的 JSON 反序列化(在请求端)和反序列化(在响应端)结合使用。

  1. 使用基于属性的测试作为假设的扩展

在这种情况下,输入验证越快,生成的测试用例就越多。当前的实现在底层使用 Python,这对于我通常使用的复杂模式来说非常慢。

更新

我尝试在此处Serialize实现trait并添加了与 @Sven Marnach 在评论中建议的原始字符串输入的比较。确实,原始字符串是最快的选择,但如果它涉及在 Python 中调用,它比具有特征的变体要差得多。json.dumps

小对象和模式(100000 次迭代):

大对象和模式(100 次迭代):

基准代码和测试数据

有一个字符串版本肯定是有意义的,但调用json.dumps是相当昂贵的。我不知道这种情况是否有更好的选择。

Python版本:3.7

锈版本:1.42.0

依赖项

  • serde_json = "1.0.48"
  • serde =“1.0.105”
  • jsonschema = "0.2.0"
0 投票
1 回答
244 浏览

python - 如何使基于 PyO3 的库在 Python 版本之间更具可移植性?

我有一个使用 Python 3.5.2 在我的系统上使用 PyO3 创建的库。.so 文件链接到对应的 libpython3.5m 文件:

但是,如果我尝试在具有不同 Python 次要版本(例如,3.6.9 或 3.7.3)的另一个系统上使用我的库,则该库不存在:

因此,我不能使用我的库:

有没有一种方法可以更通用地将我的库链接到 libpython 以适应这些次要版本更改,或者至少允许向后兼容(在较新版本上构建但允许较旧版本的 Python 也使用我的库)?或者我可以在运行时做些什么来让库仍然运行?

0 投票
1 回答
391 浏览

python - 如何使用 PyO3 从 Python 访问 Rust 迭代器?

我对 Rust 很陌生,我的第一个“严肃”项目涉及使用 PyO3 为一个小型 Rust 库编写 Python 包装器。这基本上很轻松,但我正在努力研究如何将 Rust 上的惰性迭代器暴露Vec给 Python 代码。

到目前为止,我一直在收集迭代器产生的值并返回一个列表,这显然不是最好的解决方案。这是一些说明我的问题的代码:

我试图RustIterator用 Python 包装器来包装这个类,但我不能使用 PyO3 的#[pyclass]proc。带有生命周期参数的宏。我调查pyo3::types::PyIterator过,但这看起来像是从 Rust 访问 Python 迭代器的一种方式,而不是相反的方式。

如何RustStruct.v在 Python 中访问惰性迭代器?可以安全地假设Vecalways 派生Copyand中包含的类型Clone,并且需要 Python 端的一些代码的答案是可以的(但不太理想)。

0 投票
2 回答
487 浏览

python - Python 的键盘中断不会中止 Rust 功能(PyO3)

我有一个用 PyO3 用 Rust 编写的 Python 库,它涉及一些昂贵的计算(单个函数调用最多 10 分钟)。从 Python 调用时如何中止执行?

Ctrl+C 好像只在执行结束后才处理,所以本质上是没用的。

最小的可重现示例:

输入后立即输入wait.sleep()Ctrl + C字符^C打印到屏幕上,但仅10秒后我终于得到

KeyboardInterrupt检测到,但直到调用 Rust 函数结束时才被处理。有没有办法绕过它?

当 Python 代码放入文件并从 REPL 外部执行时,行为是相同的。

0 投票
2 回答
1521 浏览

python - 如何从 Python 调用 Rust 异步方法?

我想在 Python 中使用 Rust 异步方法。我正在尝试使用PyO3rust-cpython

例如,对于同步 Rust 函数,我可以使用,

对于异步方法,我该怎么做?例如,我想在 Python 中调用以下方法,

0 投票
1 回答
462 浏览

python-3.x - 无法通过使用 PyO3 创建的 Python 绑定在多个 Rust 库之间使用类型

我正在编写一个带有多个库的 Rust 项目。一些库导出类型由工作区中的其他库使用。除了 Rust crates,我还想向 Python 公开一些库,使用pyo3crate生成 Python 绑定,这就是我遇到麻烦的地方。

问题如下。

假设我们有两个 Rust 库 crate producer, 和consumer。在producer中,我们有一个简单的类型,MyClass它是公开可用的,并且是 Python 模块的一部分。在consumercrate 中,我有一些函数可以接受 type 的对象MyClass,并对它们执行一些操作。这些函数在 Rust 中可用,并且也绑定到第二个 Python 模块中。

MyClass我可以在 Python 和 Rust 中创建对象。我可以正确调用 Rust 代码中的函数(例如,来自另一个应用程序),这些函数接受MyClass. 但是我不能从 Pythonconsumer调用模块中接受 type 对象的函数。换句话说,虽然我可以在 Rust 或 Python 中创建类型的对象并在 Rust crate中使用它们,但我不能将对象从Python 模块传递给Python 模块。这样做会生成一个,尽管对象广告本身具有类型。为什么?MyClassMyClassconsumerproducerconsumerTypeErrorMyClass

编辑:请参阅问题的底部以进行进一步调查。

我制作了一个 MCVE,可以从GitHub获得。Rust 和 Python 代码也包含在下面。

复制:

克隆 repo 后,您可以生成我得到的输出:

你应该看到:

平台详情:

  • macOS 10.14.6
  • 货物 1.44.0 (05d080faa 2020-05-06)
  • rustc 1.44.0 (49cae5576 2020-06-01)
  • Python 3.7.7
  • pyo3 v0.11.1

代码:

这个小的 Python 脚本演示了这个问题。第一个功能是确保构建的 crate 可以通过脚本导入。

更新:

我一直在深入研究这个问题,我开始怀疑这个问题是由 Rust 库的构建方式引起的。我对一般的库很熟悉,但对任何 Rust 细节都不太熟悉。似乎 Rust 将哈希编码到每个损坏的符号名称中。consumer我目前的猜测是,这些哈希值在共享库和. 之间略有不同producer,因此尽管类型具有相同的文本表示,但函数中MyClass预期的实际类型略有不同。consumer

以下是一些具体细节。列出每个 crate 中的符号,然后用rustfilt显示将它们分解:

您可以看到箱子type_obect_raw的符号中还有一个。consumer我不确定如何验证这一点,但我怀疑这是用于将对象转换为在consumercrate 中失败的函数的类型信息。这种类型的对象,虽然名称相同,但在某些方面必须有所不同,因为散列是不同的。

查看pyo3文档,该方法type_object_raw用于返回PyTypeObject表示对象类型的实际值。MyClass在我看来,当从producer模块构造一个实例时,类型对象是从符号返回的,这似乎是合理的type_object_raw::h115c96004643f7df。但是当函数像consumer::print_data尝试转换传递的实例时MyClass,它们使用符号type_object_raw::h0e4c5c91a2345444来获取对象的类型。大概这些是不同的。

所以现在我的问题是,为什么有两个不同的符号来返回实例的类型MyClass

0 投票
0 回答
229 浏览

python - 使用 pyo3 返回文档对象向量时出错

将文档对象的向量从 rust 返回到 python 失败。

我在rust中有一个结构和方法实现,如下所示。

以上失败并显示以下消息