Show More
@@ -16,6 +16,7 use cpython::ObjectProtocol; | |||||
16 | use cpython::PythonObject; |
|
16 | use cpython::PythonObject; | |
17 | use lazy_static::lazy_static; |
|
17 | use lazy_static::lazy_static; | |
18 |
|
18 | |||
|
19 | use hg::revlog::index::Index as CoreIndex; | |||
19 | use rusthg::revlog::{InnerRevlog, PySharedIndex}; |
|
20 | use rusthg::revlog::{InnerRevlog, PySharedIndex}; | |
20 |
|
21 | |||
21 | /// Force cpython's GIL handle with the appropriate lifetime |
|
22 | /// Force cpython's GIL handle with the appropriate lifetime | |
@@ -165,9 +166,21 pub fn py_rust_index_to_graph( | |||||
165 | Ok(unsafe { leaked.map(py, |idx| PySharedIndex { inner: &idx.index }) }) |
|
166 | Ok(unsafe { leaked.map(py, |idx| PySharedIndex { inner: &idx.index }) }) | |
166 | } |
|
167 | } | |
167 |
|
168 | |||
168 | pub(crate) fn proxy_index_extract<'py>( |
|
169 | /// Full extraction of the proxy index object as received in PyO3 to a | |
|
170 | /// [`CoreIndex`] reference. | |||
|
171 | /// | |||
|
172 | /// The safety invariants to maintain are those of the underlying | |||
|
173 | /// [`UnsafePyLeaked::try_borrow`]: the caller must not leak the inner | |||
|
174 | /// reference. | |||
|
175 | pub(crate) unsafe fn proxy_index_extract<'py>( | |||
169 | index_proxy: &Bound<'py, PyAny>, |
|
176 | index_proxy: &Bound<'py, PyAny>, | |
170 | ) -> PyResult<(cpython::Python<'py>, cpython::UnsafePyLeaked<PySharedIndex>)> { |
|
177 | ) -> PyResult<&'py CoreIndex> { | |
171 | let (py, idx_proxy) = to_cpython_py_object(index_proxy); |
|
178 | let (py, idx_proxy) = to_cpython_py_object(index_proxy); | |
172 |
|
|
179 | let py_leaked = py_rust_index_to_graph(py, idx_proxy)?; | |
|
180 | let py_shared = &*unsafe { | |||
|
181 | py_leaked | |||
|
182 | .try_borrow(py) | |||
|
183 | .map_err(|e| from_cpython_pyerr(py, e))? | |||
|
184 | }; | |||
|
185 | Ok(py_shared.inner) | |||
173 | } |
|
186 | } |
@@ -15,7 +15,7 use std::collections::HashSet; | |||||
15 |
|
15 | |||
16 | use hg::{dagops, Revision}; |
|
16 | use hg::{dagops, Revision}; | |
17 |
|
17 | |||
18 |
use crate::convert_cpython:: |
|
18 | use crate::convert_cpython::proxy_index_extract; | |
19 | use crate::exceptions::GraphError; |
|
19 | use crate::exceptions::GraphError; | |
20 | use crate::revision::{rev_pyiter_collect, PyRevision}; |
|
20 | use crate::revision::{rev_pyiter_collect, PyRevision}; | |
21 | use crate::util::new_submodule; |
|
21 | use crate::util::new_submodule; | |
@@ -29,14 +29,8 pub fn headrevs( | |||||
29 | index_proxy: &Bound<'_, PyAny>, |
|
29 | index_proxy: &Bound<'_, PyAny>, | |
30 | revs: &Bound<'_, PyAny>, |
|
30 | revs: &Bound<'_, PyAny>, | |
31 | ) -> PyResult<HashSet<PyRevision>> { |
|
31 | ) -> PyResult<HashSet<PyRevision>> { | |
32 | let (py, py_leaked) = proxy_index_extract(index_proxy)?; |
|
|||
33 | // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked` |
|
32 | // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked` | |
34 | let index = &*unsafe { |
|
33 | let index = unsafe { proxy_index_extract(index_proxy)? }; | |
35 | py_leaked |
|
|||
36 | .try_borrow(py) |
|
|||
37 | .map_err(|e| from_cpython_pyerr(py, e))? |
|
|||
38 | }; |
|
|||
39 |
|
||||
40 | let mut as_set: HashSet<Revision> = rev_pyiter_collect(revs, index)?; |
|
34 | let mut as_set: HashSet<Revision> = rev_pyiter_collect(revs, index)?; | |
41 | dagops::retain_heads(index, &mut as_set).map_err(GraphError::from_hg)?; |
|
35 | dagops::retain_heads(index, &mut as_set).map_err(GraphError::from_hg)?; | |
42 | Ok(as_set.into_iter().map(Into::into).collect()) |
|
36 | Ok(as_set.into_iter().map(Into::into).collect()) |
General Comments 0
You need to be logged in to leave comments.
Login now