Mercurial > hg
changeset 41243:5257e6299d4c
rust-cpython: set conversion for MissingAncestors.bases()
Also I hope that the separate `py_set()` helper will help transition
to proper `PySet` support in `rust-cpython`
Took the opportunity to replace explict for loop with iteration
and collect().
Differential Revision: https://phab.mercurial-scm.org/D5581
author | Georges Racinet <georges.racinet@octobus.net> |
---|---|
date | Mon, 14 Jan 2019 17:46:14 +0100 |
parents | 47881d2a9d99 |
children | 4856c9b8cbaf |
files | rust/hg-cpython/src/ancestors.rs tests/test-rust-ancestor.py |
diffstat | 2 files changed, 29 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-cpython/src/ancestors.rs Mon Jan 14 10:07:48 2019 +0100 +++ b/rust/hg-cpython/src/ancestors.rs Mon Jan 14 17:46:14 2019 +0100 @@ -11,9 +11,9 @@ //! //! # Classes visible from Python: //! - [`LazyAncestors`] is the Rust implementation of -//! `mercurial.ancestor.lazyancestors`. -//! The only difference is that it is instantiated with a C `parsers.index` -//! instance instead of a parents function. +//! `mercurial.ancestor.lazyancestors`. The only difference is that it is +//! instantiated with a C `parsers.index` instance instead of a parents +//! function. //! //! - [`MissingAncestors`] is the Rust implementation of //! `mercurial.ancestor.incrementalmissingancestors`. @@ -27,9 +27,9 @@ //! is accepted. //! //! - [`AncestorsIterator`] is the Rust counterpart of the -//! `ancestor._lazyancestorsiter` Python generator. -//! From Python, instances of this should be mainly obtained by calling -//! `iter()` on a [`LazyAncestors`] instance. +//! `ancestor._lazyancestorsiter` Python generator. From Python, instances of +//! this should be mainly obtained by calling `iter()` on a [`LazyAncestors`] +//! instance. //! //! [`LazyAncestors`]: struct.LazyAncestors.html //! [`MissingAncestors`]: struct.MissingAncestors.html @@ -37,8 +37,8 @@ use crate::conversion::rev_pyiter_collect; use cindex::Index; use cpython::{ - ObjectProtocol, PyClone, PyDict, PyList, PyModule, PyObject, - PyResult, PyTuple, Python, PythonObject, ToPyObject, + ObjectProtocol, PyClone, PyDict, PyList, PyModule, PyObject, PyResult, + PyTuple, Python, PythonObject, ToPyObject, }; use exceptions::GraphError; use hg::Revision; @@ -90,6 +90,24 @@ } } +/// Copy and convert an `HashSet<Revision>` in a Python set +/// +/// This will probably turn useless once `PySet` support lands in +/// `rust-cpython`. +/// +/// This builds a Python tuple, then calls Python's "set()" on it +fn py_set(py: Python, set: &HashSet<Revision>) -> PyResult<PyObject> { + let as_vec: Vec<PyObject> = set + .iter() + .map(|rev| rev.to_py_object(py).into_object()) + .collect(); + let as_pytuple = PyTuple::new(py, as_vec.as_slice()); + + let locals = PyDict::new(py); + locals.set_item(py, "obj", as_pytuple.to_py_object(py))?; + py.eval("set(obj)", None, Some(&locals)) +} + py_class!(pub class LazyAncestors |py| { data inner: RefCell<Box<CoreLazy<Index>>>; @@ -144,16 +162,8 @@ Ok(py.None()) } - def bases(&self) -> PyResult<PyTuple> { - let inner = self.inner(py).borrow(); - let bases_set = inner.get_bases(); - // convert as Python tuple TODO how to return a proper Python set? - let mut bases_vec: Vec<PyObject> = Vec::with_capacity( - bases_set.len()); - for rev in bases_set { - bases_vec.push(rev.to_py_object(py).into_object()); - } - Ok(PyTuple::new(py, bases_vec.as_slice())) + def bases(&self) -> PyResult<PyObject> { + py_set(py, self.inner(py).borrow().get_bases()) } def removeancestorsfrom(&self, revs: PyObject) -> PyResult<PyObject> {
--- a/tests/test-rust-ancestor.py Mon Jan 14 10:07:48 2019 +0100 +++ b/tests/test-rust-ancestor.py Mon Jan 14 17:46:14 2019 +0100 @@ -112,7 +112,7 @@ self.assertTrue(missanc.hasbases()) self.assertEqual(missanc.missingancestors([3]), [2, 3]) missanc.addbases({2}) - self.assertEqual(set(missanc.bases()), {1, 2}) + self.assertEqual(missanc.bases(), {1, 2}) self.assertEqual(missanc.missingancestors([3]), [3]) def testmissingancestorsremove(self):