diff tests/test-rust-ancestor.py @ 52533:6b694bdf752a

rust-pyo3: implementation of LazyAncestors There is a difference in the implementaion of `__contains__` between PyO3 and rust-cpython: if the specified signature in Rust code is for a precise type (e.g., `PyRevision`) rust-cpython would automatically convert the potential resulting `TypeError` into `Ok(false)`, whereas PyO3 let it bubble up. Hence we treat the case manually and add it to the common test. In Mercurial Python code, `None in` for a `LazyAncestors` object can really happens, namely in this lambda from `discover._postprocessobsolete`: ``` ispushed = lambda n: torev(n) in futurecommon ``` This lambda can get called with `n` such that `torev(n)` is `False` (seen in `test-bookmarks-push-pull.t`).
author Georges Racinet <georges.racinet@cloudcrane.io>
date Sat, 07 Dec 2024 18:54:31 +0100
parents 3ffcdbf0b432
children 507fec66014f
line wrap: on
line diff
--- a/tests/test-rust-ancestor.py	Sat Dec 07 18:42:06 2024 +0100
+++ b/tests/test-rust-ancestor.py	Sat Dec 07 18:54:31 2024 +0100
@@ -68,6 +68,49 @@
         ait = AncestorsIterator(idx, [3], 0, False)
         self.assertEqual([r for r in ait], [2, 1, 0])
 
+        ait = AncestorsIterator(idx, [3], 0, False)
+        # tainting the index with a mutation, let's see what happens
+        # (should be more critical with AncestorsIterator)
+        del idx[0:2]
+        try:
+            next(ait)
+        except RuntimeError as exc:
+            assert "leaked reference after mutation" in exc.args[0]
+        else:
+            raise AssertionError("Expected an exception")
+
+    def testlazyancestors(self):
+        LazyAncestors = self.ancestors_mod().LazyAncestors
+
+        idx = self.parserustindex()
+        start_count = sys.getrefcount(idx.inner)  # should be 2 (see Python doc)
+        self.assertEqual(
+            {i: (r[5], r[6]) for i, r in enumerate(idx)},
+            {0: (-1, -1), 1: (0, -1), 2: (1, -1), 3: (2, -1)},
+        )
+        lazy = LazyAncestors(idx, [3], 0, True)
+        # the LazyAncestors instance holds just one reference to the
+        # inner revlog. TODO check that this is normal
+        self.assertEqual(sys.getrefcount(idx.inner), start_count + 1)
+
+        self.assertTrue(2 in lazy)
+        self.assertTrue(bool(lazy))
+        self.assertFalse(None in lazy)
+        self.assertEqual(list(lazy), [3, 2, 1, 0])
+        # a second time to validate that we spawn new iterators
+        self.assertEqual(list(lazy), [3, 2, 1, 0])
+
+        # now let's watch the refcounts closer
+        ait = iter(lazy)
+        self.assertEqual(sys.getrefcount(idx.inner), start_count + 2)
+        del ait
+        self.assertEqual(sys.getrefcount(idx.inner), start_count + 1)
+        del lazy
+        self.assertEqual(sys.getrefcount(idx.inner), start_count)
+
+        # let's check bool for an empty one
+        self.assertFalse(LazyAncestors(idx, [0], 0, False))
+
     def testrefcount(self):
         AncestorsIterator = self.ancestors_mod().AncestorsIterator
 
@@ -135,37 +178,6 @@
 ):
     rustext_pkg = rustext
 
-    def testlazyancestors(self):
-        LazyAncestors = self.ancestors_mod().LazyAncestors
-
-        idx = self.parserustindex()
-        start_count = sys.getrefcount(idx.inner)  # should be 2 (see Python doc)
-        self.assertEqual(
-            {i: (r[5], r[6]) for i, r in enumerate(idx)},
-            {0: (-1, -1), 1: (0, -1), 2: (1, -1), 3: (2, -1)},
-        )
-        lazy = LazyAncestors(idx, [3], 0, True)
-        # the LazyAncestors instance holds just one reference to the
-        # inner revlog.
-        self.assertEqual(sys.getrefcount(idx.inner), start_count + 1)
-
-        self.assertTrue(2 in lazy)
-        self.assertTrue(bool(lazy))
-        self.assertEqual(list(lazy), [3, 2, 1, 0])
-        # a second time to validate that we spawn new iterators
-        self.assertEqual(list(lazy), [3, 2, 1, 0])
-
-        # now let's watch the refcounts closer
-        ait = iter(lazy)
-        self.assertEqual(sys.getrefcount(idx.inner), start_count + 2)
-        del ait
-        self.assertEqual(sys.getrefcount(idx.inner), start_count + 1)
-        del lazy
-        self.assertEqual(sys.getrefcount(idx.inner), start_count)
-
-        # let's check bool for an empty one
-        self.assertFalse(LazyAncestors(idx, [0], 0, False))
-
     def testmissingancestors(self):
         MissingAncestors = self.ancestors_mod().MissingAncestors