diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py --- a/mercurial/pure/parsers.py +++ b/mercurial/pure/parsers.py @@ -11,6 +11,7 @@ import zlib from ..node import nullid +from ..thirdparty import attr from .. import pycompat stringio = pycompat.stringio @@ -37,13 +38,49 @@ def offset_type(offset, type): return int(int(offset) << 16 | type) +@attr.s +class IndexV1Entry(object): + """Represents a revlog v1 index entry.""" + offsetflags = attr.ib() + chunklength = attr.ib() + rawlength = attr.ib() + baserev = attr.ib() + linkrev = attr.ib() + p1rev = attr.ib() + p2rev = attr.ib() + node = attr.ib() + + def __getitem__(self, x): + if x == 0: + return self.offsetflags + elif x == 1: + return self.chunklength + elif x == 2: + return self.rawlength + elif x == 3: + return self.baserev + elif x == 4: + return self.linkrev + elif x == 5: + return self.p1rev + elif x == 6: + return self.p2rev + elif x == 7: + return self.node + else: + raise IndexError('index out of range') + class BaseIndexObject(object): def __len__(self): return self._lgt + len(self._extra) + 1 - def insert(self, i, tup): + def insert(self, i, entry): assert i == -1 - self._extra.append(tup) + + if isinstance(entry, tuple): + entry = IndexV1Entry(*entry) + + self._extra.append(entry) def _fix_index(self, i): if not isinstance(i, int): @@ -57,7 +94,7 @@ def __getitem__(self, i): i = self._fix_index(i) if i == len(self) - 1: - return (0, 0, 0, -1, -1, -1, -1, nullid) + return IndexV1Entry(0, 0, 0, -1, -1, -1, -1, nullid) if i >= self._lgt: return self._extra[i - self._lgt] index = self._calculate_index(i) @@ -66,8 +103,8 @@ e = list(r) type = gettype(e[0]) e[0] = offset_type(0, type) - return tuple(e) - return r + return IndexV1Entry(*e) + return IndexV1Entry(*r) class IndexObject(BaseIndexObject): def __init__(self, data): diff --git a/tests/test-parseindex2.py b/tests/test-parseindex2.py --- a/tests/test-parseindex2.py +++ b/tests/test-parseindex2.py @@ -13,6 +13,10 @@ nullid, nullrev, ) +# no-check-code +from mercurial.pure import ( + parsers as pureparsers, +) from mercurial import ( policy, ) @@ -165,6 +169,21 @@ testversionfail(4, makehex(major, minor + 1, micro)) testversionfail(5, "'foo'") +def index_equal(a, b): + """Determine if 2 index objects are equal.""" + # Normalize all entries to IndexV1Entry instances. + def normvalue(x): + if isinstance(x, pureparsers.IndexV1Entry): + return x + + assert isinstance(x, tuple) + return pureparsers.IndexV1Entry(*x) + + idxa = list(map(normvalue, a[0])) + idxb = list(map(normvalue, b[0])) + + return (idxa, a[1]) == (idxb, b[1]) + def runtest() : # Only test the version-detection logic if it is present. try: @@ -191,10 +210,10 @@ py_res_2 = py_parseindex(data_non_inlined, False) c_res_2 = parse_index2(data_non_inlined, False) - if py_res_1 != c_res_1: + if not index_equal(py_res_1, c_res_1): print("Parse index result (with inlined data) differs!") - if py_res_2 != c_res_2: + if not index_equal(py_res_2, c_res_2): print("Parse index result (no inlined data) differs!") ix = parsers.parse_index2(data_inlined, True)[0]