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

#[pymethods] generated code triggers unsafe_op_in_unsafe_fn lint #4663

Closed
nsunderland1 opened this issue Oct 28, 2024 · 0 comments · Fixed by #4674
Closed

#[pymethods] generated code triggers unsafe_op_in_unsafe_fn lint #4663

nsunderland1 opened this issue Oct 28, 2024 · 0 comments · Fixed by #4674
Labels

Comments

@nsunderland1
Copy link

Bug Description

Functions in impl blocks annotated with pymethods trigger the unsafe_op_in_unsafe_fn lint. In a crate with #![deny(unsafe_op_in_unsafe_fn)] set, I get the following error:

error[E0133]: call to unsafe function `pyo3::impl_::pymethods::BoundRef::<'a, 'py, pyo3::PyAny>::ref_from_ptr` is unsafe and requires unsafe block
  --> src/lib.rs:10:19
   |
10 |     fn do_nothing(&self) {}
   |                   ^ call to unsafe function
   |
   = note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
   = note: consult the function's documentation for information on how to avoid undefined behavior
note: an unsafe function restricts its caller, but its body is safe by default
  --> src/lib.rs:8:1
   |
8  | #[pymethods]
   | ^^^^^^^^^^^^
note: the lint level is defined here
  --> src/lib.rs:1:9
   |
1  | #![deny(unsafe_op_in_unsafe_fn)]
   |         ^^^^^^^^^^^^^^^^^^^^^^
   = note: this error originates in the attribute macro `pymethods` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0133`.
error: could not compile `repro_pyo3` (lib) due to 1 previous error

This points to a call to ref_from_ptr, which we can see in the expanded code:

#[doc(hidden)]
#[allow(non_snake_case)]
impl Foo {
    unsafe fn __pymethod_do_nothing__<'py>(
        py: ::pyo3::Python<'py>,
        _slf: *mut ::pyo3::ffi::PyObject,
    ) -> ::pyo3::PyResult<*mut ::pyo3::ffi::PyObject> {
        let _slf_ref = &_slf;
        let function = Foo::do_nothing;
        #[allow(clippy::let_unit_value)]
        let mut holder_0 = ::pyo3::impl_::extract_argument::FunctionArgumentHolder::INIT;
        let gil_refs_checker_0 = ::pyo3::impl_::deprecations::GilRefs::new();
        let result = {
            let ret = function(::pyo3::impl_::deprecations::inspect_type(
                ::pyo3::impl_::extract_argument::extract_pyclass_ref::<Foo>(
                    // vvv right here
                    ::pyo3::impl_::pymethods::BoundRef::ref_from_ptr(py, &_slf).0, // <<< right here
                    // ^^^ right here
                    &mut holder_0,
                )?,
                &gil_refs_checker_0,
            ));
            ::pyo3::impl_::wrap::map_result_into_ptr(
                py,
                ::pyo3::impl_::wrap::OkWrap::wrap(ret)
                    .map_err(::core::convert::Into::<::pyo3::PyErr>::into),
            )
        };
        gil_refs_checker_0.function_arg();
        result
    }
}

Steps to Reproduce

Quick method:

  1. Clone this repo: https://github.com/nsunderland1/repro_pyo3/tree/main
  2. Run cargo build

Alternatively:

  1. Create a PyO3 project following the steps in https://github.com/PyO3/pyo3?tab=readme-ov-file#using-rust-from-python
  2. Replace the contents of lib.rs with the following code:
#![deny(unsafe_op_in_unsafe_fn)]

use pyo3::prelude::*;

#[pyclass]
struct Foo;

#[pymethods]
impl Foo {
    fn do_nothing(&self) {}
}
  1. Run cargo build

Backtrace

No response

Your operating system and version

macOS Sonoma

Your Python version (python --version)

Python 3.10.14

Your Rust version (rustc --version)

rustc 1.80.0 (051478957 2024-07-21)

Your PyO3 version

0.22.0

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

pyenv, using a virtual env as in the steps laid out here https://github.com/PyO3/pyo3?tab=readme-ov-file#using-rust-from-python

Additional Info

No response

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