Skip to content

Instantly share code, notes, and snippets.

@mejrs
Last active April 11, 2022 18:31
Show Gist options
  • Save mejrs/4199fefcf72e56567ecdd3c89b407ae2 to your computer and use it in GitHub Desktop.
Save mejrs/4199fefcf72e56567ecdd3c89b407ae2 to your computer and use it in GitHub Desktop.

This is a collection of of pyo3 errors I'd like to improve.

Trying to misuse Python::allow_threads.

Code:

use pyo3::prelude::*;
use pyo3::types::PyString;

fn parallel_print(py: Python<'_>) {
    let s = PyString::new(py, "This object cannot be accessed without holding the GIL >_<");
    py.allow_threads(move || {
        println!("{:?}", s); // This causes a compile error.
    });
}

Error:

error[E0277]: `UnsafeCell<PyObject>` cannot be shared between threads safely
   --> src\lib.rs:6:8
    |
6   |     py.allow_threads(move || {
    |        ^^^^^^^^^^^^^ `UnsafeCell<PyObject>` cannot be shared between threads safely
    |
    = help: within `PyString`, the trait `Sync` is not implemented for `UnsafeCell<PyObject>`
    = note: required because it appears within the type `PyAny`
    = note: required because it appears within the type `PyString`
    = note: required because of the requirements on the impl of `Send` for `&PyString`
    = note: required because it appears within the type `[closure@src\lib.rs:6:22: 8:6]`
    = note: required because of the requirements on the impl of `Ungil` for `[closure@src\lib.rs:6:22: 8:6]`
note: required by a bound in `pyo3::Python::<'py>::allow_threads`
   --> C:\Users\bruno\rust\pyo3\src\marker.rs:450:12
    |
450 |         F: Ungil + FnOnce() -> T,
    |            ^^^^^ required by this bound in `pyo3::Python::<'py>::allow_threads`

For more information about this error, try `rustc --explain E0277`.

Improved error:

error[E0277]: the trait bound `PyString: Ungil` is not satisfied in `[closure@src\lib.rs:6:22: 8:6]`
   --> src\lib.rs:6:8
    |
8   |         println!("{:?}", s); // This causes a compile error.
    |                          ^ note: A `PyString` is accessed here...
...
    |
6   |       py.allow_threads(move || {
    |          ^^^^^^^^^^^^^---...but the GIL was released here

    = note: Python objects are not threadsafe and cannot be used while other Python threads are running.
    = note: see <link to guide> for more details.
For more information about this error, try `rustc --explain E0277`.

Missing a tuple argument in e.g. PyAny::call_method1.

use pyo3::prelude::*;
use pyo3::types::*;
use std::collections::HashMap;

fn foo(py: python<'_>) {
    let list = PyList::empty(py);
    let map = HashMap::from([("hello", "world")]);
    list.call_method1("append", map).unwrap();
}

Error:

error[E0277]: the trait bound `HashMap<&str, &str>: IntoPy<Py<PyTuple>>` is not satisfied
   --> src\lib.rs:8:33
    |
8   |     list.call_method1("append", map).unwrap();
    |          ------------           ^^^ the trait `IntoPy<Py<PyTuple>>` is not implemented for `HashMap<&str, &str>`
    |          |
    |          required by a bound introduced by this call
    |
    = help: the trait `IntoPy<Py<PyAny>>` is implemented for `HashMap<K, V, H>`
note: required by a bound in `PyAny::call_method1`
   --> C:\Users\bruno\rust\pyo3\src\types\any.rs:610:55
    |
610 |     pub fn call_method1(&self, name: &str, args: impl IntoPy<Py<PyTuple>>) -> PyResult<&PyAny> {
    |  
                                                     ^^^^^^^^^^^^^^^^^^^ required by this bound in `PyAny::call_method1`													

Improved error:

error[E0277]: the trait bound `HashMap<&str, &str>: IntoPy<Py<PyTuple>>` is not satisfied
   --> src\lib.rs:8:33
    |
8   |     list.call_method1("append", map).unwrap();
    |          ------------           ^^^ the trait `IntoPy<Py<PyTuple>>` is not implemented for `HashMap<&str, &str>`
    |          |
    |          required by a bound introduced by this call
    |
help: use `(...,)` instead of `(...)` to specify a single-field tuple.
    |
8   |     list.call_method1("append", (map,)).unwrap();
    |                                 +	  ++						 

Using the wrong receiver

use pyo3::prelude::*;

#[pyclass]
struct MyClass {}

#[pymethods]
impl MyClass {
    fn method_with_invalid_self_type(slf: i32, py: Python<'_>, index: u32) {}
}

Error:

error[E0277]: the trait bound `i32: From<&PyCell<MyClass>>` is not satisfied
 --> src\lib.rs:8:43
  |
8 |     fn method_with_invalid_self_type(slf: i32, py: Python<'_>, index: u32) {}
  |                                           ^^^ the trait `From<&PyCell<MyClass>>` is not implemented for `i32`
  |
  = help: the following other types implement trait `From<T>`:
            <f32 as From<i16>>
            <f32 as From<i8>>
            <f32 as From<u16>>
            <f32 as From<u8>>
            <f64 as From<f32>>
            <f64 as From<i16>>
            <f64 as From<i32>>
            <f64 as From<i8>>
          and 67 others
  = note: required because of the requirements on the impl of `Into<i32>` for `&PyCell<MyClass>`
  = note: required because of the requirements on the impl of `TryFrom<&PyCell<MyClass>>` for `i32`

For more information about this error, try `rustc --explain E0277`.

Improved error:

error[E0277]: the trait bound `i32: From<&PyCell<MyClass>>` is not satisfied
 --> src\lib.rs:8:43
  |
8 |     fn method_with_invalid_self_type(slf: i32, py: Python<'_>, index: u32) {}
  |                                           ^^^ the trait `From<&PyCell<MyClass>>` is not implemented for `i32`
  |
  = help: use one of the valid receiver types: `&self`, `&mut self, `slf: PyRef<'_, Self>` or `slf: PyRefMut<'_, Self>`.
  |
8 |     fn method_with_invalid_self_type(&self, py: Python<'_>, index: u32) {}
  |                                      +++++
  |
  = help: declare `method_with_invalid_self_type` as a static method
  |
  |     #[staticmethod]
  |     ++++++++++++++
8 |     fn method_with_invalid_self_type(slf: i32, py: Python<'_>, index: u32) {}
  |     
For more information about this error, try `rustc --explain E0277`.
@davidhewitt
Copy link

Strange! Thanks for creating the upstream issue 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment