X-Git-Url: https://arthur.barton.de/gitweb/?a=blobdiff_plain;f=lib%2Fbup%2Findex.py;h=b9a4013be032bfd75d68e350250a43d4b9571d85;hb=f26a6a9ec9d7179c440c2486fe6fd7459c43bda3;hp=2e7e5eca7a9e2c3f043423c8f0cbc296d51191ea;hpb=aac44c48f74679f9f14cd1e98b7e117fe8a61de0;p=bup.git diff --git a/lib/bup/index.py b/lib/bup/index.py index 2e7e5ec..b9a4013 100644 --- a/lib/bup/index.py +++ b/lib/bup/index.py @@ -2,17 +2,12 @@ from __future__ import absolute_import, print_function import errno, os, stat, struct, tempfile -from bup import compat, metadata, xstat +from bup import metadata, xstat from bup._helpers import UINT_MAX, bytescmp -from bup.compat import range +from bup.compat import pending_raise, range from bup.helpers import (add_error, log, merge_iter, mmap_readwrite, progress, qprogress, resolve_parent, slashappend) -if compat.py_maj > 2: - from bup.compat import buffer - -import sys - EMPTY_SHA = b'\0' * 20 FAKE_SHA = b'\x01' * 20 @@ -63,8 +58,12 @@ class MetaStoreReader: self._file.close() self._file = None - def __del__(self): - self.close() + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + with pending_raise(value, rethrow=True): + self.close() def metadata_at(self, ofs): self._file.seek(ofs) @@ -95,7 +94,7 @@ class MetaStoreWriter: except EOFError: pass except: - log('index metadata in %r appears to be corrupt' % filename) + log('index metadata in %r appears to be corrupt\n' % filename) raise finally: m_file.close() @@ -106,9 +105,12 @@ class MetaStoreWriter: self._file.close() self._file = None - def __del__(self): - # Be optimistic. - self.close() + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + with pending_raise(value, rethrow=False): + self.close() def store(self, metadata): meta_encoded = metadata.encode(include_path=False) @@ -132,7 +134,7 @@ class Level: (ofs,n) = (f.tell(), len(self.list)) if self.list: count = len(self.list) - #log('popping %r with %d entries\n' + #log('popping %r with %d entries\n' # % (''.join(self.ename), count)) for e in self.list: e.write(f) @@ -170,8 +172,8 @@ def _golevel(level, f, ename, newentry, metastore, tmax): class Entry: def __init__(self, basename, name, meta_ofs, tmax): - assert basename is None or type(basename) == bytes - assert name is None or type(name) == bytes + assert basename is None or isinstance(basename, bytes) + assert name is None or isinstance(name, bytes) self.basename = basename self.name = name self.meta_ofs = meta_ofs @@ -205,7 +207,7 @@ class Entry: log('pack error: %s (%r)\n' % (e, self)) raise - def stale(self, st, tstart, check_device=True): + def stale(self, st, check_device=True): if self.size != st.st_size: return True if self.mtime != st.st_mtime: @@ -224,10 +226,6 @@ class Entry: return True if check_device and (self.dev != st.st_dev): return True - # Check that the ctime's "second" is at or after tstart's. - ctime_sec_in_ns = xstat.fstime_floor_secs(st.st_ctime) * 10**9 - if ctime_sec_in_ns >= tstart: - return True return False def update_from_stat(self, st, meta_ofs): @@ -305,7 +303,7 @@ class Entry: def __eq__(self, other): return self._cmp(other) == 0 - def __ne__(): + def __ne__(self, other): return self._cmp(other) != 0 def __lt__(self, other): @@ -314,10 +312,10 @@ class Entry: def __gt__(self, other): return self._cmp(other) > 0 - def __le__(): + def __le__(self, other): return self._cmp(other) <= 0 - def __ge__(): + def __ge__(self, other): return self._cmp(other) >= 0 def write(self, f): @@ -411,7 +409,7 @@ class ExistingEntry(Entry): def __iter__(self): return self.iter() - + class Reader: def __init__(self, filename): @@ -441,8 +439,12 @@ class Reader: self.m[st.st_size - FOOTLEN : st.st_size])[0] - def __del__(self): - self.close() + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + with pending_raise(value, rethrow=False): + self.close() def __len__(self): return int(self.count) @@ -535,8 +537,12 @@ class Writer: self.f = os.fdopen(ffd, 'wb', 65536) self.f.write(INDEX_HDR) - def __del__(self): - self.abort() + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + with pending_raise(value, rethrow=False): + self.abort() def abort(self): f = self.f @@ -566,7 +572,7 @@ class Writer: def _add(self, ename, entry): if self.lastfile and self.lastfile <= ename: - raise Error('%r must come before %r' + raise Error('%r must come before %r' % (''.join(ename), ''.join(self.lastfile))) self.lastfile = ename self.level = _golevel(self.level, self.f, ename, entry, @@ -643,7 +649,7 @@ def reduce_paths(paths): paths = [] prev = None for (rp, p) in xpaths: - if prev and (prev == rp + if prev and (prev == rp or (prev.endswith(b'/') and rp.startswith(prev))): continue # already superceded by previous path paths.append((rp, p))