[PATCH 18/23] index.Writer.__del__: replace with context management

0 views
Skip to first unread message

Rob Browning

unread,
Nov 13, 2021, 12:59:32 PM11/13/21
to bup-...@googlegroups.com, Bas Stottelaar
Signed-off-by: Rob Browning <r...@defaultvalue.org>
Tested-by: Rob Browning <r...@defaultvalue.org>
---
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 cc542e64..9bc4f2a5 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 e7214d1d..b9a4013b 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 6d97127c..51eab853 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.30.2

Reply all
Reply to author
Forward
0 new messages