annotate rust/hg-cpython/src/ancestors.rs @ 51723:9367571fea21

cext: correct the argument handling of `b85encode()` The type stub indicated that this argument is `Optional`, which implies None is allowed. I don't see in the documentation where that's the case for `i`[1], and trying it in `hg debugshell` resulted in the method failing with a TypeError. I guess it was typed as an `int` argument because the `p` format unit wasn't added until Python 3.3[2]. In any event, 2 clients in core (`pvec` and `obsolete`) call this with no argument supplied, and `mdiff` calls it with True. So I guess we've avoided the None arg case, and when no arg is supplied, it defaults to the 0 initialization of the `pad` variable in C. Since the `p` format unit accepts both `int` and None, as well as `bool`, I'm not bothering to bump the module version- this code is more permissive than it was, in addition to being more correct. Interestingly, when I first imported the `cext` and `pure` methods in the same manner as the previous commit, it dropped the `Optional` part of the argument type when generating `util.pyi`. No idea why. [1] https://docs.python.org/3/c-api/arg.html#numbers [2] https://docs.python.org/3/c-api/arg.html#other-objects
author Matt Harbison <matt_harbison@yahoo.com>
date Sat, 20 Jul 2024 01:55:09 -0400
parents 3876d4c6c79e
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
40965
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
1 // ancestors.rs
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
2 //
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
3 // Copyright 2018 Georges Racinet <gracinet@anybox.fr>
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
4 //
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
5 // This software may be used and distributed according to the terms of the
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
6 // GNU General Public License version 2 or any later version.
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
7
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41114
diff changeset
8 //! Bindings for the `hg::ancestors` module provided by the
40965
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
9 //! `hg-core` crate. From Python, this will be seen as `rustext.ancestor`
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41114
diff changeset
10 //! and can be used as replacement for the the pure `ancestor` Python module.
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41114
diff changeset
11 //!
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41114
diff changeset
12 //! # Classes visible from Python:
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41114
diff changeset
13 //! - [`LazyAncestors`] is the Rust implementation of
41243
5257e6299d4c rust-cpython: set conversion for MissingAncestors.bases()
Georges Racinet <georges.racinet@octobus.net>
parents: 41240
diff changeset
14 //! `mercurial.ancestor.lazyancestors`. The only difference is that it is
5257e6299d4c rust-cpython: set conversion for MissingAncestors.bases()
Georges Racinet <georges.racinet@octobus.net>
parents: 41240
diff changeset
15 //! instantiated with a C `parsers.index` instance instead of a parents
5257e6299d4c rust-cpython: set conversion for MissingAncestors.bases()
Georges Racinet <georges.racinet@octobus.net>
parents: 41240
diff changeset
16 //! function.
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41114
diff changeset
17 //!
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
18 //! - [`MissingAncestors`] is the Rust implementation of
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
19 //! `mercurial.ancestor.incrementalmissingancestors`.
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
20 //!
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
21 //! API differences:
51705
3876d4c6c79e rustfmt: format the codebase with nightly-2024-07-16
Raphaël Gomès <rgomes@octobus.net>
parents: 51700
diff changeset
22 //! + it is instantiated with a C `parsers.index` instance instead of a
3876d4c6c79e rustfmt: format the codebase with nightly-2024-07-16
Raphaël Gomès <rgomes@octobus.net>
parents: 51700
diff changeset
23 //! parents function.
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
24 //! + `MissingAncestors.bases` is a method returning a tuple instead of
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
25 //! a set-valued attribute. We could return a Python set easily if our
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
26 //! [PySet PR](https://github.com/dgrunwald/rust-cpython/pull/165)
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
27 //! is accepted.
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
28 //!
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41114
diff changeset
29 //! - [`AncestorsIterator`] is the Rust counterpart of the
41243
5257e6299d4c rust-cpython: set conversion for MissingAncestors.bases()
Georges Racinet <georges.racinet@octobus.net>
parents: 41240
diff changeset
30 //! `ancestor._lazyancestorsiter` Python generator. From Python, instances of
5257e6299d4c rust-cpython: set conversion for MissingAncestors.bases()
Georges Racinet <georges.racinet@octobus.net>
parents: 41240
diff changeset
31 //! this should be mainly obtained by calling `iter()` on a [`LazyAncestors`]
5257e6299d4c rust-cpython: set conversion for MissingAncestors.bases()
Georges Racinet <georges.racinet@octobus.net>
parents: 41240
diff changeset
32 //! instance.
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41114
diff changeset
33 //!
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41114
diff changeset
34 //! [`LazyAncestors`]: struct.LazyAncestors.html
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
35 //! [`MissingAncestors`]: struct.MissingAncestors.html
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41114
diff changeset
36 //! [`AncestorsIterator`]: struct.AncestorsIterator.html
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
37 use crate::revlog::py_rust_index_to_graph;
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
38 use crate::PyRevision;
42609
326fdce22fb2 rust: switch hg-core and hg-cpython to rust 2018 edition
Raphaël Gomès <rgomes@octobus.net>
parents: 41693
diff changeset
39 use crate::{
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
40 conversion::rev_pyiter_collect, exceptions::GraphError,
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
41 revlog::PySharedIndex,
42609
326fdce22fb2 rust: switch hg-core and hg-cpython to rust 2018 edition
Raphaël Gomès <rgomes@octobus.net>
parents: 41693
diff changeset
42 };
41053
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
43 use cpython::{
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
44 ObjectProtocol, PyClone, PyDict, PyErr, PyList, PyModule, PyObject,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
45 PyResult, Python, PythonObject, ToPyObject, UnsafePyLeaked,
41053
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
46 };
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
47
48519
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44431
diff changeset
48 use hg::MissingAncestors as CoreMissing;
41053
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
49 use hg::Revision;
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
50 use std::cell::RefCell;
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
51 use std::collections::HashSet;
48519
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44431
diff changeset
52 use vcsgraph::lazy_ancestors::{
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44431
diff changeset
53 AncestorsIterator as VCGAncestorsIterator,
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44431
diff changeset
54 LazyAncestors as VCGLazyAncestors,
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44431
diff changeset
55 };
41053
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
56
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
57 // Error propagation for an [`UnsafePyLeaked`] wrapping a [`Result`]
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
58 //
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
59 // It would be nice for UnsharedPyLeaked to provide this directly as a variant
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
60 // of the `map` method with a signature such as:
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
61 //
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
62 // ```
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
63 // unsafe fn map_or_err(py: Python,
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
64 // f: impl FnOnce(T) -> Result(U, E),
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
65 // convert_err: impl FnOnce(Python, E) -> PyErr)
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
66 // ```
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
67 //
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
68 // This would spare users of the `cpython` crate the additional `unsafe` deref
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
69 // to inspect the error and return it outside `UnsafePyLeaked`, and the
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
70 // subsequent unwrapping that this function performs.
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
71 fn pyleaked_or_map_err<T, E: std::fmt::Debug + Copy>(
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
72 py: Python,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
73 leaked: UnsafePyLeaked<Result<T, E>>,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
74 convert_err: impl FnOnce(Python, E) -> PyErr,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
75 ) -> PyResult<UnsafePyLeaked<T>> {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
76 // Result.inspect_err is unstable in Rust 1.61
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
77 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
78 if let Err(e) = *unsafe { leaked.try_borrow(py)? } {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
79 return Err(convert_err(py, e));
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
80 }
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
81 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
82 Ok(unsafe {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
83 leaked.map(py, |res| {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
84 res.expect("Error case should have already be treated")
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
85 })
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
86 })
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
87 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
88
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41114
diff changeset
89 py_class!(pub class AncestorsIterator |py| {
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
90 data inner: RefCell<UnsafePyLeaked<VCGAncestorsIterator<PySharedIndex>>>;
41053
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
91
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
92 def __next__(&self) -> PyResult<Option<PyRevision>> {
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
93 let mut leaked = self.inner(py).borrow_mut();
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
94 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
95 let mut inner = unsafe { leaked.try_borrow_mut(py)? };
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
96 match inner.next() {
48519
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44431
diff changeset
97 Some(Err(e)) => Err(GraphError::pynew_from_vcsgraph(py, e)),
41053
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
98 None => Ok(None),
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
99 Some(Ok(r)) => Ok(Some(PyRevision(r))),
41053
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
100 }
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
101 }
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
102
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
103 def __contains__(&self, rev: PyRevision) -> PyResult<bool> {
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
104 let mut leaked = self.inner(py).borrow_mut();
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
105 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
106 let mut inner = unsafe { leaked.try_borrow_mut(py)? };
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
107 inner.contains(rev.0)
48519
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44431
diff changeset
108 .map_err(|e| GraphError::pynew_from_vcsgraph(py, e))
41053
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
109 }
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
110
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
111 def __iter__(&self) -> PyResult<Self> {
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
112 Ok(self.clone_ref(py))
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
113 }
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
114
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
115 def __new__(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
116 _cls,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
117 index: PyObject,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
118 initrevs: PyObject,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
119 stoprev: PyRevision,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
120 inclusive: bool
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
121 ) -> PyResult<AncestorsIterator> {
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
122 Self::inner_new(py, index, initrevs, stoprev, inclusive)
41053
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
123 }
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
124
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
125 });
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
126
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
127 impl AncestorsIterator {
48519
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44431
diff changeset
128 pub fn from_inner(
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44431
diff changeset
129 py: Python,
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
130 ait: UnsafePyLeaked<VCGAncestorsIterator<PySharedIndex>>,
48519
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44431
diff changeset
131 ) -> PyResult<Self> {
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
132 Self::create_instance(py, RefCell::new(ait))
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
133 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
134
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
135 pub fn inner_new(
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
136 py: Python,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
137 index: PyObject,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
138 initrevs: PyObject,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
139 stoprev: PyRevision,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
140 inclusive: bool,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
141 ) -> PyResult<AncestorsIterator> {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
142 let index = py_rust_index_to_graph(py, index)?;
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
143 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
144 let initvec: Vec<_> = {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
145 let borrowed_idx = unsafe { index.try_borrow(py)? };
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
146 rev_pyiter_collect(py, &initrevs, &*borrowed_idx)?
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
147 };
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
148 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
149 let res_ait = unsafe {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
150 index.map(py, |idx| {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
151 VCGAncestorsIterator::new(
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
152 idx,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
153 initvec.into_iter().map(|r| r.0),
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
154 stoprev.0,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
155 inclusive,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
156 )
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
157 })
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
158 };
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
159 let ait =
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
160 pyleaked_or_map_err(py, res_ait, GraphError::pynew_from_vcsgraph)?;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
161 AncestorsIterator::from_inner(py, ait)
41053
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
162 }
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
163 }
40965
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
164
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41114
diff changeset
165 py_class!(pub class LazyAncestors |py| {
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
166 data inner: RefCell<UnsafePyLeaked<
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
167 RefCell<VCGLazyAncestors<PySharedIndex>>
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
168 >>;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
169 data index: PyObject;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
170 data initrevs: PyObject;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
171 data stoprev: PyRevision;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
172 data inclusive: bool;
41114
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
173
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
174 def __contains__(&self, rev: PyRevision) -> PyResult<bool> {
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
175 let leaked = self.inner(py).borrow();
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
176 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
177 let inner: &RefCell<VCGLazyAncestors<PySharedIndex>> =
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
178 &*unsafe { leaked.try_borrow(py)? };
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
179 let inner_mut: &mut VCGLazyAncestors<PySharedIndex> =
51272
c4cbb515b006 rust-clippy: apply some more trivial fixes
Raphaël Gomès <rgomes@octobus.net>
parents: 51255
diff changeset
180 &mut inner.borrow_mut();
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
181 inner_mut.contains(rev.0)
48519
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44431
diff changeset
182 .map_err(|e| GraphError::pynew_from_vcsgraph(py, e))
41114
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
183 }
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
184
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
185 def __iter__(&self) -> PyResult<AncestorsIterator> {
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
186 let index = self.index(py).clone_ref(py);
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
187 let initrevs = self.initrevs(py).clone_ref(py);
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
188 AncestorsIterator::inner_new(py, index, initrevs,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
189 *self.stoprev(py),
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
190 *self.inclusive(py))
41114
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
191 }
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
192
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
193 def __bool__(&self) -> PyResult<bool> {
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
194 let leaked = self.inner(py).borrow();
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
195 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
196 let inner = unsafe { leaked.try_borrow(py)? };
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
197 let empty = inner.borrow().is_empty();
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
198 Ok(!empty)
41114
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
199 }
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
200
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
201 def __new__(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
202 _cls,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
203 index: PyObject,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
204 initrevs: PyObject,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
205 stoprev: PyRevision,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
206 inclusive: bool
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
207 ) -> PyResult<Self> {
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
208 let cloned_index = index.clone_ref(py);
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
209 let index = py_rust_index_to_graph(py, index)?;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
210 let initvec: Vec<_> = {
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
211 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
212 let borrowed_idx = unsafe {index.try_borrow(py)?};
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
213 rev_pyiter_collect(py, &initrevs, &*borrowed_idx)?
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
214 };
41114
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
215
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
216 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
217 let res_lazy =
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
218 unsafe { index.map(py, |idx| VCGLazyAncestors::new(
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
219 idx,
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
220 initvec.into_iter().map(|r| r.0),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
221 stoprev.0,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
222 inclusive
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
223 ))};
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
224 let lazy = pyleaked_or_map_err(py, res_lazy,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
225 GraphError::pynew_from_vcsgraph)?;
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
226 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
227 let lazy_cell = unsafe { lazy.map(py, RefCell::new)};
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
228 let res = Self::create_instance(
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
229 py, RefCell::new(lazy_cell),
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
230 cloned_index, initrevs, stoprev, inclusive)?;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50979
diff changeset
231 Ok(res)
41114
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
232 }
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
233
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
234 });
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
235
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
236 py_class!(pub class MissingAncestors |py| {
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
237 data inner: RefCell<UnsafePyLeaked<
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
238 CoreMissing<PySharedIndex>
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
239 >>;
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
240 data index: PyObject;
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
241
44431
b24721e7c5ee rust-format: cleanup ancestors.rs to make rustfmt happy
Raphaël Gomès <rgomes@octobus.net>
parents: 43945
diff changeset
242 def __new__(
b24721e7c5ee rust-format: cleanup ancestors.rs to make rustfmt happy
Raphaël Gomès <rgomes@octobus.net>
parents: 43945
diff changeset
243 _cls,
b24721e7c5ee rust-format: cleanup ancestors.rs to make rustfmt happy
Raphaël Gomès <rgomes@octobus.net>
parents: 43945
diff changeset
244 index: PyObject,
b24721e7c5ee rust-format: cleanup ancestors.rs to make rustfmt happy
Raphaël Gomès <rgomes@octobus.net>
parents: 43945
diff changeset
245 bases: PyObject
b24721e7c5ee rust-format: cleanup ancestors.rs to make rustfmt happy
Raphaël Gomès <rgomes@octobus.net>
parents: 43945
diff changeset
246 )
b24721e7c5ee rust-format: cleanup ancestors.rs to make rustfmt happy
Raphaël Gomès <rgomes@octobus.net>
parents: 43945
diff changeset
247 -> PyResult<MissingAncestors> {
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
248 let cloned_index = index.clone_ref(py);
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
249 let inner_index = py_rust_index_to_graph(py, index)?;
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
250 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
251 let bases_vec: Vec<_> = {
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
252 let borrowed_idx = unsafe { inner_index.try_borrow(py)? };
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
253 rev_pyiter_collect(py, &bases, &*borrowed_idx)?
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
254 };
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
255
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
256 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
257 let inner = unsafe {
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
258 inner_index.map(py, |idx| CoreMissing::new(idx, bases_vec))
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
259 };
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
260 MissingAncestors::create_instance(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
261 py,
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
262 RefCell::new(inner),
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
263 cloned_index,
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
264 )
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
265 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
266
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
267 def hasbases(&self) -> PyResult<bool> {
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
268 let leaked = self.inner(py).borrow();
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
269 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
270 let inner: &CoreMissing<PySharedIndex> =
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
271 &*unsafe { leaked.try_borrow(py)? };
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
272 Ok(inner.has_bases())
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
273 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
274
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
275 def addbases(&self, bases: PyObject) -> PyResult<PyObject> {
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
276 let bases_vec: Vec<_> = {
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
277 let leaked = py_rust_index_to_graph(py,
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
278 self.index(py).clone_ref(py))?;
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
279 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
280 let index = &*unsafe { leaked.try_borrow(py)? };
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
281 rev_pyiter_collect(py, &bases, index)?
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
282 };
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
283
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
284 let mut leaked = self.inner(py).borrow_mut();
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
285 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
286 let inner: &mut CoreMissing<PySharedIndex> =
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
287 &mut *unsafe { leaked.try_borrow_mut(py)? };
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
288
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
289 inner.add_bases(bases_vec);
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
290 // cpython doc has examples with PyResult<()> but this gives me
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
291 // the trait `cpython::ToPyObject` is not implemented for `()`
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
292 // so let's return an explicit None
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
293 Ok(py.None())
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
294 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
295
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
296 def bases(&self) -> PyResult<HashSet<PyRevision>> {
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
297 let leaked = self.inner(py).borrow();
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
298 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
299 let inner: &CoreMissing<PySharedIndex> =
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
300 &*unsafe { leaked.try_borrow(py)? };
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
301 Ok(inner.get_bases()
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
302 .iter()
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
303 .map(|r| PyRevision(r.0))
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
304 .collect()
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
305 )
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
306 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
307
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
308 def basesheads(&self) -> PyResult<HashSet<PyRevision>> {
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
309 let leaked = self.inner(py).borrow();
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
310 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
311 let inner: &CoreMissing<PySharedIndex> =
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
312 &*unsafe { leaked.try_borrow(py)? };
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
313 Ok(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
314 inner
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
315 .bases_heads()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
316 .map_err(|e| GraphError::pynew(py, e))?
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
317 .into_iter()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
318 .map(|r| PyRevision(r.0))
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
319 .collect()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
320 )
41246
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41243
diff changeset
321 }
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41243
diff changeset
322
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
323 def removeancestorsfrom(&self, revs: PyObject) -> PyResult<PyObject> {
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
324 let mut revs_pyset: HashSet<Revision> = {
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
325 // this is very lame: we convert to a Rust set, update it in place
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
326 // and then convert back to Python, only to have Python remove the
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
327 // excess (thankfully, Python is happy with a list or even an
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
328 // iterator)
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
329 // Leads to improve this:
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
330 // - have the CoreMissing instead do something emit revisions to
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
331 // discard
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
332 // - define a trait for sets of revisions in the core and
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
333 // implement it for a Python set rewrapped with the GIL marker
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
334 let leaked = py_rust_index_to_graph(py,
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
335 self.index(py).clone_ref(py))?;
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
336 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
337 let index = &*unsafe { leaked.try_borrow(py)? };
51272
c4cbb515b006 rust-clippy: apply some more trivial fixes
Raphaël Gomès <rgomes@octobus.net>
parents: 51255
diff changeset
338 rev_pyiter_collect(py, &revs, index)?
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
339 };
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
340
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
341 let mut leaked = self.inner(py).borrow_mut();
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
342 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
343 let inner: &mut CoreMissing<PySharedIndex> =
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
344 &mut *unsafe { leaked.try_borrow_mut(py)? };
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
345
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
346 inner.remove_ancestors_from(&mut revs_pyset)
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
347 .map_err(|e| GraphError::pynew(py, e))?;
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
348
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
349 // convert as Python list
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
350 let mut remaining_pyint_vec: Vec<PyObject> = Vec::with_capacity(
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
351 revs_pyset.len());
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
352 for rev in revs_pyset {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
353 remaining_pyint_vec.push(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
354 PyRevision(rev.0).to_py_object(py).into_object()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
355 );
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
356 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
357 let remaining_pylist = PyList::new(py, remaining_pyint_vec.as_slice());
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
358 revs.call_method(py, "intersection_update", (remaining_pylist, ), None)
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
359 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
360
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
361 def missingancestors(&self, revs: PyObject) -> PyResult<PyList> {
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
362 let revs_vec: Vec<Revision> = {
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
363 let leaked = py_rust_index_to_graph(py,
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
364 self.index(py).clone_ref(py))?;
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
365 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
366 let index = &*unsafe { leaked.try_borrow(py)? };
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
367 rev_pyiter_collect(py, &revs, index)?
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
368 };
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
369
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
370 let mut leaked = self.inner(py).borrow_mut();
51255
24d3298189d7 rust-index: document safety invariants being upheld for every `unsafe` block
Raphaël Gomès <rgomes@octobus.net>
parents: 51240
diff changeset
371 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
51240
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
372 let inner: &mut CoreMissing<PySharedIndex> =
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
373 &mut *unsafe { leaked.try_borrow_mut(py)? };
59d81768ad6d rust-index: using `hg::index::Index` in MissingAncestors
Georges Racinet on incendie.racinet.fr <georges@racinet.fr>
parents: 51239
diff changeset
374
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
375 let missing_vec = match inner.missing_ancestors(revs_vec) {
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
376 Ok(missing) => missing,
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
377 Err(e) => {
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
378 return Err(GraphError::pynew(py, e));
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
379 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
380 };
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
381 // convert as Python list
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
382 let mut missing_pyint_vec: Vec<PyObject> = Vec::with_capacity(
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
383 missing_vec.len());
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
384 for rev in missing_vec {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
385 missing_pyint_vec.push(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
386 PyRevision(rev.0).to_py_object(py).into_object()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48519
diff changeset
387 );
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
388 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
389 Ok(PyList::new(py, missing_pyint_vec.as_slice()))
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
390 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
391 });
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
392
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
393 /// Create the module, with __package__ given from parent
40965
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
394 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
395 let dotted_name = &format!("{}.ancestor", package);
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
396 let m = PyModule::new(py, dotted_name)?;
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
397 m.add(py, "__package__", package)?;
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
398 m.add(
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
399 py,
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
400 "__doc__",
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
401 "Generic DAG ancestor algorithms - Rust implementation",
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
402 )?;
41053
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40965
diff changeset
403 m.add_class::<AncestorsIterator>(py)?;
41114
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41053
diff changeset
404 m.add_class::<LazyAncestors>(py)?;
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
405 m.add_class::<MissingAncestors>(py)?;
40965
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
406
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
407 let sys = PyModule::import(py, "sys")?;
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
408 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
409 sys_modules.set_item(py, dotted_name, &m)?;
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
410 // Example C code (see pyexpat.c and import.c) will "give away the
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
411 // reference", but we won't because it will be consumed once the
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
412 // Rust PyObject is dropped.
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
413 Ok(m)
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
414 }