【问题标题】:Pyo3: The trait `PyClass` is not implemented for `&Py<PyAny>`Pyo3:没有为 `&Py<PyAny>` 实现特征 `PyClass`
【发布时间】:2021-05-18 23:07:21
【问题描述】:

我正在学习 rust 并尝试使用 pyo3maturin 制作一个非常简单的 python 模块。不过,我在 rust 代码上遇到了问题,

Cargo.toml

[package]
name = "lenrs"
version = "0.1.0"
authors = ["matheusfillipe"]
edition = "2018"

[dependencies.pyo3]
version = "0.13.2"
features = ["extension-module"]

[lib]
crate-type = ["cdylib"]
name = "lenrs"

src/lib.rs

extern crate pyo3;

use pyo3::exceptions::PyTypeError;
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;

#[pyfunction]
fn length(py: Python, obj: &PyObject) -> PyResult<PyObject> {
    if let Ok(s) = obj.extract::<String>(py) {
        return Ok(s.len().to_object(py));
    }
    if let Ok(s) = obj.extract::<Vec<String>>(py) {
        return Ok(s.len().to_object(py));
    }
    Err(PyTypeError::new_err("Not Supported"))
}

#[pymodule]
fn lenrs(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_wrapped(wrap_pyfunction!(length))?;
    Ok(())
}

lenrs/init.py

from .lenrs import *

构建输出

$ cargo build                 
   Compiling lenrs v0.1.0 (/home/matheus/projects/learn-rust/lenrs)
error[E0277]: the trait bound `&Py<PyAny>: PyClass` is not satisfied
 --> src/lib.rs:7:1
  |
7 | #[pyfunction]
  | ^^^^^^^^^^^^^ the trait `PyClass` is not implemented for `&Py<PyAny>`
  |
  = note: required because of the requirements on the impl of `pyo3::FromPyObject<'_>` for `&Py<PyAny>`
  = note: required because of the requirements on the impl of `ExtractExt<'_>` for `&Py<PyAny>`
  = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `lenrs`

To learn more, run the command again with --verbose.

我发现问题出在#[pyfunction] 上。当我有一个仅适用于字符串的更简单版本并且length 函数将返回PyResult&lt;()&gt; 时,一切都运行良好,而我最终只会返回Ok(()),但现在我不确定该怎么做如果不支持该类型,此函数将引发 python 错误。

【问题讨论】:

    标签: python rust rust-cargo pyo3


    【解决方案1】:

    我刚刚发现 obj 不应该是引用,将函数签名更改为:fn length(py: Python, obj: PyObject) -&gt; PyResult&lt;PyObject&gt; 使其工作:

    extern crate pyo3;
    
    use pyo3::exceptions::PyTypeError;
    use pyo3::prelude::*;
    use pyo3::wrap_pyfunction;
    
    #[pyfunction]
    fn length(py: Python, obj: PyObject) -> PyResult<PyObject> {
        if let Ok(s) = obj.extract::<String>(py) {
            return Ok(s.len().to_object(py));
        }
        if let Ok(s) = obj.extract::<Vec<String>>(py) {
            return Ok(s.len().to_object(py));
        }
        Err(PyTypeError::new_err("Not Supported"))
    }
    
    #[pymodule]
    fn lenrs(py: Python, m: &PyModule) -> PyResult<()> {
        m.add_wrapped(wrap_pyfunction!(length))?;
        Ok(())
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-18
      • 2023-03-29
      • 2019-12-08
      • 2022-01-26
      • 2015-11-11
      • 2020-03-24
      相关资源
      最近更新 更多