问题标签 [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.
rust - 使用 PyAny 将 Rust 创建的对象从 Python 传递回 Rust
我在 Rust 中有一个 struct + 实现,我返回 Python。这个对象也可以传回Rust 做进一步的工作。(在我的实际代码中,我使用的是 a HashMap<String, MyStruct>
,但即使直接使用 struct 似乎也会导致相同的问题,因此我的示例使用struct Person
简单。)
看来我需要,impl FromPyObject for Person
但 Rust 找不到方法PyAny
downcast
这是将 Rust 对象从 Python 传回 Rust 的正确方法吗?如果是这样,在这里使用的正确方法是PyAny
什么?
python - Rust Pyo3 绑定:如何在通用 rust 类型上重用 python 方法
我有一个比这更复杂的问题。但我认为这打破了它。我有一些通用结构,它有三个构造函数来获得一个具体的类型结构。除了构造函数之外,它们都具有相同的泛型方法。我想要的是这样的:
当我尝试编译这个。pyo3
警告我它不能使用泛型。error: #[pyclass] cannot have generic parameters
.
是否可以创建某种通用基础class
来继承具体类型?
完成;这是我的Cargo.toml
:
python - 如何使用 PyO3 解组 PyCodeObject?
我正在阅读 .pyc 文件,并且需要能够解组代码对象。当我尝试将未编组的内容向下转换PyAny
为 时PyCodeObject
,我收到以下错误消息:
这样做的正确方法是什么?
MCVE
创建测试文件:
- 创建一个 .py 文件
- 在 Python 中导入模块(例如
python(3) -c 'import ...'
) __pycache__
文件夹中应该有一个 .pyc 文件- 将调用中代码中的路径替换为
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
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 方面来看,可能有两个用例:
- 该实例是一个 JSON 编码的字符串:
- 该实例是一个 Python 结构(不是 JSON 编码的字符串):
可能的用例
Web 应用程序请求/响应结构验证。
- 当一个请求进入时,它的主体被原样验证,而不根据模式进行解析。
- 返回响应时,在序列化为 JSON 之前,根据 schema 验证此结构;
将来,这两个步骤可能会与 Rust 支持的 JSON 反序列化(在请求端)和反序列化(在响应端)结合使用。
- 使用基于属性的测试作为假设的扩展
在这种情况下,输入验证越快,生成的测试用例就越多。当前的实现在底层使用 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"
python - 如何使基于 PyO3 的库在 Python 版本之间更具可移植性?
我有一个使用 Python 3.5.2 在我的系统上使用 PyO3 创建的库。.so 文件链接到对应的 libpython3.5m 文件:
但是,如果我尝试在具有不同 Python 次要版本(例如,3.6.9 或 3.7.3)的另一个系统上使用我的库,则该库不存在:
因此,我不能使用我的库:
有没有一种方法可以更通用地将我的库链接到 libpython 以适应这些次要版本更改,或者至少允许向后兼容(在较新版本上构建但允许较旧版本的 Python 也使用我的库)?或者我可以在运行时做些什么来让库仍然运行?
python - 如何使用 PyO3 从 Python 访问 Rust 迭代器?
我对 Rust 很陌生,我的第一个“严肃”项目涉及使用 PyO3 为一个小型 Rust 库编写 Python 包装器。这基本上很轻松,但我正在努力研究如何将 Rust 上的惰性迭代器暴露Vec
给 Python 代码。
到目前为止,我一直在收集迭代器产生的值并返回一个列表,这显然不是最好的解决方案。这是一些说明我的问题的代码:
我试图RustIterator
用 Python 包装器来包装这个类,但我不能使用 PyO3 的#[pyclass]
proc。带有生命周期参数的宏。我调查pyo3::types::PyIterator
过,但这看起来像是从 Rust 访问 Python 迭代器的一种方式,而不是相反的方式。
如何RustStruct.v
在 Python 中访问惰性迭代器?可以安全地假设Vec
always 派生Copy
and中包含的类型Clone
,并且需要 Python 端的一些代码的答案是可以的(但不太理想)。
python - Python 的键盘中断不会中止 Rust 功能(PyO3)
我有一个用 PyO3 用 Rust 编写的 Python 库,它涉及一些昂贵的计算(单个函数调用最多 10 分钟)。从 Python 调用时如何中止执行?
Ctrl+C 好像只在执行结束后才处理,所以本质上是没用的。
最小的可重现示例:
输入后立即输入wait.sleep()
,Ctrl + C
字符^C
打印到屏幕上,但仅10秒后我终于得到
被KeyboardInterrupt
检测到,但直到调用 Rust 函数结束时才被处理。有没有办法绕过它?
当 Python 代码放入文件并从 REPL 外部执行时,行为是相同的。
python - 如何从 Python 调用 Rust 异步方法?
我想在 Python 中使用 Rust 异步方法。我正在尝试使用PyO3或rust-cpython。
例如,对于同步 Rust 函数,我可以使用,
对于异步方法,我该怎么做?例如,我想在 Python 中调用以下方法,
python-3.x - 无法通过使用 PyO3 创建的 Python 绑定在多个 Rust 库之间使用类型
我正在编写一个带有多个库的 Rust 项目。一些库导出类型由工作区中的其他库使用。除了 Rust crates,我还想向 Python 公开一些库,使用pyo3
crate生成 Python 绑定,这就是我遇到麻烦的地方。
问题如下。
假设我们有两个 Rust 库 crate producer
, 和consumer
。在producer
中,我们有一个简单的类型,MyClass
它是公开可用的,并且是 Python 模块的一部分。在consumer
crate 中,我有一些函数可以接受 type 的对象MyClass
,并对它们执行一些操作。这些函数在 Rust 中可用,并且也绑定到第二个 Python 模块中。
MyClass
我可以在 Python 和 Rust 中创建对象。我可以正确调用 Rust 代码中的函数(例如,来自另一个应用程序),这些函数接受MyClass
. 但是我不能从 Pythonconsumer
调用模块中接受 type 对象的函数。换句话说,虽然我可以在 Rust 或 Python 中创建类型的对象并在 Rust crate中使用它们,但我不能将对象从Python 模块传递给Python 模块。这样做会生成一个,尽管对象广告本身具有类型。为什么?MyClass
MyClass
consumer
producer
consumer
TypeError
MyClass
编辑:请参阅问题的底部以进行进一步调查。
我制作了一个 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
我不确定如何验证这一点,但我怀疑这是用于将对象转换为在consumer
crate 中失败的函数的类型信息。这种类型的对象,虽然名称相同,但在某些方面必须有所不同,因为散列是不同的。
查看pyo3
文档,该方法type_object_raw
用于返回PyTypeObject
表示对象类型的实际值。MyClass
在我看来,当从producer
模块构造一个实例时,类型对象是从符号返回的,这似乎是合理的type_object_raw::h115c96004643f7df
。但是当函数像consumer::print_data
尝试转换传递的实例时MyClass
,它们使用符号type_object_raw::h0e4c5c91a2345444
来获取对象的类型。大概这些是不同的。
所以现在我的问题是,为什么有两个不同的符号来返回实例的类型MyClass
?
python - 使用 pyo3 返回文档对象向量时出错
将文档对象的向量从 rust 返回到 python 失败。
我在rust中有一个结构和方法实现,如下所示。
以上失败并显示以下消息