##// END OF EJS Templates
rust-dirstate: actually remember the identity...
rust-dirstate: actually remember the identity This was an oversight that likely had no influence on anything since we have only been writing the dirstate for status. We will start writing the dirstate for more operations now, so we'll need this fixed.

File last commit:

r52598:3876d4c6 default
r52926:88aa21d6 default
Show More
ancestors.rs
414 lines | 15.3 KiB | application/rls-services+xml | RustLexer
Georges Racinet
rust-cpython: start cpython crate bindings...
r41001 // ancestors.rs
//
// Copyright 2018 Georges Racinet <gracinet@anybox.fr>
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
Georges Racinet
rust-cpython: rustdoc improvements...
r41220 //! Bindings for the `hg::ancestors` module provided by the
Georges Racinet
rust-cpython: start cpython crate bindings...
r41001 //! `hg-core` crate. From Python, this will be seen as `rustext.ancestor`
Georges Racinet
rust-cpython: rustdoc improvements...
r41220 //! and can be used as replacement for the the pure `ancestor` Python module.
//!
//! # Classes visible from Python:
//! - [`LazyAncestors`] is the Rust implementation of
Georges Racinet
rust-cpython: set conversion for MissingAncestors.bases()...
r41279 //! `mercurial.ancestor.lazyancestors`. The only difference is that it is
//! instantiated with a C `parsers.index` instance instead of a parents
//! function.
Georges Racinet
rust-cpython: rustdoc improvements...
r41220 //!
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 //! - [`MissingAncestors`] is the Rust implementation of
//! `mercurial.ancestor.incrementalmissingancestors`.
//!
//! API differences:
Raphaël Gomès
rustfmt: format the codebase with nightly-2024-07-16...
r52598 //! + it is instantiated with a C `parsers.index` instance instead of a
//! parents function.
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 //! + `MissingAncestors.bases` is a method returning a tuple instead of
//! a set-valued attribute. We could return a Python set easily if our
//! [PySet PR](https://github.com/dgrunwald/rust-cpython/pull/165)
//! is accepted.
//!
Georges Racinet
rust-cpython: rustdoc improvements...
r41220 //! - [`AncestorsIterator`] is the Rust counterpart of the
Georges Racinet
rust-cpython: set conversion for MissingAncestors.bases()...
r41279 //! `ancestor._lazyancestorsiter` Python generator. From Python, instances of
//! this should be mainly obtained by calling `iter()` on a [`LazyAncestors`]
//! instance.
Georges Racinet
rust-cpython: rustdoc improvements...
r41220 //!
//! [`LazyAncestors`]: struct.LazyAncestors.html
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 //! [`MissingAncestors`]: struct.MissingAncestors.html
Georges Racinet
rust-cpython: rustdoc improvements...
r41220 //! [`AncestorsIterator`]: struct.AncestorsIterator.html
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 use crate::revlog::py_rust_index_to_graph;
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 use crate::PyRevision;
Raphaël Gomès
rust: switch hg-core and hg-cpython to rust 2018 edition...
r42828 use crate::{
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 conversion::rev_pyiter_collect, exceptions::GraphError,
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 revlog::PySharedIndex,
Raphaël Gomès
rust: switch hg-core and hg-cpython to rust 2018 edition...
r42828 };
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 use cpython::{
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 ObjectProtocol, PyClone, PyDict, PyErr, PyList, PyModule, PyObject,
PyResult, Python, PythonObject, ToPyObject, UnsafePyLeaked,
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 };
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132
pacien
hg-cpython: use ancestor iterator impls from vcsgraph...
r49350 use hg::MissingAncestors as CoreMissing;
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 use hg::Revision;
use std::cell::RefCell;
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 use std::collections::HashSet;
pacien
hg-cpython: use ancestor iterator impls from vcsgraph...
r49350 use vcsgraph::lazy_ancestors::{
AncestorsIterator as VCGAncestorsIterator,
LazyAncestors as VCGLazyAncestors,
};
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 // Error propagation for an [`UnsafePyLeaked`] wrapping a [`Result`]
//
// It would be nice for UnsharedPyLeaked to provide this directly as a variant
// of the `map` method with a signature such as:
//
// ```
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // unsafe fn map_or_err(py: Python,
// f: impl FnOnce(T) -> Result(U, E),
// convert_err: impl FnOnce(Python, E) -> PyErr)
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 // ```
//
// This would spare users of the `cpython` crate the additional `unsafe` deref
// to inspect the error and return it outside `UnsafePyLeaked`, and the
// subsequent unwrapping that this function performs.
fn pyleaked_or_map_err<T, E: std::fmt::Debug + Copy>(
py: Python,
leaked: UnsafePyLeaked<Result<T, E>>,
convert_err: impl FnOnce(Python, E) -> PyErr,
) -> PyResult<UnsafePyLeaked<T>> {
// Result.inspect_err is unstable in Rust 1.61
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 if let Err(e) = *unsafe { leaked.try_borrow(py)? } {
return Err(convert_err(py, e));
}
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 Ok(unsafe {
leaked.map(py, |res| {
res.expect("Error case should have already be treated")
})
})
}
Georges Racinet
rust-cpython: rustdoc improvements...
r41220 py_class!(pub class AncestorsIterator |py| {
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 data inner: RefCell<UnsafePyLeaked<VCGAncestorsIterator<PySharedIndex>>>;
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 def __next__(&self) -> PyResult<Option<PyRevision>> {
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let mut leaked = self.inner(py).borrow_mut();
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let mut inner = unsafe { leaked.try_borrow_mut(py)? };
match inner.next() {
pacien
hg-cpython: use ancestor iterator impls from vcsgraph...
r49350 Some(Err(e)) => Err(GraphError::pynew_from_vcsgraph(py, e)),
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 None => Ok(None),
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 Some(Ok(r)) => Ok(Some(PyRevision(r))),
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 }
}
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 def __contains__(&self, rev: PyRevision) -> PyResult<bool> {
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let mut leaked = self.inner(py).borrow_mut();
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let mut inner = unsafe { leaked.try_borrow_mut(py)? };
inner.contains(rev.0)
pacien
hg-cpython: use ancestor iterator impls from vcsgraph...
r49350 .map_err(|e| GraphError::pynew_from_vcsgraph(py, e))
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 }
def __iter__(&self) -> PyResult<Self> {
Ok(self.clone_ref(py))
}
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 def __new__(
_cls,
index: PyObject,
initrevs: PyObject,
stoprev: PyRevision,
inclusive: bool
) -> PyResult<AncestorsIterator> {
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 Self::inner_new(py, index, initrevs, stoprev, inclusive)
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 }
});
impl AncestorsIterator {
pacien
hg-cpython: use ancestor iterator impls from vcsgraph...
r49350 pub fn from_inner(
py: Python,
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 ait: UnsafePyLeaked<VCGAncestorsIterator<PySharedIndex>>,
pacien
hg-cpython: use ancestor iterator impls from vcsgraph...
r49350 ) -> PyResult<Self> {
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 Self::create_instance(py, RefCell::new(ait))
}
pub fn inner_new(
py: Python,
index: PyObject,
initrevs: PyObject,
stoprev: PyRevision,
inclusive: bool,
) -> PyResult<AncestorsIterator> {
let index = py_rust_index_to_graph(py, index)?;
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let initvec: Vec<_> = {
let borrowed_idx = unsafe { index.try_borrow(py)? };
rev_pyiter_collect(py, &initrevs, &*borrowed_idx)?
};
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let res_ait = unsafe {
index.map(py, |idx| {
VCGAncestorsIterator::new(
idx,
initvec.into_iter().map(|r| r.0),
stoprev.0,
inclusive,
)
})
};
let ait =
pyleaked_or_map_err(py, res_ait, GraphError::pynew_from_vcsgraph)?;
AncestorsIterator::from_inner(py, ait)
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 }
}
Georges Racinet
rust-cpython: start cpython crate bindings...
r41001
Georges Racinet
rust-cpython: rustdoc improvements...
r41220 py_class!(pub class LazyAncestors |py| {
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 data inner: RefCell<UnsafePyLeaked<
RefCell<VCGLazyAncestors<PySharedIndex>>
>>;
data index: PyObject;
data initrevs: PyObject;
data stoprev: PyRevision;
data inclusive: bool;
Georges Racinet
rust-cpython: binding for LazyAncestors...
r41149
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 def __contains__(&self, rev: PyRevision) -> PyResult<bool> {
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let leaked = self.inner(py).borrow();
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let inner: &RefCell<VCGLazyAncestors<PySharedIndex>> =
&*unsafe { leaked.try_borrow(py)? };
let inner_mut: &mut VCGLazyAncestors<PySharedIndex> =
Raphaël Gomès
rust-clippy: apply some more trivial fixes...
r52165 &mut inner.borrow_mut();
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 inner_mut.contains(rev.0)
pacien
hg-cpython: use ancestor iterator impls from vcsgraph...
r49350 .map_err(|e| GraphError::pynew_from_vcsgraph(py, e))
Georges Racinet
rust-cpython: binding for LazyAncestors...
r41149 }
def __iter__(&self) -> PyResult<AncestorsIterator> {
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let index = self.index(py).clone_ref(py);
let initrevs = self.initrevs(py).clone_ref(py);
AncestorsIterator::inner_new(py, index, initrevs,
*self.stoprev(py),
*self.inclusive(py))
Georges Racinet
rust-cpython: binding for LazyAncestors...
r41149 }
def __bool__(&self) -> PyResult<bool> {
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let leaked = self.inner(py).borrow();
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let inner = unsafe { leaked.try_borrow(py)? };
let empty = inner.borrow().is_empty();
Ok(!empty)
Georges Racinet
rust-cpython: binding for LazyAncestors...
r41149 }
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 def __new__(
_cls,
index: PyObject,
initrevs: PyObject,
stoprev: PyRevision,
inclusive: bool
) -> PyResult<Self> {
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let cloned_index = index.clone_ref(py);
let index = py_rust_index_to_graph(py, index)?;
let initvec: Vec<_> = {
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let borrowed_idx = unsafe {index.try_borrow(py)?};
rev_pyiter_collect(py, &initrevs, &*borrowed_idx)?
};
Georges Racinet
rust-cpython: binding for LazyAncestors...
r41149
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let res_lazy =
unsafe { index.map(py, |idx| VCGLazyAncestors::new(
idx,
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 initvec.into_iter().map(|r| r.0),
stoprev.0,
inclusive
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 ))};
let lazy = pyleaked_or_map_err(py, res_lazy,
GraphError::pynew_from_vcsgraph)?;
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet
rust-index: using the `hg::index::Index` in ancestors iterator and lazy set...
r52132 let lazy_cell = unsafe { lazy.map(py, RefCell::new)};
let res = Self::create_instance(
py, RefCell::new(lazy_cell),
cloned_index, initrevs, stoprev, inclusive)?;
Ok(res)
Georges Racinet
rust-cpython: binding for LazyAncestors...
r41149 }
});
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 py_class!(pub class MissingAncestors |py| {
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 data inner: RefCell<UnsafePyLeaked<
CoreMissing<PySharedIndex>
>>;
data index: PyObject;
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224
Raphaël Gomès
rust-format: cleanup ancestors.rs to make rustfmt happy...
r44927 def __new__(
_cls,
index: PyObject,
bases: PyObject
)
-> PyResult<MissingAncestors> {
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let cloned_index = index.clone_ref(py);
let inner_index = py_rust_index_to_graph(py, index)?;
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let bases_vec: Vec<_> = {
let borrowed_idx = unsafe { inner_index.try_borrow(py)? };
rev_pyiter_collect(py, &bases, &*borrowed_idx)?
};
Raphaël Gomès
rust: make `Revision` a newtype...
r51872
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let inner = unsafe {
inner_index.map(py, |idx| CoreMissing::new(idx, bases_vec))
};
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 MissingAncestors::create_instance(
py,
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 RefCell::new(inner),
cloned_index,
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 )
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 }
def hasbases(&self) -> PyResult<bool> {
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let leaked = self.inner(py).borrow();
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let inner: &CoreMissing<PySharedIndex> =
&*unsafe { leaked.try_borrow(py)? };
Ok(inner.has_bases())
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 }
def addbases(&self, bases: PyObject) -> PyResult<PyObject> {
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let bases_vec: Vec<_> = {
let leaked = py_rust_index_to_graph(py,
self.index(py).clone_ref(py))?;
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let index = &*unsafe { leaked.try_borrow(py)? };
rev_pyiter_collect(py, &bases, index)?
};
let mut leaked = self.inner(py).borrow_mut();
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let inner: &mut CoreMissing<PySharedIndex> =
&mut *unsafe { leaked.try_borrow_mut(py)? };
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 inner.add_bases(bases_vec);
// cpython doc has examples with PyResult<()> but this gives me
// the trait `cpython::ToPyObject` is not implemented for `()`
// so let's return an explicit None
Ok(py.None())
}
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 def bases(&self) -> PyResult<HashSet<PyRevision>> {
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let leaked = self.inner(py).borrow();
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let inner: &CoreMissing<PySharedIndex> =
&*unsafe { leaked.try_borrow(py)? };
Ok(inner.get_bases()
.iter()
.map(|r| PyRevision(r.0))
.collect()
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 )
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 }
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 def basesheads(&self) -> PyResult<HashSet<PyRevision>> {
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let leaked = self.inner(py).borrow();
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let inner: &CoreMissing<PySharedIndex> =
&*unsafe { leaked.try_borrow(py)? };
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 Ok(
inner
.bases_heads()
.map_err(|e| GraphError::pynew(py, e))?
.into_iter()
.map(|r| PyRevision(r.0))
.collect()
)
Georges Racinet
rust: MissingAncestors.basesheads()...
r41282 }
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 def removeancestorsfrom(&self, revs: PyObject) -> PyResult<PyObject> {
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let mut revs_pyset: HashSet<Revision> = {
// this is very lame: we convert to a Rust set, update it in place
// and then convert back to Python, only to have Python remove the
// excess (thankfully, Python is happy with a list or even an
// iterator)
// Leads to improve this:
// - have the CoreMissing instead do something emit revisions to
// discard
// - define a trait for sets of revisions in the core and
// implement it for a Python set rewrapped with the GIL marker
let leaked = py_rust_index_to_graph(py,
self.index(py).clone_ref(py))?;
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let index = &*unsafe { leaked.try_borrow(py)? };
Raphaël Gomès
rust-clippy: apply some more trivial fixes...
r52165 rev_pyiter_collect(py, &revs, index)?
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 };
let mut leaked = self.inner(py).borrow_mut();
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let inner: &mut CoreMissing<PySharedIndex> =
&mut *unsafe { leaked.try_borrow_mut(py)? };
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 inner.remove_ancestors_from(&mut revs_pyset)
.map_err(|e| GraphError::pynew(py, e))?;
// convert as Python list
let mut remaining_pyint_vec: Vec<PyObject> = Vec::with_capacity(
revs_pyset.len());
for rev in revs_pyset {
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 remaining_pyint_vec.push(
PyRevision(rev.0).to_py_object(py).into_object()
);
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 }
let remaining_pylist = PyList::new(py, remaining_pyint_vec.as_slice());
revs.call_method(py, "intersection_update", (remaining_pylist, ), None)
}
def missingancestors(&self, revs: PyObject) -> PyResult<PyList> {
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let revs_vec: Vec<Revision> = {
let leaked = py_rust_index_to_graph(py,
self.index(py).clone_ref(py))?;
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let index = &*unsafe { leaked.try_borrow(py)? };
rev_pyiter_collect(py, &revs, index)?
};
Raphaël Gomès
rust: make `Revision` a newtype...
r51872
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let mut leaked = self.inner(py).borrow_mut();
Raphaël Gomès
rust-index: document safety invariants being upheld for every `unsafe` block...
r52148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
Georges Racinet on incendie.racinet.fr
rust-index: using `hg::index::Index` in MissingAncestors...
r52133 let inner: &mut CoreMissing<PySharedIndex> =
&mut *unsafe { leaked.try_borrow_mut(py)? };
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 let missing_vec = match inner.missing_ancestors(revs_vec) {
Ok(missing) => missing,
Err(e) => {
return Err(GraphError::pynew(py, e));
}
};
// convert as Python list
let mut missing_pyint_vec: Vec<PyObject> = Vec::with_capacity(
missing_vec.len());
for rev in missing_vec {
Raphaël Gomès
rust: make `Revision` a newtype...
r51872 missing_pyint_vec.push(
PyRevision(rev.0).to_py_object(py).into_object()
);
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 }
Ok(PyList::new(py, missing_pyint_vec.as_slice()))
}
});
/// Create the module, with __package__ given from parent
Georges Racinet
rust-cpython: start cpython crate bindings...
r41001 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
let dotted_name = &format!("{}.ancestor", package);
let m = PyModule::new(py, dotted_name)?;
m.add(py, "__package__", package)?;
m.add(
py,
"__doc__",
"Generic DAG ancestor algorithms - Rust implementation",
)?;
Georges Racinet
rust-cpython: binding for AncestorsIterator...
r41083 m.add_class::<AncestorsIterator>(py)?;
Georges Racinet
rust-cpython: binding for LazyAncestors...
r41149 m.add_class::<LazyAncestors>(py)?;
Georges Racinet
rust-cpython: bindings for MissingAncestors...
r41224 m.add_class::<MissingAncestors>(py)?;
Georges Racinet
rust-cpython: start cpython crate bindings...
r41001
let sys = PyModule::import(py, "sys")?;
let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
sys_modules.set_item(py, dotted_name, &m)?;
// Example C code (see pyexpat.c and import.c) will "give away the
// reference", but we won't because it will be consumed once the
// Rust PyObject is dropped.
Ok(m)
}