Add Py::into_ref

This commit is contained in:
David Hewitt 2020-08-09 22:56:30 +01:00
parent 77ed6d6d69
commit 7d0b3b386a
3 changed files with 36 additions and 2 deletions

View File

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Implement `Debug` for `PyIterator`. [#1051](https://github.com/PyO3/pyo3/pull/1051) - Implement `Debug` for `PyIterator`. [#1051](https://github.com/PyO3/pyo3/pull/1051)
- Implement type information for conversion failures. [#1050](https://github.com/PyO3/pyo3/pull/1050) - Implement type information for conversion failures. [#1050](https://github.com/PyO3/pyo3/pull/1050)
- Add `PyBytes::new_with` and `PyByteArray::new_with` for initialising Python-allocated bytes and bytearrays using a closure. [#1074](https://github.com/PyO3/pyo3/pull/1074) - Add `PyBytes::new_with` and `PyByteArray::new_with` for initialising Python-allocated bytes and bytearrays using a closure. [#1074](https://github.com/PyO3/pyo3/pull/1074)
- Add `Py::as_ref` and `Py::into_ref`. [#1098](https://github.com/PyO3/pyo3/pull/1098)
### Changed ### Changed
- Exception types have been renamed from e.g. `RuntimeError` to `PyRuntimeError`, and are now only accessible by `&T` or `Py<T>` similar to other Python-native types. The old names continue to exist but are deprecated. [#1024](https://github.com/PyO3/pyo3/pull/1024) - Exception types have been renamed from e.g. `RuntimeError` to `PyRuntimeError`, and are now only accessible by `&T` or `Py<T>` similar to other Python-native types. The old names continue to exist but are deprecated. [#1024](https://github.com/PyO3/pyo3/pull/1024)
@ -31,6 +32,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Remove `Python::register_any`. [#1023](https://github.com/PyO3/pyo3/pull/1023) - Remove `Python::register_any`. [#1023](https://github.com/PyO3/pyo3/pull/1023)
- Remove `GILGuard::acquire` from the public API. Use `Python::acquire_gil` or `Python::with_gil`. [#1036](https://github.com/PyO3/pyo3/pull/1036) - Remove `GILGuard::acquire` from the public API. Use `Python::acquire_gil` or `Python::with_gil`. [#1036](https://github.com/PyO3/pyo3/pull/1036)
- Remove `FromPy`. [#1063](https://github.com/PyO3/pyo3/pull/1063) - Remove `FromPy`. [#1063](https://github.com/PyO3/pyo3/pull/1063)
- Remove `AsPyRef`. [#1098](https://github.com/PyO3/pyo3/pull/1098)
### Fixed ### Fixed
- Conversion from types with an `__index__` method to Rust BigInts. [#1027](https://github.com/PyO3/pyo3/pull/1027) - Conversion from types with an `__index__` method to Rust BigInts. [#1027](https://github.com/PyO3/pyo3/pull/1027)

View File

@ -140,9 +140,10 @@ Can be cloned using Python reference counts with `.clone()`.
# let py = gil.python(); # let py = gil.python();
let list: Py<PyList> = PyList::empty(py).into(); let list: Py<PyList> = PyList::empty(py).into();
// Access the native type using Py::as_ref(py) // Access the native type using Py::as_ref(py) or Py::into_ref(py)
// (For #[pyclass] types, as_ref() will return &PyCell<T>) // (For #[pyclass] types, these will return &PyCell<T>)
let _: &PyList = list.as_ref(py); let _: &PyList = list.as_ref(py);
let _: &PyList = list.clone().into_ref(py);
// Convert to PyObject with .into() // Convert to PyObject with .into()
let _: PyObject = list.into(); let _: PyObject = list.into();

View File

@ -111,6 +111,37 @@ where
let any = self.as_ptr() as *const PyAny; let any = self.as_ptr() as *const PyAny;
unsafe { PyNativeType::unchecked_downcast(&*any) } unsafe { PyNativeType::unchecked_downcast(&*any) }
} }
/// Similar to [`as_ref`](#method.as_ref), but instead consumes this `Py` and registers the
/// Python object reference in PyO3's object storage. The reference count for the Python
/// object will not be decreased until the GIL lifetime ends.
///
/// # Examples
/// Create `&PyList` from `Py<PyList>`:
/// ```
/// # use pyo3::prelude::*;
/// # use pyo3::types::PyList;
/// # Python::with_gil(|py| {
/// let list: Py<PyList> = PyList::empty(py).into();
/// let list: &PyList = list.into_ref(py);
/// assert_eq!(list.len(), 0);
/// # });
/// ```
///
/// Create `&PyCell<MyClass>` from `Py<MyClass>`:
/// ```
/// # use pyo3::prelude::*;
/// #[pyclass]
/// struct MyClass { }
/// # Python::with_gil(|py| {
/// let my_class: Py<MyClass> = Py::new(py, MyClass { }).unwrap();
/// let my_class_cell: &PyCell<MyClass> = my_class.into_ref(py);
/// assert!(my_class_cell.try_borrow().is_ok());
/// # });
/// ```
pub fn into_ref(self, py: Python) -> &T::AsRefTarget {
unsafe { py.from_owned_ptr(self.into_ptr()) }
}
} }
impl<T> Py<T> impl<T> Py<T>