revlog: signal which revlog index are compatible with Rust
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.
Differential Revision: https://phab.mercurial-scm.org/D10665
--- a/mercurial/cext/parsers.c Tue May 04 11:19:48 2021 +0200
+++ b/mercurial/cext/parsers.c Tue May 04 14:16:26 2021 +0200
@@ -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)
{
--- a/mercurial/cext/revlog.c Tue May 04 11:19:48 2021 +0200
+++ b/mercurial/cext/revlog.c Tue May 04 14:16:26 2021 +0200
@@ -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 */
};
--- a/mercurial/policy.py Tue May 04 11:19:48 2021 +0200
+++ b/mercurial/policy.py Tue May 04 14:16:26 2021 +0200
@@ -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
--- a/mercurial/pure/parsers.py Tue May 04 11:19:48 2021 +0200
+++ b/mercurial/pure/parsers.py Tue May 04 14:16:26 2021 +0200
@@ -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
--- a/mercurial/revlogutils/revlogv0.py Tue May 04 11:19:48 2021 +0200
+++ b/mercurial/revlogutils/revlogv0.py Tue May 04 14:16:26 2021 +0200
@@ -42,6 +42,7 @@
class revlogoldindex(list):
+ rust_ext_compat = 0
entry_size = INDEX_ENTRY_V0.size
null_item = (
0,
--- a/rust/hg-cpython/src/cindex.rs Tue May 04 11:19:48 2021 +0200
+++ b/rust/hg-cpython/src/cindex.rs Tue May 04 14:16:26 2021 +0200
@@ -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 })
}
--- a/rust/hg-cpython/src/revlog.rs Tue May 04 11:19:48 2021 +0200
+++ b/rust/hg-cpython/src/revlog.rs Tue May 04 14:16:26 2021 +0200
@@ -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 {