Merge pull request #966 from davidhewitt/pyclass-send
Require Send for #[pyclass] (no compilefail test)
This commit is contained in:
commit
7a7271319c
|
@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
- Simplify internals of `#[pyo3(get)]` attribute. (Remove the hidden API `GetPropertyValue`.) [#934](https://github.com/PyO3/pyo3/pull/934)
|
||||
- Call `Py_Finalize` at exit to flush buffers, etc. [#943](https://github.com/PyO3/pyo3/pull/943)
|
||||
- Add type parameter to PyBuffer. #[951](https://github.com/PyO3/pyo3/pull/951)
|
||||
- Require `Send` bound for `#[pyclass]`. [#966](https://github.com/PyO3/pyo3/pull/966)
|
||||
|
||||
### Removed
|
||||
- Remove `ManagedPyRef` (unused, and needs specialization) [#930](https://github.com/PyO3/pyo3/pull/930)
|
||||
|
|
|
@ -14,10 +14,9 @@ struct MyClass {
|
|||
}
|
||||
```
|
||||
|
||||
The above example generates implementations for [`PyTypeInfo`], [`PyTypeObject`],
|
||||
and [`PyClass`] for `MyClass`.
|
||||
Because Python objects are freely shared between threads by the Python interpreter, all structs annotated with `#[pyclass]` must implement `Send`.
|
||||
|
||||
If you curious what `#[pyclass]` generates, see [How methods are implemented](#how-methods-are-implemented) section.
|
||||
The above example generates implementations for [`PyTypeInfo`], [`PyTypeObject`], and [`PyClass`] for `MyClass`. To see these generated implementations, refer to the section [How methods are implemented](#how-methods-are-implemented) at the end of this chapter.
|
||||
|
||||
## Adding the class to a module
|
||||
|
||||
|
|
|
@ -72,7 +72,9 @@ pub unsafe fn tp_free_fallback(obj: *mut ffi::PyObject) {
|
|||
///
|
||||
/// The `#[pyclass]` attribute automatically implements this trait for your Rust struct,
|
||||
/// so you don't have to use this trait directly.
|
||||
pub trait PyClass: PyTypeInfo<Layout = PyCell<Self>> + Sized + PyClassAlloc + PyMethods {
|
||||
pub trait PyClass:
|
||||
PyTypeInfo<Layout = PyCell<Self>> + Sized + PyClassAlloc + PyMethods + Send
|
||||
{
|
||||
/// Specify this class has `#[pyclass(dict)]` or not.
|
||||
type Dict: PyClassDict;
|
||||
/// Specify this class has `#[pyclass(weakref)]` or not.
|
||||
|
|
|
@ -4,7 +4,6 @@ use pyo3::class::PyVisit;
|
|||
use pyo3::prelude::*;
|
||||
use pyo3::type_object::PyTypeObject;
|
||||
use pyo3::{py_run, AsPyPointer, PyCell, PyTryInto};
|
||||
use std::cell::RefCell;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -84,19 +83,19 @@ fn data_is_dropped() {
|
|||
#[allow(dead_code)]
|
||||
#[pyclass]
|
||||
struct GCIntegration {
|
||||
self_ref: RefCell<PyObject>,
|
||||
self_ref: PyObject,
|
||||
dropped: TestDropCall,
|
||||
}
|
||||
|
||||
#[pyproto]
|
||||
impl PyGCProtocol for GCIntegration {
|
||||
fn __traverse__(&self, visit: PyVisit) -> Result<(), PyTraverseError> {
|
||||
visit.call(&*self.self_ref.borrow())
|
||||
visit.call(&self.self_ref)
|
||||
}
|
||||
|
||||
fn __clear__(&mut self) {
|
||||
let gil = GILGuard::acquire();
|
||||
*self.self_ref.borrow_mut() = gil.python().None();
|
||||
self.self_ref = gil.python().None();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +109,7 @@ fn gc_integration() {
|
|||
let inst = PyCell::new(
|
||||
py,
|
||||
GCIntegration {
|
||||
self_ref: RefCell::new(py.None()),
|
||||
self_ref: py.None(),
|
||||
dropped: TestDropCall {
|
||||
drop_called: Arc::clone(&drop_called),
|
||||
},
|
||||
|
@ -119,7 +118,7 @@ fn gc_integration() {
|
|||
.unwrap();
|
||||
|
||||
let mut borrow = inst.borrow_mut();
|
||||
*borrow.self_ref.borrow_mut() = inst.to_object(py);
|
||||
borrow.self_ref = inst.to_object(py);
|
||||
}
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
|
|
|
@ -1,17 +1,9 @@
|
|||
use pyo3::prelude::*;
|
||||
use pyo3::types::PyList;
|
||||
|
||||
#[pyclass]
|
||||
struct MyClass {
|
||||
list: &'static PyList,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl MyClass {
|
||||
#[new]
|
||||
fn new(list: &'static PyList) -> Self {
|
||||
Self { list }
|
||||
}
|
||||
#[pyfunction]
|
||||
fn static_ref(list: &'static PyList) -> usize {
|
||||
list.len()
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0597]: `pool` does not live long enough
|
||||
--> $DIR/static_ref.rs:9:1
|
||||
--> $DIR/static_ref.rs:4:1
|
||||
|
|
||||
9 | #[pymethods]
|
||||
| ^^^^^^^^^^^^
|
||||
4 | #[pyfunction]
|
||||
| ^^^^^^^^^^^^^
|
||||
| |
|
||||
| borrowed value does not live long enough
|
||||
| `pool` dropped here while still borrowed
|
||||
|
|
Loading…
Reference in New Issue