Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#[pyo3(from_py_with = "...")] causes compilation error when used in methods with the #[setter] attribute. #3992

Closed
MarquessV opened this issue Mar 25, 2024 · 1 comment · Fixed by #3995
Labels

Comments

@MarquessV
Copy link

Bug Description

Using the from_py_with per-argument option inside a method with the #[setter] attribute causes a compilation error despite working fine in constructors and other methods without the setter attribute. The following code reproduces the issue with the error:

the trait bound `Field: pyo3::PyClass` is not satisfied
     the trait `pyo3::PyClass` is implemented for `Foo`
     required for `Field` to implement `pyo3::FromPyObject<'_>` [E0277]
use pyo3::prelude::*;

#[derive(Clone)]
struct Field(pub i32);

fn from_py_to_field(value: &PyAny) -> PyResult<Field> {
    let value = value.extract()?;
    Ok(Field(value))
}

#[pyclass]
struct Foo {
    field: Field,
}

#[pymethods]
impl Foo {
    // These compile successfully.
    #[new]
    fn new(#[pyo3(from_py_with = "from_py_to_field")] field: Field) -> Self {
        Self { field }
    }

    fn set_field_fn(&mut self, #[pyo3(from_py_with = "from_py_to_field")] field: Field) {
        self.field = field;
    }

    // This does not compile: "the trait bound `Field: pyo3::PyClass` is not satisfied"
    #[setter]
    fn field(&mut self, #[pyo3(from_py_with = "from_py_to_field")] field: Field) {
        self.field = field
    }
}

I've tested this in 0.20.3 and 0.21.0-beta.0 with the new Bound smart pointer.

Steps to Reproduce

  1. Annotate the argument of a #[setter] method with #[pyo3(from_py_with="..")] for some argument that doesn't implement PyClass (or run the example from the issue).
  2. Compile

Backtrace

No response

Your operating system and version

MacOS Sonoma (M1 Max)

Your Python version (python --version)

N/A

Your Rust version (rustc --version)

rustc 1.76.0 (07dca489a 2024-02-04)

Your PyO3 version

0.20.3 and 0.21-beta.0

How did you install python? Did you use a virtualenv?

I install python with pyenv, but this issue does not require a Python installation or virtual environment to reproduce.

Additional Info

No response

@Icxolu
Copy link
Contributor

Icxolu commented Mar 26, 2024

It seems like the #[pyo3(from_py_with = "...")] attribute was not handled for #[setter] methods at all, so pyo3 tried to extract Field here using FromPyObject. Since Field does not implement FromPyObject that failed.

I don't see a reason why #[pyo3(from_py_with = "...")] should not be supported here, so I implemented a fix in #3995

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants