peerdb/tripe-newpeers.in (MyConfigParser._get): Automate path maintenance.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 26 May 2018 11:01:29 +0000 (12:01 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 14 Jun 2018 11:50:37 +0000 (12:50 +0100)
Rather than having lots of `path.pop()' calls, and hoping that
everything balances, wrap `try ... finally ...' around the method body.
Remove the explicit poppings, and simplify.

We still need to copy the path if we find a local result or raise an
exception.

peerdb/tripe-newpeers.in

index c6bf723..09df754 100644 (file)
@@ -226,58 +226,64 @@ class MyConfigParser (CP.RawConfigParser):
     if map is None: map = {}
     if path is None: path = []
 
-    ## If we've been this way before on another pass through then return the
-    ## value we found then.  If we're still thinking about it then we've
-    ## found a cycle.
+    ## Extend the path to cover the lookup section, but remember to remove us
+    ## again when we've finished.  If we need to pass the current path back
+    ## upwards, then remember to take a copy.
     path.append(sec)
     try:
-      threadp, value = map[sec]
-    except KeyError:
-      pass
-    else:
-      if threadp:
-        raise InheritanceCycleError(key, path)
 
-    ## See whether the answer is ready waiting for us.
-    try:
-      v = CP.RawConfigParser.get(me, sec, key)
-    except CP.NoOptionError:
-      pass
-    else:
-      p = path[:]
+      ## If we've been this way before on another pass through then return
+      ## the value we found then.  If we're still thinking about it then
+      ## we've found a cycle.
+      try:
+        threadp, value = map[sec]
+      except KeyError:
+        pass
+      else:
+        if threadp:
+          raise InheritanceCycleError(key, path[:])
+
+      ## See whether the answer is ready waiting for us.
+      try:
+        v = CP.RawConfigParser.get(me, sec, key)
+      except CP.NoOptionError:
+        pass
+      else:
+        return v, path[:]
+
+      ## No, apparently, not.  Find out our list of parents.
+      try:
+        parents = CP.RawConfigParser.get(me, sec, '@inherit').\
+            replace(',', ' ').split()
+      except CP.NoOptionError:
+        parents = []
+
+      ## Initially we have no idea.
+      value = None
+      winner = None
+
+      ## Go through our parents and ask them what they think.
+      map[sec] = True, None
+      for p in parents:
+
+        ## See whether we get an answer.  If not, keep on going.
+        v, pp = me._get(p, key, map, path)
+        if v is None: continue
+
+        ## If we got an answer, check that it matches any previous ones.
+        if value is None:
+          value = v
+          winner = pp
+        elif value != v:
+          raise AmbiguousOptionError(key, winner, value, pp, v)
+
+      ## That's the best we could manage.
+      map[sec] = False, value
+      return value, winner
+
+    finally:
+      ## Remove us from the path again.
       path.pop()
-      return v, p
-
-    ## No, apparently, not.  Find out our list of parents.
-    try:
-      parents = CP.RawConfigParser.get(me, sec, '@inherit').\
-          replace(',', ' ').split()
-    except CP.NoOptionError:
-      parents = []
-
-    ## Initially we have no idea.
-    value = None
-    winner = None
-
-    ## Go through our parents and ask them what they think.
-    map[sec] = True, None
-    for p in parents:
-
-      ## See whether we get an answer.  If not, keep on going.
-      v, pp = me._get(p, key, map, path)
-      if v is None: continue
-
-      ## If we got an answer, check that it matches any previous ones.
-      if value is None:
-        value = v
-        winner = pp
-      elif value != v:
-        raise AmbiguousOptionError(key, winner, value, pp, v)
-
-    ## That's the best we could manage.
-    path.pop()
-    map[sec] = False, value
-    return value, winner
 
   def get(me, sec, key, resolvep = True):
     """