diff --git a/mercurial/changelog.py b/mercurial/changelog.py --- a/mercurial/changelog.py +++ b/mercurial/changelog.py @@ -556,8 +556,8 @@ if revs is not None: if revs: assert revs[-1] + 1 == rev - revs = pycompat.xrange(revs[0], rev + 1) + revs = pycompat.membershiprange(revs[0], rev + 1) else: - revs = pycompat.xrange(rev, rev + 1) + revs = pycompat.membershiprange(rev, rev + 1) transaction.changes['revs'] = revs return node diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py --- a/mercurial/pycompat.py +++ b/mercurial/pycompat.py @@ -278,6 +278,7 @@ hasattr = _wrapattrfunc(builtins.hasattr) setattr = _wrapattrfunc(builtins.setattr) xrange = builtins.range + membershiprange = builtins.range unicode = str def open(name, mode='r', buffering=-1, encoding=None): @@ -343,6 +344,25 @@ strurl = identity bytesurl = identity + class membershiprange(object): + "Like xrange(a,b) but with constant-time membership test" + def __init__(self, a, b): + self._range = xrange(a, b) + def __getitem__(self, n): + return self._range[n] + def __hash__(self): + return hash(self._range) + def __iter__(self): + return iter(self._range) + def __len__(self): + return len(self._range) + def __reversed__(self): + return reversed(self._range) + def __contains__(self, n): + if not self._range: + return False + return n >= self._range[0] and n <= self._range[-1] + # this can't be parsed on Python 3 exec('def raisewithtb(exc, tb):\n' ' raise exc, None, tb\n')