)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"f78377b01b75e7e0de5191d98d766a0287e9bb12","unresolved":false,"context_lines":[{"line_number":1,"context_line":"Parent:     aebbcff1 (Updated from global requirements)"},{"line_number":2,"context_line":"Author:     d34dh0r53 \u003cdavid.wilde@rackspace.com\u003e"},{"line_number":3,"context_line":"AuthorDate: 2015-01-19 18:02:08 -0600"},{"line_number":4,"context_line":"Commit:     d34dh0r53 \u003cdavid.wilde@rackspace.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2015-02-10 16:10:25 -0600"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"da86d52c_b396a8ee","line":2,"updated":"2015-02-10 23:07:27.000000000","message":"Did you mean the author/committer info to be \"d34dh0r53\" or \"David Wilde\"?","commit_id":"c7775af245c973d0c9bf99d2275df0f2a4bed4d9"},{"author":{"_account_id":7414,"name":"David Wilde","email":"dwilde@redhat.com","username":"d34dh0r53"},"change_message_id":"edfeb297dd05521df6010936d77bf66304ed2d08","unresolved":false,"context_lines":[{"line_number":1,"context_line":"Parent:     aebbcff1 (Updated from global requirements)"},{"line_number":2,"context_line":"Author:     d34dh0r53 \u003cdavid.wilde@rackspace.com\u003e"},{"line_number":3,"context_line":"AuthorDate: 2015-01-19 18:02:08 -0600"},{"line_number":4,"context_line":"Commit:     d34dh0r53 \u003cdavid.wilde@rackspace.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2015-02-10 16:10:25 -0600"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"da86d52c_6e8d237c","line":2,"in_reply_to":"da86d52c_b396a8ee","updated":"2015-02-10 23:21:31.000000000","message":"That\u0027s my LP username, so yes.","commit_id":"c7775af245c973d0c9bf99d2275df0f2a4bed4d9"}],"glanceclient/exc.py":[{"author":{"_account_id":11356,"name":"Louis Taylor","email":"louis@kragniz.eu","username":"kragniz"},"change_message_id":"8b30a325495d9ddb9f46fa85c1463f5aa85483b4","unresolved":false,"context_lines":[{"line_number":158,"context_line":"        # Iterate over the nested objects and retreive the \"message\" attribute."},{"line_number":159,"context_line":"        # Filter out None from any objects that don\u0027t have a \"message\" attr."},{"line_number":160,"context_line":"        messages \u003d filter(None, map(lambda obj: obj.get(\u0027message\u0027),"},{"line_number":161,"context_line":"                                    response.json().values()))"},{"line_number":162,"context_line":"        # Join all of the messages together nicely."},{"line_number":163,"context_line":"        details \u003d \u0027\\n\u0027.join(messages)"},{"line_number":164,"context_line":"        return cls(details\u003ddetails)"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_db13aa63","line":161,"updated":"2015-01-20 00:42:57.000000000","message":"Could this be written a little more pythonically, rather than the lispy map filter? Something along the lines of:\n\n    messages \u003d (obj.get(\u0027message\u0027) for obj in response.json().values())\n    # Join all of the messages together nicely.\n    details \u003d \u0027\\n\u0027.join(msg for msg in messages if msg is not None)\n\nThoughts?","commit_id":"ce8364b43c0cb2f606eb49be40fa5dab3f2905f8"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"3e0c9d4840df4318156b02a330fa15deb756a816","unresolved":false,"context_lines":[{"line_number":158,"context_line":"        # Iterate over the nested objects and retreive the \"message\" attribute."},{"line_number":159,"context_line":"        # Filter out None from any objects that don\u0027t have a \"message\" attr."},{"line_number":160,"context_line":"        messages \u003d filter(None, map(lambda obj: obj.get(\u0027message\u0027),"},{"line_number":161,"context_line":"                                    response.json().values()))"},{"line_number":162,"context_line":"        # Join all of the messages together nicely."},{"line_number":163,"context_line":"        details \u003d \u0027\\n\u0027.join(messages)"},{"line_number":164,"context_line":"        return cls(details\u003ddetails)"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a961159_8f063ccc","line":161,"in_reply_to":"3a961159_db13aa63","updated":"2015-01-20 04:05:21.000000000","message":"What about:\n\n    messages \u003d filter(None,\n                      (obj.get(\u0027message\u0027) for obj in response.json().values()))\n\nI really don\u0027t think there\u0027s anything inherently more \"pythonic\" in your code Louis than this or passing the generator to filter or using map.","commit_id":"ce8364b43c0cb2f606eb49be40fa5dab3f2905f8"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"d5955b6b329a6b4f119ea6336091d6a92f359b36","unresolved":false,"context_lines":[{"line_number":158,"context_line":"        # Iterate over the nested objects and retreive the \"message\" attribute."},{"line_number":159,"context_line":"        # Filter out None from any objects that don\u0027t have a \"message\" attr."},{"line_number":160,"context_line":"        # messages \u003d filter(None, map(lambda obj: obj.get(\u0027message\u0027),"},{"line_number":161,"context_line":"        #                            response.json().values()))"},{"line_number":162,"context_line":"        messages \u003d [obj.get(\u0027message\u0027) for obj in response.json().values()]"},{"line_number":163,"context_line":"        # Join all of the messages together nicely."},{"line_number":164,"context_line":"        details \u003d \u0027\\n\u0027.join([i for i in messages if i is not None])"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a930d6b_0726a5b7","line":161,"updated":"2015-01-21 21:52:01.000000000","message":"Should probably remove the commented out code here.","commit_id":"e97266ffe1784d820da70f16d7fa425c539ce363"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"3058ece48b7881d0b05a8a149a8b98a37d96b55e","unresolved":false,"context_lines":[{"line_number":156,"context_line":"    cls \u003d _code_map.get(response.status_code, HTTPException)"},{"line_number":157,"context_line":"    if body and \u0027json\u0027 in response.headers[\u0027content-type\u0027]:"},{"line_number":158,"context_line":"        # Iterate over the nested objects and retreive the \"message\" attribute."},{"line_number":159,"context_line":"        messages \u003d [obj.get(\u0027message\u0027) for obj in response.json().values()]"},{"line_number":160,"context_line":"        # Join all of the messages together nicely and filter out any objects"},{"line_number":161,"context_line":"        # that don\u0027t have a \"message\" attr."},{"line_number":162,"context_line":"        details \u003d \u0027\\n\u0027.join(i for i in messages if i is not None)"}],"source_content_type":"text/x-python","patch_set":3,"id":"da86d52c_386855f5","line":159,"updated":"2015-01-30 22:36:22.000000000","message":"We want to include the \"details\" of the error here as well, no?","commit_id":"060e57c04a0b6e9d4099faf488f9b7e69db9beec"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"498b9ff6f4dc515c95b2f887dcc16f455407dd7d","unresolved":false,"context_lines":[{"line_number":156,"context_line":"    cls \u003d _code_map.get(response.status_code, HTTPException)"},{"line_number":157,"context_line":"    if body and \u0027json\u0027 in response.headers[\u0027content-type\u0027]:"},{"line_number":158,"context_line":"        # Iterate over the nested objects and retreive the \"message\" attribute."},{"line_number":159,"context_line":"        messages \u003d [obj.get(\u0027message\u0027) for obj in response.json().values()]"},{"line_number":160,"context_line":"        # Join all of the messages together nicely and filter out any objects"},{"line_number":161,"context_line":"        # that don\u0027t have a \"message\" attr."},{"line_number":162,"context_line":"        details \u003d \u0027\\n\u0027.join(i for i in messages if i is not None)"}],"source_content_type":"text/x-python","patch_set":3,"id":"da86d52c_8311d2ae","line":159,"in_reply_to":"da86d52c_386855f5","updated":"2015-01-30 23:05:11.000000000","message":"I think the better question is how long/succinct do we want the exception message to be?","commit_id":"060e57c04a0b6e9d4099faf488f9b7e69db9beec"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"8f8d6e20b4ee76afd7695824d907e91ad545297c","unresolved":false,"context_lines":[{"line_number":168,"context_line":"        details_seen \u003d set()"},{"line_number":169,"context_line":"        details_seen_add \u003d details_seen.add"},{"line_number":170,"context_line":"        details \u003d list([re.sub(r\u0027\u003c.+?\u003e\u0027, \u0027\u0027, i) for i in details"},{"line_number":171,"context_line":"                        if not (i in details_seen or details_seen_add(i))])"},{"line_number":172,"context_line":"        # Return joined string separated by colons."},{"line_number":173,"context_line":"        details \u003d \u0027: \u0027.join(i for i in details if i)"},{"line_number":174,"context_line":"        return cls(details\u003ddetails)"}],"source_content_type":"text/x-python","patch_set":5,"id":"da86d52c_bc8e7d2c","line":171,"updated":"2015-02-10 20:45:09.000000000","message":"So a few things\n\n1. You don\u0027t need to wrap this in a call to list()\n\n2. You should probably strip the HTML from the lines on L166\n\n3. I think your condition here is faulty (which is why the tests are failing). You probably meant\n\n    if (i not in details_seen and details_seen_add(i))\n\nThis means if i is not in details_seen and the result of adding i to the set is True, then it\u0027ll include it in the list. If we look at the set and the list we\u0027re building like this, it should be clearer\n\n    details \u003d [\"Error\", \"Error\", \"Danger Will Robinson\"]\n    seen \u003d {}\n\nOn the first \"Error\" we\u0027ll see that it is not in seen and we\u0027ll add it and keep it in the new list. The second time, we will see it is already there so we\u0027ll return False from `i not in details_seen` (short circuiting the whole conditional) and then skip it in the list comprehension. Finally we\u0027ll see \"Danger Will Robinson\" and add that.\n\nIf we keep the HTML around and use that in the set than a body like the following could display funny:\n\n    \u003ch1\u003eError\u003c/h1\u003e\n    \u003ch2\u003eError\u003c/h2\u003e\n    \u003cp\u003eDanger Will Robinson\u003c/p\u003e\n\nBecause while we\u0027ve already decided to print \"Error\" from the h1, the \"Error\" from the h2 will also be printed because \"\u003ch2\u003eError\u003c/h2\u003e\" is not in the set.","commit_id":"d8c870648ad35a33e8ebaf8cbe730eab9ee6cedf"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"f78377b01b75e7e0de5191d98d766a0287e9bb12","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        # Remove duplicates from the list."},{"line_number":170,"context_line":"        details_seen \u003d set()"},{"line_number":171,"context_line":"        details_temp \u003d []"},{"line_number":172,"context_line":"        for i in details:"},{"line_number":173,"context_line":"            if (i not in details_seen):"},{"line_number":174,"context_line":"                details_temp.append(i)"},{"line_number":175,"context_line":"            details_seen.add(i)"}],"source_content_type":"text/x-python","patch_set":6,"id":"da86d52c_53000c34","line":172,"updated":"2015-02-10 23:07:27.000000000","message":"So instead of filtering out lines that end up having nothing in the above, we should add a check in the loop like:\n\n    for i in details:\n        if not i:\n            continue\n        if i not in details_seen:\n            details_temp.append(i)\n            details_seen.add(i)\n\nThis means later we can just do\n\n    details \u003d \u0027: \u0027.join(details_temp)\n\nFinally, we could probably rename details_temp to unique_details.","commit_id":"c7775af245c973d0c9bf99d2275df0f2a4bed4d9"},{"author":{"_account_id":7414,"name":"David Wilde","email":"dwilde@redhat.com","username":"d34dh0r53"},"change_message_id":"edfeb297dd05521df6010936d77bf66304ed2d08","unresolved":false,"context_lines":[{"line_number":169,"context_line":"        # Remove duplicates from the list."},{"line_number":170,"context_line":"        details_seen \u003d set()"},{"line_number":171,"context_line":"        details_temp \u003d []"},{"line_number":172,"context_line":"        for i in details:"},{"line_number":173,"context_line":"            if (i not in details_seen):"},{"line_number":174,"context_line":"                details_temp.append(i)"},{"line_number":175,"context_line":"            details_seen.add(i)"}],"source_content_type":"text/x-python","patch_set":6,"id":"da86d52c_6e00c3ab","line":172,"in_reply_to":"da86d52c_53000c34","updated":"2015-02-10 23:21:31.000000000","message":"Done","commit_id":"c7775af245c973d0c9bf99d2275df0f2a4bed4d9"},{"author":{"_account_id":6549,"name":"Zhi Yan Liu","email":"lzy.dev@gmail.com","username":"lzy-dev"},"change_message_id":"0454bb0aa9c11eb1aaef7fdc3c16defe5b9efce1","unresolved":false,"context_lines":[{"line_number":162,"context_line":"        details \u003d \u0027\\n\u0027.join(i for i in messages if i is not None)"},{"line_number":163,"context_line":"        return cls(details\u003ddetails)"},{"line_number":164,"context_line":"    elif body and \u0027html\u0027 in response.headers[\u0027content-type\u0027]:"},{"line_number":165,"context_line":"        # Split the lines, strip whitespace and inline HTML from the response."},{"line_number":166,"context_line":"        details \u003d [re.sub(r\u0027\u003c.+?\u003e\u0027, \u0027\u0027, i.strip())"},{"line_number":167,"context_line":"                   for i in response.text.splitlines()]"},{"line_number":168,"context_line":"        details \u003d [i for i in details if i]"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba7be1f8_1695d2e3","line":165,"updated":"2015-03-01 15:04:42.000000000","message":"This logic for text/html branch is fine to me even I think under current glance-api design, the exception response with this kind of content type could be returned in any normal case due to glance currently only support json content.","commit_id":"01caf4e734fb012f0b5b19c24a8ffeaef31a06be"}],"tests/test_exc.py":[{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"3058ece48b7881d0b05a8a149a8b98a37d96b55e","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        }"},{"line_number":55,"context_line":"        err \u003d exc.from_response(mock_resp, \"Non-empty body\")"},{"line_number":56,"context_line":"        self.assertIsInstance(err, exc.HTTPOverLimit)"},{"line_number":57,"context_line":"        self.assertEqual(\"OverLimit Retry...\", err.details)"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    def test_handles_html(self):"},{"line_number":60,"context_line":"        \"\"\"exc.from_response should not print HTML.\"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"da86d52c_7872cde6","line":57,"updated":"2015-01-30 22:36:22.000000000","message":"https://review.openstack.org/#/c/148387/3/glanceclient/exc.py\n\nline 159","commit_id":"060e57c04a0b6e9d4099faf488f9b7e69db9beec"},{"author":{"_account_id":11356,"name":"Louis Taylor","email":"louis@kragniz.eu","username":"kragniz"},"change_message_id":"945a4e0be1d60b81b57f08688f53d0669fd9305d","unresolved":false,"context_lines":[{"line_number":67,"context_line":"        err \u003d exc.from_response(mock_resp, HTML_MSG)"},{"line_number":68,"context_line":"        self.assertIsInstance(err, exc.HTTPNotFound)"},{"line_number":69,"context_line":"        self.assertEqual(\"Entity could not be found: 404 Entity Not Found\","},{"line_number":70,"context_line":"                         err.details)"}],"source_content_type":"text/x-python","patch_set":3,"id":"da86d52c_101f2a6d","line":70,"updated":"2015-02-05 11:48:31.000000000","message":"This appears to be a non-deterministic test. err.details is being returned as either \"404 Entity Not Found: Entity could not be found\" or \"Entity could not be found: 404 Entity Not Found\"","commit_id":"060e57c04a0b6e9d4099faf488f9b7e69db9beec"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"039ff426232480549bee1297e877ea877f992474","unresolved":false,"context_lines":[{"line_number":67,"context_line":"        err \u003d exc.from_response(mock_resp, HTML_MSG)"},{"line_number":68,"context_line":"        self.assertIsInstance(err, exc.HTTPNotFound)"},{"line_number":69,"context_line":"        self.assertEqual(\"Entity could not be found: 404 Entity Not Found\","},{"line_number":70,"context_line":"                         err.details)"}],"source_content_type":"text/x-python","patch_set":3,"id":"da86d52c_de8e4a78","line":70,"in_reply_to":"da86d52c_101f2a6d","updated":"2015-02-06 15:49:22.000000000","message":"+1 to Louis.\n\nThe error is:\n\ntesttools.matchers._impl.MismatchError: !\u003d:\nreference \u003d \u0027Entity could not be found: 404 Entity Not Found\u0027\nactual    \u003d \u0027404 Entity Not Found: Entity could not be found\u0027","commit_id":"060e57c04a0b6e9d4099faf488f9b7e69db9beec"}]}
