Browse Source

Add a dedicated exception for UnresolvedDeltas

Fixes #1221
Jelmer Vernooij 1 year ago
parent
commit
c9726cdafa
3 changed files with 18 additions and 7 deletions
  1. 3 0
      NEWS
  2. 9 2
      dulwich/pack.py
  3. 6 5
      dulwich/tests/test_pack.py

+ 3 - 0
NEWS

@@ -6,6 +6,9 @@
  * Raise exception when default identity can't be found.
    (Jelmer Vernooij)
 
+ * Add a dedicated exception class for unresolved
+   deltas. (Jelmer Vernooij, #1221)
+
 0.21.6	2023-09-02
 
  * index: Handle different stages of conflicted paths.

+ 9 - 2
dulwich/pack.py

@@ -108,6 +108,13 @@ ProgressFn = Callable[[int, str], None]
 PackHint = Tuple[int, Optional[bytes]]
 
 
+class UnresolvedDeltas(Exception):
+    """"Delta objects could not be resolved."""
+
+    def __init__(self, shas):
+        self.shas = shas
+
+
 class ObjectContainer(Protocol):
 
     def add_object(self, obj: ShaFile) -> None:
@@ -1443,7 +1450,7 @@ class DeltaChainIterator(Generic[T]):
 
     def _ensure_no_pending(self) -> None:
         if self._pending_ref:
-            raise KeyError([sha_to_hex(s) for s in self._pending_ref])
+            raise UnresolvedDeltas([sha_to_hex(s) for s in self._pending_ref])
 
     def _walk_ref_chains(self):
         if not self._resolve_ext_ref:
@@ -2442,7 +2449,7 @@ class Pack:
                 yield child
         assert not ofs_pending
         if not allow_missing and todo:
-            raise KeyError(todo.pop())
+            raise UnresolvedDeltas(todo)
 
     def iter_unpacked(self, include_comp=False):
         ofs_to_entries = {ofs: (sha, crc32) for (sha, ofs, crc32) in self.index.iterentries()}

+ 6 - 5
dulwich/tests/test_pack.py

@@ -46,6 +46,7 @@ from ..pack import (
     PackData,
     PackStreamReader,
     UnpackedObject,
+    UnresolvedDeltas,
     _delta_encode_size,
     _encode_copy_operation,
     apply_delta,
@@ -592,7 +593,7 @@ class TestThinPack(PackTests):
 
     def test_iterobjects(self):
         with self.make_pack(False) as p:
-            self.assertRaises(KeyError, list, p.iterobjects())
+            self.assertRaises(UnresolvedDeltas, list, p.iterobjects())
         with self.make_pack(True) as p:
             self.assertEqual(
                 sorted(
@@ -1216,8 +1217,8 @@ class DeltaChainIteratorTests(TestCase):
         try:
             list(pack_iter._walk_all_chains())
             self.fail()
-        except KeyError as e:
-            self.assertEqual(([blob.id],), e.args)
+        except UnresolvedDeltas as e:
+            self.assertEqual([blob.id], e.shas)
 
     def test_bad_ext_ref_thin_pack(self):
         b1, b2, b3 = self.store_blobs([b"foo", b"bar", b"baz"])
@@ -1238,8 +1239,8 @@ class DeltaChainIteratorTests(TestCase):
         try:
             list(pack_iter._walk_all_chains())
             self.fail()
-        except KeyError as e:
-            self.assertEqual((sorted([b2.id, b3.id]),), (sorted(e.args[0]),))
+        except UnresolvedDeltas as e:
+            self.assertEqual((sorted([b2.id, b3.id]),), (sorted(e.shas),))
 
 
 class DeltaEncodeSizeTests(TestCase):