Skip to content

Commit

Permalink
Add Py::into_ref
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Aug 9, 2020
1 parent 77ed6d6 commit 7d0b3b3
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 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 `Py::as_ref` and `Py::into_ref`. [#1098](https://github.com/PyO3/pyo3/pull/1098)

### 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)
Expand All @@ -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 `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 `AsPyRef`. [#1098](https://github.com/PyO3/pyo3/pull/1098)

### Fixed
- Conversion from types with an `__index__` method to Rust BigInts. [#1027](https://github.com/PyO3/pyo3/pull/1027)
Expand Down
5 changes: 3 additions & 2 deletions guide/src/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,10 @@ Can be cloned using Python reference counts with `.clone()`.
# let py = gil.python();
let list: Py<PyList> = PyList::empty(py).into();

// Access the native type using Py::as_ref(py)
// (For #[pyclass] types, as_ref() will return &PyCell<T>)
// Access the native type using Py::as_ref(py) or Py::into_ref(py)
// (For #[pyclass] types, these will return &PyCell<T>)
let _: &PyList = list.as_ref(py);
let _: &PyList = list.clone().into_ref(py);

// Convert to PyObject with .into()
let _: PyObject = list.into();
Expand Down
31 changes: 31 additions & 0 deletions src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,37 @@ where
let any = self.as_ptr() as *const PyAny;
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>
Expand Down

0 comments on commit 7d0b3b3

Please sign in to comment.