Patchwork D10665: revlog: signal which revlog index are compatible with Rust

login
register
mail settings
Submitter phabricator
Date May 4, 2021, 2:20 p.m.
Message ID <differential-rev-PHID-DREV-anosiv47w7ajkzymamcb-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/48983/
State Superseded
Headers show

Comments

phabricator - May 4, 2021, 2:20 p.m.
marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  Otherwise, Rust may treat python object like `cindex` object, leading to
  trouble. The new attribute is an integer because I expect we might need a flag
  field in the future.
  
  As a start we get the rust code to raise a clear TypeError. We will use the
  information in a smarter way in the next changesets.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D10665

AFFECTED FILES
  mercurial/cext/parsers.c
  mercurial/cext/revlog.c
  mercurial/policy.py
  mercurial/pure/parsers.py
  mercurial/revlogutils/revlogv0.py
  rust/hg-cpython/src/cindex.rs
  rust/hg-cpython/src/revlog.rs

CHANGE DETAILS




To: marmoute, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/rust/hg-cpython/src/revlog.rs b/rust/hg-cpython/src/revlog.rs
--- a/rust/hg-cpython/src/revlog.rs
+++ b/rust/hg-cpython/src/revlog.rs
@@ -300,6 +300,11 @@ 
         self.cindex(py).borrow().inner().getattr(py, "entry_size")?.extract::<PyInt>(py)
     }
 
+    @property
+    def rust_ext_compat(&self) -> PyResult<PyInt> {
+        self.cindex(py).borrow().inner().getattr(py, "rust_ext_compat")?.extract::<PyInt>(py)
+    }
+
 });
 
 impl MixedIndex {
diff --git a/rust/hg-cpython/src/cindex.rs b/rust/hg-cpython/src/cindex.rs
--- a/rust/hg-cpython/src/cindex.rs
+++ b/rust/hg-cpython/src/cindex.rs
@@ -11,8 +11,8 @@ 
 //! but this will take some time to get there.
 
 use cpython::{
-    exc::ImportError, ObjectProtocol, PyClone, PyErr, PyObject, PyResult,
-    PyTuple, Python, PythonObject,
+    exc::ImportError, exc::TypeError, ObjectProtocol, PyClone, PyErr,
+    PyObject, PyResult, PyTuple, Python, PythonObject,
 };
 use hg::revlog::{Node, RevlogIndex};
 use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION};
@@ -90,6 +90,13 @@ 
                 ),
             ));
         }
+        let compat: u64 = index.getattr(py, "rust_ext_compat")?.extract(py)?;
+        if compat == 0 {
+            return Err(PyErr::new::<TypeError, _>(
+                py,
+                "index object not compatible with Rust",
+            ));
+        }
         Ok(Index { index, capi })
     }
 
diff --git a/mercurial/revlogutils/revlogv0.py b/mercurial/revlogutils/revlogv0.py
--- a/mercurial/revlogutils/revlogv0.py
+++ b/mercurial/revlogutils/revlogv0.py
@@ -42,6 +42,7 @@ 
 
 
 class revlogoldindex(list):
+    rust_ext_compat = 0
     entry_size = INDEX_ENTRY_V0.size
     null_item = (
         0,
diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -47,6 +47,8 @@ 
 
 
 class BaseIndexObject(object):
+    # Can I be passed to an algorithme implemented in Rust ?
+    rust_ext_compat = 0
     # Format of an index entry according to Python's `struct` language
     index_format = revlog_constants.INDEX_ENTRY_V1
     # Size of a C unsigned long long int, platform independent
diff --git a/mercurial/policy.py b/mercurial/policy.py
--- a/mercurial/policy.py
+++ b/mercurial/policy.py
@@ -80,7 +80,7 @@ 
     ('cext', 'bdiff'): 3,
     ('cext', 'mpatch'): 1,
     ('cext', 'osutil'): 4,
-    ('cext', 'parsers'): 19,
+    ('cext', 'parsers'): 20,
 }
 
 # map import request to other package or module
diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c
--- a/mercurial/cext/revlog.c
+++ b/mercurial/cext/revlog.c
@@ -101,8 +101,10 @@ 
 	int inlined;
 	long entry_size; /* size of index headers. Differs in v1 v.s. v2 format
 	                  */
-	char format_version; /* size of index headers. Differs in v1 v.s. v2
-	                        format */
+	long rust_ext_compat; /* compatibility with being used in rust
+	                         extensions */
+	char format_version;  /* size of index headers. Differs in v1 v.s. v2
+	                         format */
 };
 
 static Py_ssize_t index_length(const indexObject *self)
@@ -2769,6 +2771,7 @@ 
 	self->offsets = NULL;
 	self->nodelen = 20;
 	self->nullentry = NULL;
+	self->rust_ext_compat = 1;
 
 	revlogv2 = NULL;
 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", kwlist,
@@ -2941,6 +2944,8 @@ 
 static PyMemberDef index_members[] = {
     {"entry_size", T_LONG, offsetof(indexObject, entry_size), 0,
      "size of an index entry"},
+    {"rust_ext_compat", T_LONG, offsetof(indexObject, rust_ext_compat), 0,
+     "size of an index entry"},
     {NULL} /* Sentinel */
 };
 
diff --git a/mercurial/cext/parsers.c b/mercurial/cext/parsers.c
--- a/mercurial/cext/parsers.c
+++ b/mercurial/cext/parsers.c
@@ -668,7 +668,7 @@ 
 void manifest_module_init(PyObject *mod);
 void revlog_module_init(PyObject *mod);
 
-static const int version = 19;
+static const int version = 20;
 
 static void module_init(PyObject *mod)
 {