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

cannot find value py in this scope when deriving FromPyObject on struct #2397

Closed
lesurp opened this issue May 24, 2022 · 3 comments · Fixed by #2414
Closed

cannot find value py in this scope when deriving FromPyObject on struct #2397

lesurp opened this issue May 24, 2022 · 3 comments · Fixed by #2414
Labels

Comments

@lesurp
Copy link

lesurp commented May 24, 2022

Bug Description

There seems to be a missing let py = _pyo3::PyNativeType::py(obj); in the generated code when trying to use from_py_with (note that the problem does not appear when using an item, which explains why the tests pass despite this bug). See cargo expand output.

Steps to Reproduce

fn pouf(py: &PyAny) -> PyResult<usize> {
    Ok(1)
}

// NOT OK
#[derive(Debug, FromPyObject)]
pub(crate) struct Zap {
    #[pyo3(from_py_with = "pouf")]
    pub foo: usize,
}

// OK
#[derive(Debug, FromPyObject)]
pub(crate) struct Zap2 {
    pub foo: usize,
}

Generated code:

impl<'source> _pyo3::FromPyObject<'source> for Zap2 {
            fn extract(obj: &'source _pyo3::PyAny) -> _pyo3::PyResult<Self> {
                ::std::result::Result::Ok(Zap2 {
                    foo: {
                        let py = _pyo3::PyNativeType::py(obj); /////////// This is missing in the Zap implementation!
                        obj.getattr({
                            fn isolate_from_dyn_env(
                                py: ::pyo3::Python<'_>,
                            ) -> &::pyo3::types::PyString {
                                static INTERNED: ::pyo3::once_cell::GILOnceCell<
                                    ::pyo3::Py<::pyo3::types::PyString>,
                                > = ::pyo3::once_cell::GILOnceCell::new();
                                INTERNED
                                    .get_or_init(py, || {
                                        ::pyo3::conversion::IntoPy::into_py(
                                            ::pyo3::types::PyString::intern(py, "foo"),
                                            py,
                                        )
                                    })
                                    .as_ref(py)
                            }
                            isolate_from_dyn_env(py)
                        })?
                        .extract()
                        .map_err(|inner| {
                            let new_err = _pyo3::exceptions::PyTypeError::new_err(
                                "failed to extract field Zap2.foo",
                            );
                            new_err.set_cause(py, ::std::option::Option::Some(inner));
                            new_err
                        })?
                    },
                })
            }
        }

impl<'source> _pyo3::FromPyObject<'source> for Zap {
            fn extract(obj: &'source _pyo3::PyAny) -> _pyo3::PyResult<Self> {
                ::std::result::Result::Ok(Zap {
                    foo: pouf(obj.getattr({
                        fn isolate_from_dyn_env(
                            py: ::pyo3::Python<'_>,
                        ) -> &::pyo3::types::PyString {
                            static INTERNED: ::pyo3::once_cell::GILOnceCell<
                                ::pyo3::Py<::pyo3::types::PyString>,
                            > = ::pyo3::once_cell::GILOnceCell::new();
                            INTERNED
                                .get_or_init(py, || {
                                    ::pyo3::conversion::IntoPy::into_py(
                                        ::pyo3::types::PyString::intern(py, "paf"),
                                        py,
                                    )
                                })
                                .as_ref(py)
                        }
                        isolate_from_dyn_env(py)
                    })?)
                    .map_err(|inner| {
                        let py = _pyo3::PyNativeType::py(obj);
                        let new_err = _pyo3::exceptions::PyTypeError::new_err(
                            "failed to extract field Zap.foo",
                        );
                        new_err.set_cause(py, ::std::option::Option::Some(inner));
                        new_err
                    })?,
                })
            }

Backtrace

error[E0425]: cannot find value `py` in this scope
  --> src\pyo3_types.rs:17:17
   |
17 | #[derive(Debug, FromPyObject)]
   |                 ^^^^^^^^^^^^ not found in this scope
   |
   = note: this error originates in the derive macro `FromPyObject` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0425`.


### Your operating system and version

Windows 10

### Your Python version (`python --version`)

Python 3.10.0

### Your Rust version (`rustc --version`)

rustc 1.63.0-nightly (ee160f2f5 2022-05-23)

### Your PyO3 version

0.16.3

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

anaconda

### Additional Info

_No response_
@davidhewitt
Copy link
Member

Thanks for reporting! I've pushed some clean ups to the macro in #2414 which will fix this case.

@relsunkaev
Copy link

Is there a workaround for this in the meantime?

@davidhewitt
Copy link
Member

You can use git dependency of PyO3, alternatively I expect to push a release very soon, just need to tidy up some rough edges.

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.

3 participants