Mercurial > public > mercurial-scm > hg
changeset 52793:6a70e4931773
rust-pyo3-revlog: ReadingContextManager
Stepping aside from the implementation of index methods to show
that this will not be a problem.
The test basically only demonstrates that it behaves like a
context manager indeed ? of course our fixture does not provide
any reasonable file access.
author | Georges Racinet <georges.racinet@cloudcrane.io> |
---|---|
date | Mon, 23 Dec 2024 00:17:03 +0100 |
parents | acae91fad6be |
children | 5ad4ed71fbe0 |
files | rust/hg-pyo3/src/revlog/mod.rs tests/test-rust-revlog.py |
diffstat | 2 files changed, 49 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-pyo3/src/revlog/mod.rs Sun Dec 22 17:02:09 2024 +0100 +++ b/rust/hg-pyo3/src/revlog/mod.rs Mon Dec 23 00:17:03 2024 +0100 @@ -53,6 +53,38 @@ }; #[pyclass] +struct ReadingContextManager { + inner_revlog: Py<InnerRevlog>, +} + +#[pymethods] +impl ReadingContextManager { + fn __enter__(slf: PyRef<'_, Self>) -> PyResult<()> { + let inner_bound = slf.inner_revlog.bind(slf.py()); + let shareable = &inner_bound.borrow().irl; + // Safety: the owner is correct and we won't use `share()` anyway + let core_irl = + unsafe { shareable.borrow_with_owner(inner_bound) }.read(); + core_irl + .enter_reading_context() + .map_err(revlog_error_from_msg) + .inspect_err(|_e| { + // `__exit__` is not called from Python if `__enter__` fails + core_irl.exit_reading_context(); + }) + } + + #[pyo3(signature = (*_args))] + fn __exit__(slf: PyRef<'_, Self>, _args: &Bound<'_, PyTuple>) { + let inner_bound = slf.inner_revlog.bind(slf.py()); + let shareable = &inner_bound.borrow().irl; + // Safety: the owner is correct and we won't use `share()` anyway + let core_irl_ref = unsafe { shareable.borrow_with_owner(inner_bound) }; + core_irl_ref.read().exit_reading_context(); + } +} + +#[pyclass] #[allow(dead_code)] struct InnerRevlog { irl: PyShareable<CoreInnerRevlog>, @@ -146,6 +178,12 @@ }) } + fn reading(slf: &Bound<'_, Self>) -> PyResult<ReadingContextManager> { + Ok(ReadingContextManager { + inner_revlog: slf.clone().unbind(), + }) + } + // // -- forwarded index methods -- // @@ -575,5 +613,6 @@ let m = new_submodule(py, package, "revlog")?; m.add_class::<InnerRevlog>()?; m.add_class::<NodeTree>()?; + m.add_class::<ReadingContextManager>()?; Ok(m) }
--- a/tests/test-rust-revlog.py Sun Dec 22 17:02:09 2024 +0100 +++ b/tests/test-rust-revlog.py Mon Dec 23 00:17:03 2024 +0100 @@ -156,6 +156,16 @@ del idx[3] self.assertTrue(nt.is_invalidated()) + def test_reading_context_manager(self): + irl = self.make_inner_revlog() + try: + with irl.reading(): + # not much to do yet + pass + except error.RevlogError as exc: + # well our data file does not even exist + self.assertTrue(b"when reading Just a path/test.d" in exc.args[0]) + # Conditional skipping done by the base class class RustInnerRevlogTest(