Przeglądaj źródła

Split out exception for symbolic reference loops.

Jelmer Vernooij 2 lat temu
rodzic
commit
054a172b95
3 zmienionych plików z 20 dodań i 3 usunięć
  1. 8 0
      NEWS
  2. 10 2
      dulwich/refs.py
  3. 2 1
      dulwich/tests/test_refs.py

+ 8 - 0
NEWS

@@ -1,5 +1,9 @@
 0.20.46	UNRELEASED
 
+ * Add a separate Exception for symbolic
+   reference loops - dulwich.refs.SymrefLoop.
+   (Jelmer Vernooij)
+
 0.20.45	2022-07-15
 
  * Add basic ``dulwich.porcelain.submodule_list`` and ``dulwich.porcelain.submodule_add``
@@ -66,6 +70,10 @@
    (Filipp Frizzy)
 
 0.20.35	2022-03-20
+<<<<<<< Updated upstream
+=======
+>>>>>>> Stashed changes
+>>>>>>> Stashed changes
 
  * Document the ``path`` attribute for ``Repo``.
    (Jelmer Vernooij, #854)

+ 10 - 2
dulwich/refs.py

@@ -49,6 +49,14 @@ BAD_REF_CHARS = set(b"\177 ~^:?*[")
 ANNOTATED_TAG_SUFFIX = b"^{}"
 
 
+class SymrefLoop(Exception):
+    """There is a loop between one or more symrefs."""
+
+    def __init__(self, ref, depth):
+        self.ref = ref
+        self.depth = depth
+
+
 def parse_symref_value(contents):
     """Parse a symref value.
 
@@ -231,7 +239,7 @@ class RefsContainer(object):
         for key in keys:
             try:
                 ret[key] = self[(base + b"/" + key).strip(b"/")]
-            except KeyError:
+            except SymrefLoop:
                 continue  # Unable to resolve
 
         return ret
@@ -294,7 +302,7 @@ class RefsContainer(object):
                 break
             depth += 1
             if depth > 5:
-                raise KeyError(name)
+                raise SymrefLoop(name, depth)
         return refnames, contents
 
     def _follow(self, name):

+ 2 - 1
dulwich/tests/test_refs.py

@@ -34,6 +34,7 @@ from dulwich.objects import ZERO_SHA
 from dulwich.refs import (
     DictRefsContainer,
     InfoRefsContainer,
+    SymrefLoop,
     check_ref_format,
     _split_ref_line,
     parse_symref_value,
@@ -518,7 +519,7 @@ class DiskRefsContainerTests(RefsContainerTests, TestCase):
             ),
             self._refs.follow(b"refs/heads/master"),
         )
-        self.assertRaises(KeyError, self._refs.follow, b"refs/heads/loop")
+        self.assertRaises(SymrefLoop, self._refs.follow, b"refs/heads/loop")
 
     def test_delitem(self):
         RefsContainerTests.test_delitem(self)