]> arthur.barton.de Git - bup.git/blobdiff - lib/bup/vfs.py
fix unfinished read on tag commits found in vfs cache
[bup.git] / lib / bup / vfs.py
index 09267f4c3e634fa1cf511cdb80cb2c8b6112adb1..541a28f3b4849a8741c1ede4cd0a992731a19b83 100644 (file)
@@ -57,9 +57,9 @@ from time import localtime, strftime
 import re, sys
 
 from bup import git, vint
-from bup.compat import hexstr, range, str_type
+from bup.compat import hexstr, pending_raise
 from bup.git import BUP_CHUNKED, parse_commit, tree_decode
-from bup.helpers import debug2, last
+from bup.helpers import debug2, last, nullcontext_if_not
 from bup.io import path_msg
 from bup.metadata import Metadata
 from bup.vint import read_bvec, write_bvec
@@ -195,6 +195,7 @@ class _ChunkReader:
 class _FileReader(object):
     def __init__(self, repo, oid, known_size=None):
         assert len(oid) == 20
+        self.closed = False
         self.oid = oid
         self.ofs = 0
         self.reader = None
@@ -231,13 +232,17 @@ class _FileReader(object):
         return buf
 
     def close(self):
-        pass
+        self.closed = True
+
+    def __del__(self):
+        assert self.closed
 
     def __enter__(self):
         return self
+
     def __exit__(self, type, value, traceback):
-        self.close()
-        return False
+        with pending_raise(value, rethrow=False):
+            self.close()
 
 _multiple_slashes_rx = re.compile(br'//+')
 
@@ -714,8 +719,9 @@ def tree_items_with_meta(repo, oid, tree_data, names):
             break
         if mangled_name > b'.bupm':
             break
-    for item in tree_items(oid, tree_data, names, bupm):
-        yield item
+    with nullcontext_if_not(bupm):
+        for item in tree_items(oid, tree_data, names, bupm):
+            yield item
 
 _save_name_rx = re.compile(br'^\d\d\d\d-\d\d-\d\d-\d{6}(-\d+)?$')
 
@@ -823,12 +829,14 @@ def tags_items(repo, names):
 
     def tag_item(oid):
         assert len(oid) == 20
+        cached = cache_get_commit_item(oid, need_meta=False)
+        if cached:
+            return cached
         oidx = hexlify(oid)
         it = repo.cat(oidx)
         _, typ, size = next(it)
         if typ == b'commit':
-            return cache_get_commit_item(oid, need_meta=False) \
-                or _commit_item_from_data(oid, b''.join(it))
+            return _commit_item_from_data(oid, b''.join(it))
         for _ in it: pass
         if typ == b'blob':
             return Item(meta=default_file_mode, oid=oid)
@@ -945,7 +953,7 @@ def _resolve_path(repo, path, parent=None, want_meta=True, follow=True):
     if parent:
         for x in parent:
             assert len(x) == 2
-            assert isinstance(x[0], (bytes, str_type))
+            assert isinstance(x[0], (bytes, str))
             assert isinstance(x[1], item_types)
         assert parent[0][1] == _root
         if not S_ISDIR(item_mode(parent[-1][1])):