)]}'
{"heat/engine/dependencies.py":[{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"b8600f5be0bb4a58326a25449541dc49ee02e0c3","unresolved":false,"context_lines":[{"line_number":129,"context_line":""},{"line_number":130,"context_line":"        for src in node.required_by():"},{"line_number":131,"context_line":"            if key in self[src]:"},{"line_number":132,"context_line":"                self[src] -\u003d key"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        return super(Graph, self).__delitem__(key)"},{"line_number":135,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2F7mE%3D","line":132,"updated":"2014-01-06 20:01:25.000000000","message":"It would be better to retrieve self[src] only once:\n\n  src_node \u003d self[src]\n  if key in src_node:\n      src_node -\u003d key\n\nAlternatively we could just change line 62 from remove(target) to discard(target) instead, as that avoids the KeyError.","commit_id":"47ccbea53e55b5a6a7d1831e277705e2371b63f7"}],"heat/engine/scheduler.py":[{"author":{"_account_id":7135,"name":"Liang Chen","email":"liangchen.linux@gmail.com","username":"Liang"},"change_message_id":"3644dae984c3c8365383179605d3faeb23919564","unresolved":false,"context_lines":[{"line_number":333,"context_line":"                        if r.step():"},{"line_number":334,"context_line":"                            del self._graph[k]"},{"line_number":335,"context_line":"                except Exception as e:"},{"line_number":336,"context_line":"                    r.cancel()"},{"line_number":337,"context_line":"                    if self.aggregate_exceptions:"},{"line_number":338,"context_line":"                        raised_exceptions.append(e)"},{"line_number":339,"context_line":"                    else:"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9C3w%3D","line":336,"updated":"2013-12-17 14:16:05.000000000","message":"I haven\u0027t got a chance to test this. But it seems that just canceling the failed task without raising an exception would cause all its dependents never getting a chance to start, thus making any(self._runners.itervalues())  returning True forever.","commit_id":"53cda61834f0f0b5d4e63668469a3211c9b20367"},{"author":{"_account_id":9189,"name":"Anderson Mesquita","email":"andersonvom@gmail.com","username":"andersonvom"},"change_message_id":"d9e8eddbbfc96a613674a9c10ba9957e0e884bad","unresolved":false,"context_lines":[{"line_number":333,"context_line":"                        if r.step():"},{"line_number":334,"context_line":"                            del self._graph[k]"},{"line_number":335,"context_line":"                except Exception as e:"},{"line_number":336,"context_line":"                    r.cancel()"},{"line_number":337,"context_line":"                    if self.aggregate_exceptions:"},{"line_number":338,"context_line":"                        raised_exceptions.append(e)"},{"line_number":339,"context_line":"                    else:"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAATn%2F9BSc%3D","line":336,"in_reply_to":"AAAATn%2F9C3w%3D","updated":"2013-12-17 16:13:58.000000000","message":"Agreed.\n\nIf T2 depends on T1, and T1 gets cancelled without raising an exception, T2 does not get cancelled but will never be ready to to run (since its dependencies never completed).\n\nDependent tasks should be either cancelled too or removed from the graph in order for this to work.","commit_id":"53cda61834f0f0b5d4e63668469a3211c9b20367"},{"author":{"_account_id":7135,"name":"Liang Chen","email":"liangchen.linux@gmail.com","username":"Liang"},"change_message_id":"6fbc46d6888ebc6d36cef2a244858f8d27a33336","unresolved":false,"context_lines":[{"line_number":333,"context_line":"                        if r.step():"},{"line_number":334,"context_line":"                            del self._graph[k]"},{"line_number":335,"context_line":"                except Exception as e:"},{"line_number":336,"context_line":"                    r.cancel()"},{"line_number":337,"context_line":"                    if self.aggregate_exceptions:"},{"line_number":338,"context_line":"                        raised_exceptions.append(e)"},{"line_number":339,"context_line":"                    else:"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATn%2F8zMs%3D","line":336,"updated":"2013-12-20 07:28:55.000000000","message":"Correction to my previous comments in patch-set 2 - this will not cause a dead loop. Because r.cancel will set the r._done to True, thus allowing its  dependencies to start running. This doesn\u0027t quite make sense though, but it\u0027s unrelated to this patch.\n\nHowever, the fact is that this will effectively allow all the dependency tasks to proceed without completion of their required task. That would cause \"dependency not ready\" related errors all the way down to the leaves of the dependency tree. Will it be a viable alternative to cancel/remove all the dependency tasks as Anderson suggested?","commit_id":"4bfe9fde2f96cf4c59b4d1231842f934a8b46d0f"},{"author":{"_account_id":9062,"name":"Richard Lee","email":"rblee88@gmail.com","username":"arbylee"},"change_message_id":"7604b35451332335564bb8508da40f053e91e040","unresolved":false,"context_lines":[{"line_number":333,"context_line":"                        if r.step():"},{"line_number":334,"context_line":"                            del self._graph[k]"},{"line_number":335,"context_line":"                except Exception as e:"},{"line_number":336,"context_line":"                    r.cancel()"},{"line_number":337,"context_line":"                    if self.aggregate_exceptions:"},{"line_number":338,"context_line":"                        raised_exceptions.append(e)"},{"line_number":339,"context_line":"                    else:"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATn%2F8uUc%3D","line":336,"in_reply_to":"AAAATn%2F8zMs%3D","updated":"2013-12-21 04:23:32.000000000","message":"Yup, we actually made changes to that effect in patch 3, but a failed rebase seems to have reverted that part of the code in this review.  Fixing that and resubmitting","commit_id":"4bfe9fde2f96cf4c59b4d1231842f934a8b46d0f"},{"author":{"_account_id":7253,"name":"Jason Dunsmore","email":"jasondunsmore@gmail.com","username":"jbd"},"change_message_id":"ddbcff9525a357df8114d2fd978e168e5fceabb7","unresolved":false,"context_lines":[{"line_number":85,"context_line":"    exceptions can be acted upon."},{"line_number":86,"context_line":"    \u0027\u0027\u0027"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def __init__(self, exceptions\u003dNone):"},{"line_number":89,"context_line":"        if exceptions is None:"},{"line_number":90,"context_line":"            exceptions \u003d list()"},{"line_number":91,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAT3%2F%2F0u4%3D","line":88,"updated":"2013-12-30 18:50:36.000000000","message":"Is there a reason you don\u0027t just set the default to an empty list to begin with?\n\n def __init__(self, exceptions\u003d[]):","commit_id":"19ceb141f6540bacdc2d0504b88b7049efe853f8"},{"author":{"_account_id":9189,"name":"Anderson Mesquita","email":"andersonvom@gmail.com","username":"andersonvom"},"change_message_id":"996b696e298906aa2a7d4ab693c5a20e606d6c84","unresolved":false,"context_lines":[{"line_number":85,"context_line":"    exceptions can be acted upon."},{"line_number":86,"context_line":"    \u0027\u0027\u0027"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def __init__(self, exceptions\u003dNone):"},{"line_number":89,"context_line":"        if exceptions is None:"},{"line_number":90,"context_line":"            exceptions \u003d list()"},{"line_number":91,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAT3%2F%2F0hc%3D","line":88,"in_reply_to":"AAAAT3%2F%2F0u4%3D","updated":"2013-12-30 20:12:43.000000000","message":"Hi Jason,\n\nDue to python\u0027s way of creating these objects, it can lead to unwanted behaviors:\n\n  class T(object):\n      def __init__(self, group\u003d[]):\n          self.group \u003d group\n  \n  t1 \u003d T()\n  t1.group             # \u003d\u003e [ ]\n\n  t2 \u003d T()\n  t2.group             # \u003d\u003e [ ]\n\n  t1.group.append(1)\n  t2.group             # \u003d\u003e [1]\n\nSince this is not usually wanted, it is best to avoid default args with mutable objects.","commit_id":"19ceb141f6540bacdc2d0504b88b7049efe853f8"},{"author":{"_account_id":7135,"name":"Liang Chen","email":"liangchen.linux@gmail.com","username":"Liang"},"change_message_id":"8a438582de7f1b8eb8442279ffd37e63935b0c9f","unresolved":false,"context_lines":[{"line_number":349,"context_line":"    def _cancel_recursively(self, key, runner):"},{"line_number":350,"context_line":"        runner.cancel()"},{"line_number":351,"context_line":"        node \u003d self._graph[key]"},{"line_number":352,"context_line":"        for dependent_node in node.required_by():"},{"line_number":353,"context_line":"            node_runner \u003d self._runners[dependent_node]"},{"line_number":354,"context_line":"            self._cancel_recursively(dependent_node, node_runner)"},{"line_number":355,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAT3%2F%2F%2Fdw%3D","line":352,"updated":"2013-12-25 09:41:58.000000000","message":"It seems this would not work if the nodes are traversed in reverse order, e.g. scheduler.DependencyTaskGroup(self.dependencies,                                                     resource.Resource.destroy,                                                    reverse\u003dTrue) in stack.delete.","commit_id":"19ceb141f6540bacdc2d0504b88b7049efe853f8"},{"author":{"_account_id":7135,"name":"Liang Chen","email":"liangchen.linux@gmail.com","username":"Liang"},"change_message_id":"edd5e1a54a923e8c3f16d760d5779479cc24a3a2","unresolved":false,"context_lines":[{"line_number":349,"context_line":"    def _cancel_recursively(self, key, runner):"},{"line_number":350,"context_line":"        runner.cancel()"},{"line_number":351,"context_line":"        node \u003d self._graph[key]"},{"line_number":352,"context_line":"        for dependent_node in node.required_by():"},{"line_number":353,"context_line":"            node_runner \u003d self._runners[dependent_node]"},{"line_number":354,"context_line":"            self._cancel_recursively(dependent_node, node_runner)"},{"line_number":355,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAUH%2F%2FTkg%3D","line":352,"in_reply_to":"AAAAT3%2F%2F%2Fdw%3D","updated":"2014-01-15 09:28:18.000000000","message":"After taking a closer look, this is already handled by the dependencies module.","commit_id":"19ceb141f6540bacdc2d0504b88b7049efe853f8"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"e45dcfe97043139f7d5f04e7859d82d21dfb47f2","unresolved":false,"context_lines":[{"line_number":205,"context_line":"            self._sleep(wait_time)"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    def cancel(self):"},{"line_number":208,"context_line":"        \"\"\"Cancel the task if it is running.\"\"\""},{"line_number":209,"context_line":"        if self.started() and not self.done():"},{"line_number":210,"context_line":"            logger.debug(_(\u0027%s cancelled\u0027) % str(self))"},{"line_number":211,"context_line":"            self._runner.close()"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAT3%2F%2Fq%2Bg%3D","line":208,"updated":"2014-01-03 19:11:43.000000000","message":"This is no longer accurate.","commit_id":"30b942158429dac2c32afa33c313ae38fee5d128"},{"author":{"_account_id":9189,"name":"Anderson Mesquita","email":"andersonvom@gmail.com","username":"andersonvom"},"change_message_id":"b5874fd82888ee7540885b79f738b0aba292f051","unresolved":false,"context_lines":[{"line_number":205,"context_line":"            self._sleep(wait_time)"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    def cancel(self):"},{"line_number":208,"context_line":"        \"\"\"Cancel the task if it is running.\"\"\""},{"line_number":209,"context_line":"        if self.started() and not self.done():"},{"line_number":210,"context_line":"            logger.debug(_(\u0027%s cancelled\u0027) % str(self))"},{"line_number":211,"context_line":"            self._runner.close()"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAT3%2F%2Fqqc%3D","line":208,"in_reply_to":"AAAAT3%2F%2Fq%2Bg%3D","updated":"2014-01-03 20:33:31.000000000","message":"Agreed.","commit_id":"30b942158429dac2c32afa33c313ae38fee5d128"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"e45dcfe97043139f7d5f04e7859d82d21dfb47f2","unresolved":false,"context_lines":[{"line_number":209,"context_line":"        if self.started() and not self.done():"},{"line_number":210,"context_line":"            logger.debug(_(\u0027%s cancelled\u0027) % str(self))"},{"line_number":211,"context_line":"            self._runner.close()"},{"line_number":212,"context_line":"        self._done \u003d True"},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"    def started(self):"},{"line_number":215,"context_line":"        \"\"\"Return True if the task has been started.\"\"\""}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAT3%2F%2Fq%2BM%3D","line":212,"updated":"2014-01-03 19:11:43.000000000","message":"On reflection, this should probably be done in the \u0027finally\u0027 part of a try/finally block.","commit_id":"30b942158429dac2c32afa33c313ae38fee5d128"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"898863a03d1150cdaf596cd19116f539ba007cd8","unresolved":false,"context_lines":[{"line_number":208,"context_line":"        \"\"\"Cancel the task and mark it as done.\"\"\""},{"line_number":209,"context_line":"        if self.started() and not self.done():"},{"line_number":210,"context_line":"            self._runner.close()"},{"line_number":211,"context_line":"        logger.debug(_(\u0027%s cancelled\u0027) % str(self))"},{"line_number":212,"context_line":"        self._done \u003d True"},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"    def started(self):"}],"source_content_type":"text/x-python","patch_set":11,"id":"AAAAT3%2F%2FqIg%3D","line":211,"updated":"2014-01-04 00:23:21.000000000","message":"It\u0027s generally better to log before something happens rather than after, because then if an exception occurs during you\u0027ll have some history about what caused it. I think the ideal implementation here would be:\n\n  if not self.done():\n      logger.debug(_(\u0027%s cancelled\u0027) % str(self))\n      try:\n          if self.started():\n              self._runner.close()\n      finally:\n          self._done \u003d True","commit_id":"db65ceefb4f3602771610cbc416e13bd1eb5fb21"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"b8600f5be0bb4a58326a25449541dc49ee02e0c3","unresolved":false,"context_lines":[{"line_number":206,"context_line":""},{"line_number":207,"context_line":"    def cancel(self):"},{"line_number":208,"context_line":"        \"\"\"Cancel the task and mark it as done.\"\"\""},{"line_number":209,"context_line":"        logger.debug(_(\u0027%s cancelled\u0027) % str(self))"},{"line_number":210,"context_line":"        try:"},{"line_number":211,"context_line":"            if self.started() and not self.done():"},{"line_number":212,"context_line":"                self._runner.close()"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2F7rM%3D","line":209,"updated":"2014-01-06 20:01:25.000000000","message":"I don\u0027t think we want to log this if the task already completed successfully before we called cancel(). That\u0027s why I suggested this implementation:\n\n  if not self.done():\n      logger.debug(_(\u0027%s cancelled\u0027) % str(self))\n      try:\n          if self.started():\n              self._runner.close()\n      finally:\n          self._done \u003d True","commit_id":"47ccbea53e55b5a6a7d1831e277705e2371b63f7"}],"heat/tests/test_scheduler.py":[{"author":{"_account_id":9542,"name":"Pavlo Shchelokovskyy","email":"pshchelokovskyy@mirantis.com","username":"pshchelo"},"change_message_id":"d5a29b0f8ca56f48a9eb76419bb9ff33cec55c2a","unresolved":false,"context_lines":[{"line_number":364,"context_line":""},{"line_number":365,"context_line":"                dummy.do_step(3, \u0027A\u0027).InAnyOrder(\u00273\u0027)"},{"line_number":366,"context_line":""},{"line_number":367,"context_line":"        # python 2.6 does not support self.assertRaises"},{"line_number":368,"context_line":"        # to be used as a context manager"},{"line_number":369,"context_line":"        try:"},{"line_number":370,"context_line":"            e1 \u003d Exception(\u0027e1\u0027)"}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAATn%2F8nfI%3D","line":367,"updated":"2013-12-24 09:19:01.000000000","message":"I\u0027m just curious, would it be proper/feasible to inherit this class from both mox and testtools (that are both in the requirements) to provide both mocking functionality and proper assertions universal for both py2.6 and py2.7?","commit_id":"19ceb141f6540bacdc2d0504b88b7049efe853f8"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"e45dcfe97043139f7d5f04e7859d82d21dfb47f2","unresolved":false,"context_lines":[{"line_number":367,"context_line":"                dummy.do_step(3, \u0027A\u0027).InAnyOrder(\u00273\u0027)"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"        # Use try/except/else to inspect the exception since python 2.6"},{"line_number":370,"context_line":"        # does not support self.assertRaises to be used as a context manager"},{"line_number":371,"context_line":"        try:"},{"line_number":372,"context_line":"            e1 \u003d Exception(\u0027e1\u0027)"},{"line_number":373,"context_line":"            e2 \u003d Exception(\u0027e2\u0027)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAT3%2F%2FrA4%3D","line":370,"updated":"2014-01-03 19:11:43.000000000","message":"We\u0027re not using the Python 2.6 version of self.assertRaises. We\u0027re using the one provided by testtools, which is incompatible with both Python 2.6 and Python 2.7 (sigh). The good news is that in testtools, assertRaises returns the exception that was raised.","commit_id":"30b942158429dac2c32afa33c313ae38fee5d128"},{"author":{"_account_id":9189,"name":"Anderson Mesquita","email":"andersonvom@gmail.com","username":"andersonvom"},"change_message_id":"b5874fd82888ee7540885b79f738b0aba292f051","unresolved":false,"context_lines":[{"line_number":367,"context_line":"                dummy.do_step(3, \u0027A\u0027).InAnyOrder(\u00273\u0027)"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"        # Use try/except/else to inspect the exception since python 2.6"},{"line_number":370,"context_line":"        # does not support self.assertRaises to be used as a context manager"},{"line_number":371,"context_line":"        try:"},{"line_number":372,"context_line":"            e1 \u003d Exception(\u0027e1\u0027)"},{"line_number":373,"context_line":"            e2 \u003d Exception(\u0027e2\u0027)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAT3%2F%2FqqE%3D","line":370,"in_reply_to":"AAAAT3%2F%2FrA4%3D","updated":"2014-01-03 20:33:31.000000000","message":"IMO, we should probably keep it this way, then, since we might switch from testtools in the future and relying on the fact that assertRaises returns something will break it.\n\nKeeping things this way will still work, though. Plus, it\u0027s being done just like this in other parts of the tests.","commit_id":"30b942158429dac2c32afa33c313ae38fee5d128"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"b8600f5be0bb4a58326a25449541dc49ee02e0c3","unresolved":false,"context_lines":[{"line_number":197,"context_line":"        super(DependencyTaskGroupTest, self).setUp()"},{"line_number":198,"context_line":"        self.addCleanup(self.m.VerifyAll)"},{"line_number":199,"context_line":"        self.aggregate_exceptions \u003d False"},{"line_number":200,"context_line":"        self.reverse_order \u003d False"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    @contextlib.contextmanager"},{"line_number":203,"context_line":"    def _dep_test(self, *edges):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2F7oA%3D","line":200,"updated":"2014-01-06 20:01:25.000000000","message":"I\u0027m not so worried about testing the combination of this and reverse order. Reverse order really is just the same graph with all the edges pointing in the opposite direction, so if it works for a general graph it will work in reverse. (The actual reversing part is tested elsewhere.)","commit_id":"47ccbea53e55b5a6a7d1831e277705e2371b63f7"},{"author":{"_account_id":9062,"name":"Richard Lee","email":"rblee88@gmail.com","username":"arbylee"},"change_message_id":"c8a2ad58cc2a3d34407c990f70ed93348af74122","unresolved":false,"context_lines":[{"line_number":197,"context_line":"        super(DependencyTaskGroupTest, self).setUp()"},{"line_number":198,"context_line":"        self.addCleanup(self.m.VerifyAll)"},{"line_number":199,"context_line":"        self.aggregate_exceptions \u003d False"},{"line_number":200,"context_line":"        self.reverse_order \u003d False"},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    @contextlib.contextmanager"},{"line_number":203,"context_line":"    def _dep_test(self, *edges):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2F3E8%3D","line":200,"in_reply_to":"AAAAUH%2F%2F7oA%3D","updated":"2014-01-07 15:21:36.000000000","message":"We had a previous comment that questioned whether this would work in reverse order, so we added the reverse test to make it obvious/explicit that it does work. If it seems excessive, we can remove it","commit_id":"47ccbea53e55b5a6a7d1831e277705e2371b63f7"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"b8600f5be0bb4a58326a25449541dc49ee02e0c3","unresolved":false,"context_lines":[{"line_number":378,"context_line":"            self.aggregate_exceptions \u003d True"},{"line_number":379,"context_line":"            tasks \u003d ((\u0027A\u0027, None), (\u0027B\u0027, \u0027A\u0027), (\u0027C\u0027, \u0027B\u0027))"},{"line_number":380,"context_line":"            with self._dep_test(*tasks) as dummy:"},{"line_number":381,"context_line":"                dummy.do_step(1, \u0027A\u0027).InAnyOrder(\u00271\u0027).AndRaise(e1)"},{"line_number":382,"context_line":""},{"line_number":383,"context_line":"        e1 \u003d Exception(\u0027e1\u0027)"},{"line_number":384,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2F7qg%3D","line":381,"updated":"2014-01-06 20:01:25.000000000","message":"The InAnyOrder() group here is superfluous, since there is only one mocked call. You could just do:\n\n  dummy.do_step(1, \u0027A\u0027).AndRaise(e1)\n\nThough in reality I think this issue here is we\u0027re just not testing a complicated enough case.","commit_id":"47ccbea53e55b5a6a7d1831e277705e2371b63f7"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"b8600f5be0bb4a58326a25449541dc49ee02e0c3","unresolved":false,"context_lines":[{"line_number":392,"context_line":"            self.aggregate_exceptions \u003d True"},{"line_number":393,"context_line":"            tasks \u003d ((\u0027A\u0027, None), (\u0027B\u0027, \u0027A\u0027), (\u0027C\u0027, \u0027B\u0027))"},{"line_number":394,"context_line":"            with self._dep_test(*tasks) as dummy:"},{"line_number":395,"context_line":"                dummy.do_step(1, \u0027C\u0027).InAnyOrder(\u00271\u0027).AndRaise(e1)"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"        e1 \u003d Exception(\u0027e1\u0027)"},{"line_number":398,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAUH%2F%2F7qc%3D","line":395,"updated":"2014-01-06 20:01:25.000000000","message":"ditto","commit_id":"47ccbea53e55b5a6a7d1831e277705e2371b63f7"},{"author":{"_account_id":4257,"name":"Zane Bitter","email":"zbitter@redhat.com","username":"zaneb"},"change_message_id":"bc7616af196875773b8b58ed691fa64a4330b20d","unresolved":false,"context_lines":[{"line_number":364,"context_line":"                dummy.do_step(2, \u0027A\u0027).InAnyOrder(\u00272\u0027)"},{"line_number":365,"context_line":"                dummy.do_step(2, \u0027B\u0027).InAnyOrder(\u00272\u0027).AndRaise(e2)"},{"line_number":366,"context_line":""},{"line_number":367,"context_line":"                dummy.do_step(3, \u0027A\u0027).InAnyOrder(\u00273\u0027)"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"        e1 \u003d Exception(\u0027e1\u0027)"},{"line_number":370,"context_line":"        e2 \u003d Exception(\u0027e2\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAAUH%2F%2Fw8s%3D","line":367,"updated":"2014-01-08 18:30:14.000000000","message":"This InAnyOrder() is unnecessary too.","commit_id":"826cac43f91f85b97e9c607be1f11712827db4b3"}]}
