diff --git a/mercurial/changelog.py b/mercurial/changelog.py --- a/mercurial/changelog.py +++ b/mercurial/changelog.py @@ -448,6 +448,7 @@ class changelog(revlog.revlog): def delayupdate(self, tr): """delay visibility of index updates to other readers""" + assert not self._inner.is_open if self._docket is None and not self._delayed: if len(self) == 0: self._divert = True @@ -468,6 +469,7 @@ class changelog(revlog.revlog): def _finalize(self, tr): """finalize index updates""" + assert not self._inner.is_open self._delayed = False self.opener = self._realopener self._inner.opener = self.opener @@ -494,6 +496,7 @@ class changelog(revlog.revlog): def _writepending(self, tr): """create a file containing the unfinalized state for pretxnchangegroup""" + assert not self._inner.is_open if self._docket: return self._docket.write(tr, pending=True) if self._delaybuf: diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -620,6 +620,13 @@ class _InnerRevlog: """True is a writing context is open""" return self._writinghandles is not None + @property + def is_open(self): + """True if any file handle is being held + + Used for assert and debug in the python code""" + return self._segmentfile.is_open or self._segmentfile_sidedata.is_open + @contextlib.contextmanager def writing(self, transaction, data_end=None, sidedata_end=None): """Open the revlog files for writing diff --git a/mercurial/revlogutils/randomaccessfile.py b/mercurial/revlogutils/randomaccessfile.py --- a/mercurial/revlogutils/randomaccessfile.py +++ b/mercurial/revlogutils/randomaccessfile.py @@ -50,6 +50,15 @@ class randomaccessfile: self._cached_chunk = b'' self._cached_chunk_position = 0 + @property + def is_open(self): + """True if any file handle is being held + + Used for assert and debug in the python code""" + return ( + self.reading_handle is not None or self.writing_handle is not None + ) + def _open(self, mode=b'r'): """Return a file object""" return self.opener(self.filename, mode=mode)