From f26a6a9ec9d7179c440c2486fe6fd7459c43bda3 Mon Sep 17 00:00:00 2001 From: Rob Browning Date: Mon, 27 Sep 2021 20:28:53 -0500 Subject: [PATCH] index.Writer.__del__: replace with context management Signed-off-by: Rob Browning Tested-by: Rob Browning --- lib/bup/cmd/index.py | 23 +++---- lib/bup/index.py | 8 ++- test/int/test_index.py | 140 +++++++++++++++++++++-------------------- 3 files changed, 87 insertions(+), 84 deletions(-) diff --git a/lib/bup/cmd/index.py b/lib/bup/cmd/index.py index cc542e6..9bc4f2a 100755 --- a/lib/bup/cmd/index.py +++ b/lib/bup/cmd/index.py @@ -76,10 +76,10 @@ def update_index(top, excluded_paths, exclude_rxs, indexfile, with index.MetaStoreWriter(indexfile + b'.meta') as msw, \ hlinkdb.HLinkDB(indexfile + b'.hlink') as hlinks, \ + index.Writer(indexfile, msw, tmax) as wi, \ index.Reader(indexfile) as ri: rig = IterHelper(ri.iter(name=top)) - wi = index.Writer(indexfile, msw, tmax) fake_hash = None if fake_valid: @@ -176,7 +176,9 @@ def update_index(top, excluded_paths, exclude_rxs, indexfile, hlinks.prepare_save() - if ri.exists(): + if not ri.exists(): + wi.close() + else: ri.save() wi.flush() if wi.count: @@ -186,17 +188,12 @@ def update_index(top, excluded_paths, exclude_rxs, indexfile, check_index(ri, verbose) log('check: before merging: newfile\n') check_index(wr, verbose) - mi = index.Writer(indexfile, msw, tmax) - - for e in index.merge(ri, wr): - # FIXME: shouldn't we remove deleted entries - # eventually? When? - mi.add_ixentry(e) - - mi.close() - wi.abort() - else: - wi.close() + with index.Writer(indexfile, msw, tmax) as mi: + for e in index.merge(ri, wr): + # FIXME: shouldn't we remove deleted entries + # eventually? When? + mi.add_ixentry(e) + mi.close() hlinks.commit_save() diff --git a/lib/bup/index.py b/lib/bup/index.py index e7214d1..b9a4013 100644 --- a/lib/bup/index.py +++ b/lib/bup/index.py @@ -537,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 diff --git a/test/int/test_index.py b/test/int/test_index.py index 6d97127..51eab85 100644 --- a/test/int/test_index.py +++ b/test/int/test_index.py @@ -31,14 +31,14 @@ def test_index_writer(tmpdir): os.chdir(tmpdir) ds = xstat.stat(b'.') fs = xstat.stat(lib_t_dir + b'/test_index.py') - with index.MetaStoreWriter(b'index.meta.tmp') as ms: - tmax = (time.time() - 1) * 10**9 - w = index.Writer(b'index.tmp', ms, tmax) + tmax = (time.time() - 1) * 10**9 + with index.MetaStoreWriter(b'index.meta.tmp') as ms, \ + index.Writer(b'index.tmp', ms, tmax) as w: w.add(b'/var/tmp/sporky', fs, 0) w.add(b'/etc/passwd', fs, 0) w.add(b'/etc/', ds, 0) w.add(b'/', ds, 0) - w.close() + w.close() finally: os.chdir(orig_cwd) @@ -100,72 +100,74 @@ def test_index_dirty(tmpdir): fs = xstat.stat(lib_t_dir + b'/test_index.py') tmax = (time.time() - 1) * 10**9 - w1 = index.Writer(b'index.tmp', ms1, tmax) - w1.add(b'/a/b/x', fs, meta_ofs1) - w1.add(b'/a/b/c', fs, meta_ofs1) - w1.add(b'/a/b/', ds, meta_ofs1) - w1.add(b'/a/', ds, meta_ofs1) - #w1.close() - WVPASS() - - w2 = index.Writer(b'index2.tmp', ms2, tmax) - w2.add(b'/a/b/n/2', fs, meta_ofs2) - #w2.close() - WVPASS() - - w3 = index.Writer(b'index3.tmp', ms3, tmax) - w3.add(b'/a/c/n/3', fs, meta_ofs3) - #w3.close() - WVPASS() - - with w1.new_reader() as r1, \ - w2.new_reader() as r2, \ - w3.new_reader() as r3: + with index.Writer(b'index.tmp', ms1, tmax) as w1, \ + index.Writer(b'index2.tmp', ms2, tmax) as w2, \ + index.Writer(b'index3.tmp', ms3, tmax) as w3: + + w1.add(b'/a/b/x', fs, meta_ofs1) + w1.add(b'/a/b/c', fs, meta_ofs1) + w1.add(b'/a/b/', ds, meta_ofs1) + w1.add(b'/a/', ds, meta_ofs1) + #w1.close() + WVPASS() + + w2 = index.Writer(b'index2.tmp', ms2, tmax) + w2.add(b'/a/b/n/2', fs, meta_ofs2) + #w2.close() + WVPASS() + + w3.add(b'/a/c/n/3', fs, meta_ofs3) + #w3.close() WVPASS() - r1all = [e.name for e in r1] - WVPASSEQ(r1all, - [b'/a/b/x', b'/a/b/c', b'/a/b/', b'/a/', b'/']) - r2all = [e.name for e in r2] - WVPASSEQ(r2all, - [b'/a/b/n/2', b'/a/b/n/', b'/a/b/', b'/a/', b'/']) - r3all = [e.name for e in r3] - WVPASSEQ(r3all, - [b'/a/c/n/3', b'/a/c/n/', b'/a/c/', b'/a/', b'/']) - all = [e.name for e in index.merge(r2, r1, r3)] - WVPASSEQ(all, - [b'/a/c/n/3', b'/a/c/n/', b'/a/c/', - b'/a/b/x', b'/a/b/n/2', b'/a/b/n/', b'/a/b/c', - b'/a/b/', b'/a/', b'/']) - fake_validate(r1) - dump(r1) - - print([hex(e.flags) for e in r1]) - WVPASSEQ([e.name for e in r1 if e.is_valid()], r1all) - WVPASSEQ([e.name for e in r1 if not e.is_valid()], []) - WVPASSEQ([e.name for e in index.merge(r2, r1, r3) if not e.is_valid()], - [b'/a/c/n/3', b'/a/c/n/', b'/a/c/', - b'/a/b/n/2', b'/a/b/n/', b'/a/b/', b'/a/', b'/']) - - expect_invalid = [b'/'] + r2all + r3all - expect_real = (set(r1all) - set(r2all) - set(r3all)) \ - | set([b'/a/b/n/2', b'/a/c/n/3']) - dump(index.merge(r2, r1, r3)) - for e in index.merge(r2, r1, r3): - print(e.name, hex(e.flags), e.ctime) - eiv = e.name in expect_invalid - er = e.name in expect_real - WVPASSEQ(eiv, not e.is_valid()) - WVPASSEQ(er, e.is_real()) - fake_validate(r2, r3) - dump(index.merge(r2, r1, r3)) - WVPASSEQ([e.name for e in index.merge(r2, r1, r3) if not e.is_valid()], []) - - e = eget(index.merge(r2, r1, r3), b'/a/b/c') - e.invalidate() - e.repack() - dump(index.merge(r2, r1, r3)) - WVPASSEQ([e.name for e in index.merge(r2, r1, r3) if not e.is_valid()], - [b'/a/b/c', b'/a/b/', b'/a/', b'/']) + with w1.new_reader() as r1, \ + w2.new_reader() as r2, \ + w3.new_reader() as r3: + WVPASS() + + r1all = [e.name for e in r1] + WVPASSEQ(r1all, + [b'/a/b/x', b'/a/b/c', b'/a/b/', b'/a/', b'/']) + r2all = [e.name for e in r2] + WVPASSEQ(r2all, + [b'/a/b/n/2', b'/a/b/n/', b'/a/b/', b'/a/', b'/']) + r3all = [e.name for e in r3] + WVPASSEQ(r3all, + [b'/a/c/n/3', b'/a/c/n/', b'/a/c/', b'/a/', b'/']) + all = [e.name for e in index.merge(r2, r1, r3)] + WVPASSEQ(all, + [b'/a/c/n/3', b'/a/c/n/', b'/a/c/', + b'/a/b/x', b'/a/b/n/2', b'/a/b/n/', b'/a/b/c', + b'/a/b/', b'/a/', b'/']) + fake_validate(r1) + dump(r1) + + print([hex(e.flags) for e in r1]) + WVPASSEQ([e.name for e in r1 if e.is_valid()], r1all) + WVPASSEQ([e.name for e in r1 if not e.is_valid()], []) + WVPASSEQ([e.name for e in index.merge(r2, r1, r3) if not e.is_valid()], + [b'/a/c/n/3', b'/a/c/n/', b'/a/c/', + b'/a/b/n/2', b'/a/b/n/', b'/a/b/', b'/a/', b'/']) + + expect_invalid = [b'/'] + r2all + r3all + expect_real = (set(r1all) - set(r2all) - set(r3all)) \ + | set([b'/a/b/n/2', b'/a/c/n/3']) + dump(index.merge(r2, r1, r3)) + for e in index.merge(r2, r1, r3): + print(e.name, hex(e.flags), e.ctime) + eiv = e.name in expect_invalid + er = e.name in expect_real + WVPASSEQ(eiv, not e.is_valid()) + WVPASSEQ(er, e.is_real()) + fake_validate(r2, r3) + dump(index.merge(r2, r1, r3)) + WVPASSEQ([e.name for e in index.merge(r2, r1, r3) if not e.is_valid()], []) + + e = eget(index.merge(r2, r1, r3), b'/a/b/c') + e.invalidate() + e.repack() + dump(index.merge(r2, r1, r3)) + WVPASSEQ([e.name for e in index.merge(r2, r1, r3) if not e.is_valid()], + [b'/a/b/c', b'/a/b/', b'/a/', b'/']) finally: os.chdir(orig_cwd) -- 2.39.2