Rev 2679: Fix KeyError in Graph.filter_candidate_lca corner case in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Tue Aug 7 21:01:12 BST 2007


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 2679
revision-id: pqm at pqm.ubuntu.com-20070807200109-d25wg4bqp97uo9d5
parent: pqm at pqm.ubuntu.com-20070807191900-kuqpkgh4sq9fczil
parent: abentley at panoramicfeedback.com-20070807183310-otmzbpy694aa75am
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2007-08-07 21:01:09 +0100
message:
  Fix KeyError in Graph.filter_candidate_lca corner case
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/graph.py                graph_walker.py-20070525030359-y852guab65d4wtn0-1
  bzrlib/tests/test_graph.py     test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
    ------------------------------------------------------------
    revno: 1551.2.49.1.40.1.22.1.42.1.31.1.39.1.17.1.82
    merged: abentley at panoramicfeedback.com-20070807183310-otmzbpy694aa75am
    parent: abentley at panoramicfeedback.com-20070807152626-hii4pfmff3ayxxp9
    committer: Aaron Bentley <abentley at panoramicfeedback.com>
    branch nick: Aaron's integration
    timestamp: Tue 2007-08-07 14:33:10 -0400
    message:
      Add symmetrical alternative to test case
    ------------------------------------------------------------
    revno: 1551.2.49.1.40.1.22.1.42.1.31.1.39.1.17.1.81
    merged: abentley at panoramicfeedback.com-20070807152626-hii4pfmff3ayxxp9
    parent: abentley at panoramicfeedback.com-20070807152033-tjdm70lytg1e1x1h
    committer: Aaron Bentley <abentley at panoramicfeedback.com>
    branch nick: Aaron's integration
    timestamp: Tue 2007-08-07 11:26:26 -0400
    message:
      Remove testing code
    ------------------------------------------------------------
    revno: 1551.2.49.1.40.1.22.1.42.1.31.1.39.1.17.1.80
    merged: abentley at panoramicfeedback.com-20070807152033-tjdm70lytg1e1x1h
    parent: abentley at panoramicfeedback.com-20070807151634-h9viyci8exz07pph
    committer: Aaron Bentley <abentley at panoramicfeedback.com>
    branch nick: Aaron's integration
    timestamp: Tue 2007-08-07 11:20:33 -0400
    message:
      Add NEWS entry
    ------------------------------------------------------------
    revno: 1551.2.49.1.40.1.22.1.42.1.31.1.39.1.17.1.79
    merged: abentley at panoramicfeedback.com-20070807151634-h9viyci8exz07pph
    parent: aaron.bentley at utoronto.ca-20070801134616-a3xct6wpqugrxaj3
    parent: pqm at pqm.ubuntu.com-20070807082835-sxq0vmfbvsebps5z
    committer: Aaron Bentley <abentley at panoramicfeedback.com>
    branch nick: Aaron's integration
    timestamp: Tue 2007-08-07 11:16:34 -0400
    message:
      Merge bzr.dev
    ------------------------------------------------------------
    revno: 1551.2.49.1.40.1.22.1.42.1.31.1.39.1.17.1.78
    merged: aaron.bentley at utoronto.ca-20070801134616-a3xct6wpqugrxaj3
    parent: aaron.bentley at utoronto.ca-20070731112050-5x29s1kop4x19s05
    committer: Aaron Bentley <aaron.bentley at utoronto.ca>
    branch nick: Aaron's mergeable stuff
    timestamp: Wed 2007-08-01 09:46:16 -0400
    message:
      Fix KeyError in filter_candidate_lca
=== modified file 'NEWS'
--- a/NEWS	2007-08-07 17:35:24 +0000
+++ b/NEWS	2007-08-07 20:01:09 +0000
@@ -38,6 +38,9 @@
     * allow ``easy_install bzr`` runs without fatal errors. 
       (Alexander Belchenko, #125521)
 
+    * Graph._filter_candidate_lca does not raise KeyError if a candidate
+      is eliminated just before it would normally be examined.  (Aaron Bentley)
+
   IMPROVEMENTS:
 
     * Don't show "dots" progress indicators when run non-interactively, such

=== modified file 'bzrlib/graph.py'
--- a/bzrlib/graph.py	2007-07-27 16:44:06 +0000
+++ b/bzrlib/graph.py	2007-08-07 15:26:26 +0000
@@ -234,7 +234,14 @@
         for searcher in active_searchers.itervalues():
             searcher.next()
         while len(active_searchers) > 0:
-            for candidate, searcher in list(active_searchers.iteritems()):
+            for candidate in active_searchers.keys():
+                try:
+                    searcher = active_searchers[candidate]
+                except KeyError:
+                    # rare case: we deleted candidate in a previous iteration
+                    # through this for loop, because it was determined to be
+                    # a descendant of another candidate.
+                    continue
                 try:
                     ancestors = searcher.next()
                 except StopIteration:

=== modified file 'bzrlib/tests/test_graph.py'
--- a/bzrlib/tests/test_graph.py	2007-07-26 19:56:04 +0000
+++ b/bzrlib/tests/test_graph.py	2007-08-07 18:33:10 +0000
@@ -145,6 +145,18 @@
         return self._real_parents_provider.get_parents(nodes)
 
 
+class DictParentsProvider(object):
+
+    def __init__(self, ancestry):
+        self.ancestry = ancestry
+
+    def __repr__(self):
+        return 'DictParentsProvider(%r)' % self.ancestry
+
+    def get_parents(self, revisions):
+        return [self.ancestry.get(r, None) for r in revisions]
+
+
 class TestGraph(TestCaseWithMemoryTransport):
 
     def make_graph(self, ancestors):
@@ -291,16 +303,8 @@
 
     def test_stacked_parents_provider(self):
 
-        class ParentsProvider(object):
-
-            def __init__(self, ancestry):
-                self.ancestry = ancestry
-
-            def get_parents(self, revisions):
-                return [self.ancestry.get(r, None) for r in revisions]
-
-        parents1 = ParentsProvider({'rev2': ['rev3']})
-        parents2 = ParentsProvider({'rev1': ['rev4']})
+        parents1 = DictParentsProvider({'rev2': ['rev3']})
+        parents2 = DictParentsProvider({'rev1': ['rev4']})
         stacked = _mod_graph._StackedParentsProvider([parents1, parents2])
         self.assertEqual([['rev4',], ['rev3']],
                          stacked.get_parents(['rev1', 'rev2']))
@@ -346,3 +350,16 @@
         graph = _mod_graph.Graph(instrumented_provider)
         self.assertFalse(graph.is_ancestor('a', 'c'))
         self.assertTrue('null:' not in instrumented_provider.calls)
+
+    def test_filter_candidate_lca(self):
+        """Test filter_candidate_lca for a corner case
+
+        This tests the case where we encounter the end of iteration for 'd'
+        in the same pass as we discover that 'c' is an ancestor of 'd', and
+        therefore 'd' can't be an lca.
+        """
+        # This test is sensitive to the iteration order of dicts.  It will
+        # pass incorrectly if 'e' and 'a' sort before 'c'
+        graph = self.make_graph({'c': ['b', 'd'], 'd': ['e'], 'b': ['a'],
+                                 'a': [NULL_REVISION], 'e': [NULL_REVISION]})
+        self.assertEqual(['c'], graph._filter_candidate_lca(['a', 'c', 'e']))




More information about the bazaar-commits mailing list