)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7198,"name":"Jay Bryant","email":"jungleboyj@electronicjungle.net","username":"jsbryant"},"change_message_id":"c4bf58c67abf4b8c89fb4067df3e2f5d41678bdd","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Cinder client should retry with Retry-After value"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"If a request fails but the response contains a \"Retry-After\","},{"line_number":10,"context_line":"the cinder client should wait the amount of time and then retry"},{"line_number":11,"context_line":"Cinder client should report a warning to user and continue with"},{"line_number":12,"context_line":"retry, so that user can cancel the operation if not interested"},{"line_number":13,"context_line":"in retry The value in \"Retry-After\" header will be in seconds."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"3aaa91ec_77891075","line":10,"range":{"start_line":10,"start_character":59,"end_line":10,"end_character":63},"updated":"2016-06-23 19:44:47.000000000","message":"Need \u0027.\u0027 here.","commit_id":"a70c93bcfa20b5f750b8a4cb538a75976385130a"},{"author":{"_account_id":7198,"name":"Jay Bryant","email":"jungleboyj@electronicjungle.net","username":"jsbryant"},"change_message_id":"c4bf58c67abf4b8c89fb4067df3e2f5d41678bdd","unresolved":false,"context_lines":[{"line_number":10,"context_line":"the cinder client should wait the amount of time and then retry"},{"line_number":11,"context_line":"Cinder client should report a warning to user and continue with"},{"line_number":12,"context_line":"retry, so that user can cancel the operation if not interested"},{"line_number":13,"context_line":"in retry The value in \"Retry-After\" header will be in seconds."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"How many times client should retry will be controlled by user"},{"line_number":16,"context_line":"through \"--retries\" argument to cinder api example,"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"3aaa91ec_1799acc4","line":13,"range":{"start_line":13,"start_character":3,"end_line":13,"end_character":8},"updated":"2016-06-23 19:44:47.000000000","message":"Need \u0027.\u0027 here.","commit_id":"a70c93bcfa20b5f750b8a4cb538a75976385130a"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"8857719461a58d0c9f575e459ba229057552d2d1","unresolved":false,"context_lines":[{"line_number":13,"context_line":"in retry. The value in \"Retry-After\" header will be in seconds."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"How many times client should retry will be controlled by user"},{"line_number":16,"context_line":"through \"--retries\" argument to cinder api example,"},{"line_number":17,"context_line":"$ cinder --retries 3 availability-zone-list"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"If request was not sucessful within the retries, client should"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"3aaa91ec_3c6f48fd","line":16,"range":{"start_line":16,"start_character":11,"end_line":16,"end_character":18},"updated":"2016-06-30 11:38:53.000000000","message":"nit: I believe this should not be retries, but max-retries","commit_id":"7d9f7914d19855b9408f54bb972af94ac5c010e7"},{"author":{"_account_id":11600,"name":"Michał Dulko","email":"michal.dulko@gmail.com","username":"dulek"},"change_message_id":"7e1571179278553e364b9df4ea950d8b7783fa5a","unresolved":false,"context_lines":[{"line_number":21,"context_line":"raise the exception."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"Change-Id: I99af957bfbbe3a202b148dc2fcafdd20b5d7cda0"},{"line_number":24,"context_line":"Partial-Bug: #1263069"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":15,"id":"1aa78d24_4c02840c","line":24,"range":{"start_line":24,"start_character":0,"end_line":24,"end_character":21},"updated":"2016-07-06 11:28:12.000000000","message":"I think this \"Closes-Bug\" for cinderclient. That\u0027s nothing critical however…","commit_id":"f8eef18297ec2dba4abf45f8ca57c40c2380cad9"}],"cinderclient/client.py":[{"author":{"_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},"change_message_id":"41870ae2c3c57c4ccff3d7076654121a95dacae8","unresolved":false,"context_lines":[{"line_number":90,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":91,"context_line":"        self.api_version \u003d kwargs.pop(\u0027api_version\u0027, None)"},{"line_number":92,"context_line":"        self.api_version \u003d self.api_version or api_versions.APIVersion()"},{"line_number":93,"context_line":"        self._logger \u003d logging.getLogger(__name__)"},{"line_number":94,"context_line":"        super(SessionClient, self).__init__(*args, **kwargs)"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    def request(self, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":1,"id":"3aaa91ec_32f4e184","line":93,"updated":"2016-06-23 08:45:47.000000000","message":"We don\u0027t need _logger in the client class","commit_id":"1433e177afa736b1c4a44cf43f943b06e2a6a3d2"},{"author":{"_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},"change_message_id":"41870ae2c3c57c4ccff3d7076654121a95dacae8","unresolved":false,"context_lines":[{"line_number":119,"context_line":"                    raise"},{"line_number":120,"context_line":"                msg \u003d \"Retrying after %s seconds.\" % overlim.retry_after"},{"line_number":121,"context_line":"                self._logger.debug(msg)"},{"line_number":122,"context_line":"                print(msg)"},{"line_number":123,"context_line":"                sleep(overlim.retry_after)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    def get(self, url, **kwargs):"}],"source_content_type":"text/x-python","patch_set":1,"id":"3aaa91ec_527d2de6","line":122,"updated":"2016-06-23 08:45:47.000000000","message":"It\u0027s used both for Python and CLI APIs. Please, don\u0027t use \u0027print\u0027 function here","commit_id":"1433e177afa736b1c4a44cf43f943b06e2a6a3d2"},{"author":{"_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},"change_message_id":"41870ae2c3c57c4ccff3d7076654121a95dacae8","unresolved":false,"context_lines":[{"line_number":160,"context_line":"                             \u0027auth plugin.\u0027)"},{"line_number":161,"context_line":""},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"class HTTPClient(object):"},{"line_number":164,"context_line":""},{"line_number":165,"context_line":"    SENSITIVE_HEADERS \u003d (\u0027X-Auth-Token\u0027, \u0027X-Subject-Token\u0027,)"},{"line_number":166,"context_line":"    USER_AGENT \u003d \u0027python-cinderclient\u0027"}],"source_content_type":"text/x-python","patch_set":1,"id":"3aaa91ec_d2cd9d5e","line":163,"updated":"2016-06-23 08:45:47.000000000","message":"We have to implement this feature for HTTPClient too","commit_id":"1433e177afa736b1c4a44cf43f943b06e2a6a3d2"},{"author":{"_account_id":7198,"name":"Jay Bryant","email":"jungleboyj@electronicjungle.net","username":"jsbryant"},"change_message_id":"c4bf58c67abf4b8c89fb4067df3e2f5d41678bdd","unresolved":false,"context_lines":[{"line_number":114,"context_line":"        while True:"},{"line_number":115,"context_line":"            try:"},{"line_number":116,"context_line":"                return self.request(url, method, **kwargs)"},{"line_number":117,"context_line":"            except exceptions.OverLimit as overlim:"},{"line_number":118,"context_line":"                if overlim.retry_after \u003c 1:"},{"line_number":119,"context_line":"                    raise"},{"line_number":120,"context_line":"                msg \u003d \"Retrying after %s seconds.\" % overlim.retry_after"}],"source_content_type":"text/x-python","patch_set":2,"id":"3aaa91ec_57bdf400","line":117,"range":{"start_line":117,"start_character":12,"end_line":117,"end_character":51},"updated":"2016-06-23 19:44:47.000000000","message":"Wouldn\u0027t it be possible to get stuck in this loop infinitely if a different exception was being returned?  Seems like a safer way to do this would be to check against the number of time you are looping and then error out.","commit_id":"a70c93bcfa20b5f750b8a4cb538a75976385130a"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"8857719461a58d0c9f575e459ba229057552d2d1","unresolved":false,"context_lines":[{"line_number":120,"context_line":"            except exceptions.OverLimit as overlim:"},{"line_number":121,"context_line":"                if attempts \u003e self.retries:"},{"line_number":122,"context_line":"                    raise"},{"line_number":123,"context_line":"                if overlim.retry_after \u003c 1:"},{"line_number":124,"context_line":"                    raise"},{"line_number":125,"context_line":"                msg \u003d \"Retrying after %s seconds.\" % overlim.retry_after"},{"line_number":126,"context_line":"                self._logger.debug(msg)"},{"line_number":127,"context_line":"                sleep(overlim.retry_after)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3aaa91ec_32b64ff9","line":124,"range":{"start_line":123,"start_character":0,"end_line":124,"end_character":25},"updated":"2016-06-30 11:38:53.000000000","message":"nit: Include this in the previous if:\n\n if attempts \u003e self.retries or overlim.retry_after \u003c 1:\n     raise","commit_id":"7d9f7914d19855b9408f54bb972af94ac5c010e7"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"8857719461a58d0c9f575e459ba229057552d2d1","unresolved":false,"context_lines":[{"line_number":331,"context_line":"            except exceptions.OverLimit as overlim:"},{"line_number":332,"context_line":"                if attempts \u003e self.retries:"},{"line_number":333,"context_line":"                    raise"},{"line_number":334,"context_line":"                if overlim.retry_after \u003c 1:"},{"line_number":335,"context_line":"                    raise"},{"line_number":336,"context_line":"                msg \u003d \"Retrying after %s seconds.\" % overlim.retry_after"},{"line_number":337,"context_line":"                self._logger.debug(msg)"},{"line_number":338,"context_line":"                sleep(overlim.retry_after)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3aaa91ec_52a83b8c","line":335,"range":{"start_line":334,"start_character":15,"end_line":335,"end_character":25},"updated":"2016-06-30 11:38:53.000000000","message":"ditto","commit_id":"7d9f7914d19855b9408f54bb972af94ac5c010e7"}],"cinderclient/exceptions.py":[{"author":{"_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},"change_message_id":"41870ae2c3c57c4ccff3d7076654121a95dacae8","unresolved":false,"context_lines":[{"line_number":158,"context_line":""},{"line_number":159,"context_line":"        self._get_rate_limit(response)"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"    def _get_rate_limit(self, resp):"},{"line_number":162,"context_line":"        if resp.headers:"},{"line_number":163,"context_line":"            utc_now \u003d datetime.utcnow()"},{"line_number":164,"context_line":"            value \u003d resp.headers.get(\u0027Retry-After\u0027, \u00271\u0027)"}],"source_content_type":"text/x-python","patch_set":1,"id":"3aaa91ec_128d657b","line":161,"updated":"2016-06-23 08:45:47.000000000","message":"Please, add unit test for this method","commit_id":"1433e177afa736b1c4a44cf43f943b06e2a6a3d2"},{"author":{"_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},"change_message_id":"41870ae2c3c57c4ccff3d7076654121a95dacae8","unresolved":false,"context_lines":[{"line_number":161,"context_line":"    def _get_rate_limit(self, resp):"},{"line_number":162,"context_line":"        if resp.headers:"},{"line_number":163,"context_line":"            utc_now \u003d datetime.utcnow()"},{"line_number":164,"context_line":"            value \u003d resp.headers.get(\u0027Retry-After\u0027, \u00271\u0027)"},{"line_number":165,"context_line":"            try:"},{"line_number":166,"context_line":"                value \u003d datetime.strptime(value, \u0027%a, %d %b %Y %H:%M:%S %Z\u0027)"},{"line_number":167,"context_line":"                if value \u003e utc_now:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3aaa91ec_929dd55b","line":164,"updated":"2016-06-23 08:45:47.000000000","message":"Why default value is string, instead of int?","commit_id":"1433e177afa736b1c4a44cf43f943b06e2a6a3d2"},{"author":{"_account_id":14305,"name":"Yuriy Nesenenko","email":"ynesenenko@mirantis.com","username":"yuriy_n"},"change_message_id":"11cd9913af6e7eb29e7b0fab7a144d1f9c1fb275","unresolved":false,"context_lines":[{"line_number":161,"context_line":"    def _get_rate_limit(self, resp):"},{"line_number":162,"context_line":"        if resp.headers:"},{"line_number":163,"context_line":"            utc_now \u003d datetime.utcnow()"},{"line_number":164,"context_line":"            value \u003d resp.headers.get(\u0027Retry-After\u0027, \u00271\u0027)"},{"line_number":165,"context_line":"            try:"},{"line_number":166,"context_line":"                value \u003d datetime.strptime(value, \u0027%a, %d %b %Y %H:%M:%S %Z\u0027)"},{"line_number":167,"context_line":"                if value \u003e utc_now:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3aaa91ec_d6a574a2","line":164,"in_reply_to":"3aaa91ec_929dd55b","updated":"2016-06-23 15:47:45.000000000","message":"Because the headers \"Retry-After\" value is string. Anyway that value is converted to int in the line 170","commit_id":"1433e177afa736b1c4a44cf43f943b06e2a6a3d2"},{"author":{"_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},"change_message_id":"41870ae2c3c57c4ccff3d7076654121a95dacae8","unresolved":false,"context_lines":[{"line_number":163,"context_line":"            utc_now \u003d datetime.utcnow()"},{"line_number":164,"context_line":"            value \u003d resp.headers.get(\u0027Retry-After\u0027, \u00271\u0027)"},{"line_number":165,"context_line":"            try:"},{"line_number":166,"context_line":"                value \u003d datetime.strptime(value, \u0027%a, %d %b %Y %H:%M:%S %Z\u0027)"},{"line_number":167,"context_line":"                if value \u003e utc_now:"},{"line_number":168,"context_line":"                    self.retry_after \u003d ((value - utc_now).second)"},{"line_number":169,"context_line":"            except ValueError:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3aaa91ec_f2cb7951","line":166,"updated":"2016-06-23 08:45:47.000000000","message":"Does date format depend in server\u0027s locale?","commit_id":"1433e177afa736b1c4a44cf43f943b06e2a6a3d2"},{"author":{"_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},"change_message_id":"41870ae2c3c57c4ccff3d7076654121a95dacae8","unresolved":false,"context_lines":[{"line_number":164,"context_line":"            value \u003d resp.headers.get(\u0027Retry-After\u0027, \u00271\u0027)"},{"line_number":165,"context_line":"            try:"},{"line_number":166,"context_line":"                value \u003d datetime.strptime(value, \u0027%a, %d %b %Y %H:%M:%S %Z\u0027)"},{"line_number":167,"context_line":"                if value \u003e utc_now:"},{"line_number":168,"context_line":"                    self.retry_after \u003d ((value - utc_now).second)"},{"line_number":169,"context_line":"            except ValueError:"},{"line_number":170,"context_line":"                self.retry_after \u003d int(value)"}],"source_content_type":"text/x-python","patch_set":1,"id":"3aaa91ec_92b835e7","line":167,"updated":"2016-06-23 08:45:47.000000000","message":"IMO, we should to add else statement too","commit_id":"1433e177afa736b1c4a44cf43f943b06e2a6a3d2"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"8857719461a58d0c9f575e459ba229057552d2d1","unresolved":false,"context_lines":[{"line_number":163,"context_line":"            utc_now \u003d datetime.utcnow()"},{"line_number":164,"context_line":"            value \u003d resp.headers.get(\u0027Retry-After\u0027, \u00271\u0027)"},{"line_number":165,"context_line":"            try:"},{"line_number":166,"context_line":"                value \u003d datetime.strptime(value, \u0027%a, %d %b %Y %H:%M:%S\u0027)"},{"line_number":167,"context_line":"                if value \u003e utc_now:"},{"line_number":168,"context_line":"                    self.retry_after \u003d ((value - utc_now).seconds)"},{"line_number":169,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3aaa91ec_4fad3883","line":166,"range":{"start_line":166,"start_character":16,"end_line":166,"end_character":73},"updated":"2016-06-30 11:38:53.000000000","message":"-1: This parsing is wrong, as it will fail with standard \"Sunday, 06-Nov-94 08:49:37 GMT\" response.\n\nYou should look at Retry-After header [1] and the date/time formats [2].\n\n[1]: https://tools.ietf.org/html/rfc7231#section-7.1.3\n[2]: http://tools.ietf.org/html/rfc7231#section-7.1.1.1","commit_id":"7d9f7914d19855b9408f54bb972af94ac5c010e7"},{"author":{"_account_id":14305,"name":"Yuriy Nesenenko","email":"ynesenenko@mirantis.com","username":"yuriy_n"},"change_message_id":"5a96efc0758911433b2f088377fbb6385e72975d","unresolved":false,"context_lines":[{"line_number":163,"context_line":"            utc_now \u003d datetime.utcnow()"},{"line_number":164,"context_line":"            value \u003d resp.headers.get(\u0027Retry-After\u0027, \u00271\u0027)"},{"line_number":165,"context_line":"            try:"},{"line_number":166,"context_line":"                value \u003d datetime.strptime(value, \u0027%a, %d %b %Y %H:%M:%S\u0027)"},{"line_number":167,"context_line":"                if value \u003e utc_now:"},{"line_number":168,"context_line":"                    self.retry_after \u003d ((value - utc_now).seconds)"},{"line_number":169,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3aaa91ec_a829329d","line":166,"range":{"start_line":166,"start_character":16,"end_line":166,"end_character":73},"in_reply_to":"3aaa91ec_4fad3883","updated":"2016-06-30 12:17:56.000000000","message":"Good catch. Thanks. Of course, it should be the format like that: \u0027%A, %d-%b-%y %H:%M:%S %Z\u0027","commit_id":"7d9f7914d19855b9408f54bb972af94ac5c010e7"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"8857719461a58d0c9f575e459ba229057552d2d1","unresolved":false,"context_lines":[{"line_number":165,"context_line":"            try:"},{"line_number":166,"context_line":"                value \u003d datetime.strptime(value, \u0027%a, %d %b %Y %H:%M:%S\u0027)"},{"line_number":167,"context_line":"                if value \u003e utc_now:"},{"line_number":168,"context_line":"                    self.retry_after \u003d ((value - utc_now).seconds)"},{"line_number":169,"context_line":"                else:"},{"line_number":170,"context_line":"                    self.retry_after \u003d 0"},{"line_number":171,"context_line":"            except ValueError:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3aaa91ec_4f32585f","line":168,"updated":"2016-06-30 11:38:53.000000000","message":"-1: What if the difference gives you 2 minutes and 10 seconds?  You will only wait 10 seconds.","commit_id":"7d9f7914d19855b9408f54bb972af94ac5c010e7"},{"author":{"_account_id":14305,"name":"Yuriy Nesenenko","email":"ynesenenko@mirantis.com","username":"yuriy_n"},"change_message_id":"5a96efc0758911433b2f088377fbb6385e72975d","unresolved":false,"context_lines":[{"line_number":165,"context_line":"            try:"},{"line_number":166,"context_line":"                value \u003d datetime.strptime(value, \u0027%a, %d %b %Y %H:%M:%S\u0027)"},{"line_number":167,"context_line":"                if value \u003e utc_now:"},{"line_number":168,"context_line":"                    self.retry_after \u003d ((value - utc_now).seconds)"},{"line_number":169,"context_line":"                else:"},{"line_number":170,"context_line":"                    self.retry_after \u003d 0"},{"line_number":171,"context_line":"            except ValueError:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3aaa91ec_6800ea34","line":168,"in_reply_to":"3aaa91ec_4f32585f","updated":"2016-06-30 12:17:56.000000000","message":"The difference (value - utc_now) is the \u0027datetime.timedelta\u0027 type. Only days, seconds and microseconds are stored internally. So 2 minutes 10 seconds is 130 seconds.","commit_id":"7d9f7914d19855b9408f54bb972af94ac5c010e7"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"59d38ad9be39d802a148a0e1dc4a65c4ed812fbe","unresolved":false,"context_lines":[{"line_number":165,"context_line":"            try:"},{"line_number":166,"context_line":"                value \u003d datetime.strptime(value, \u0027%a, %d %b %Y %H:%M:%S\u0027)"},{"line_number":167,"context_line":"                if value \u003e utc_now:"},{"line_number":168,"context_line":"                    self.retry_after \u003d ((value - utc_now).seconds)"},{"line_number":169,"context_line":"                else:"},{"line_number":170,"context_line":"                    self.retry_after \u003d 0"},{"line_number":171,"context_line":"            except ValueError:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3aaa91ec_2e4f0335","line":168,"in_reply_to":"3aaa91ec_6800ea34","updated":"2016-06-30 14:37:48.000000000","message":"Oooops, my bad.  :-)","commit_id":"7d9f7914d19855b9408f54bb972af94ac5c010e7"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"e4bd815fec995ff106851fb76fed9b0a4ac82d67","unresolved":false,"context_lines":[{"line_number":165,"context_line":"            utc_now \u003d timeutils.utcnow()"},{"line_number":166,"context_line":"            value \u003d resp.headers.get(\u0027Retry-After\u0027, \u00271\u0027)"},{"line_number":167,"context_line":"            try:"},{"line_number":168,"context_line":"                value \u003d datetime.strptime(value, \u0027%A, %d-%b-%y %H:%M:%S %Z\u0027)"},{"line_number":169,"context_line":"                if value \u003e utc_now:"},{"line_number":170,"context_line":"                    self.retry_after \u003d ((value - utc_now).seconds)"},{"line_number":171,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":5,"id":"3aaa91ec_cefc7f74","line":168,"range":{"start_line":168,"start_character":50,"end_line":168,"end_character":52},"updated":"2016-06-30 14:38:10.000000000","message":"-1: Unless I\u0027m mistaken this is not the preferred format, you had it mostly right in previous patch:\n\n value \u003d datetime.strptime(value, \u0027%a, %d %b %Y %H:%M:%S %Z\u0027)","commit_id":"3bbd8078f4004593ee6a03af301a3f2bd801e5d2"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"d9d5a2c6d3cd518e47f446a29db94621f1efdb87","unresolved":false,"context_lines":[{"line_number":163,"context_line":"    def _get_rate_limit(self, resp):"},{"line_number":164,"context_line":"        if resp.headers:"},{"line_number":165,"context_line":"            utc_now \u003d timeutils.utcnow()"},{"line_number":166,"context_line":"            value \u003d resp.headers.get(\u0027Retry-After\u0027, \u00271\u0027)"},{"line_number":167,"context_line":"            try:"},{"line_number":168,"context_line":"                value \u003d datetime.strptime(value, \u0027%a, %d %b %Y %H:%M:%S %Z\u0027)"},{"line_number":169,"context_line":"                if value \u003e utc_now:"}],"source_content_type":"text/x-python","patch_set":11,"id":"1aa78d24_0ae38106","line":166,"range":{"start_line":166,"start_character":51,"end_line":166,"end_character":56},"updated":"2016-07-05 09:29:54.000000000","message":"-1: If Retry-After is not present I think we should not retry.  We should have \u00270\u0027 as default.","commit_id":"63818281f796592610fb942836f0077ab23912d1"}],"cinderclient/tests/unit/test_client.py":[{"author":{"_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},"change_message_id":"41870ae2c3c57c4ccff3d7076654121a95dacae8","unresolved":false,"context_lines":[{"line_number":162,"context_line":"    def test_sessionclient_request_method_raises_overlimit("},{"line_number":163,"context_line":"            self, mock_request):"},{"line_number":164,"context_line":"        kwargs \u003d {"},{"line_number":165,"context_line":"            \"body\": {"},{"line_number":166,"context_line":"                \"volume\": {"},{"line_number":167,"context_line":"                    \"status\": \"creating\","},{"line_number":168,"context_line":"                    \"imageRef\": \"username\","}],"source_content_type":"text/x-python","patch_set":1,"id":"3aaa91ec_125f250f","line":165,"updated":"2016-06-23 08:45:47.000000000","message":"Request body for GET method looks incorrect","commit_id":"1433e177afa736b1c4a44cf43f943b06e2a6a3d2"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"f40496e2717b37fda4ad091d5435c753874a1051","unresolved":false,"context_lines":[{"line_number":158,"context_line":"        self.assertRaises(exceptions.BadRequest, session_client.request,"},{"line_number":159,"context_line":"                          mock.sentinel.url, \u0027POST\u0027, **kwargs)"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"    @mock.patch.object(adapter.Adapter, \u0027request\u0027)"},{"line_number":162,"context_line":"    def test_sessionclient_request_method_raises_overlimit("},{"line_number":163,"context_line":"            self, mock_request):"},{"line_number":164,"context_line":"        resp \u003d {"},{"line_number":165,"context_line":"            \"overLimitFault\": {"},{"line_number":166,"context_line":"                \"message\": \"This request was rate-limited.\","}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_880d9d92","line":163,"range":{"start_line":161,"start_character":0,"end_line":163,"end_character":32},"updated":"2016-07-05 18:13:51.000000000","message":"-1: You need to rebase your patch and change this to:\n\n    @mock.patch.object(cinderclient.client, \u0027_log_request_id\u0027)\n    @mock.patch.object(adapter.Adapter, \u0027request\u0027)            \n    def test_sessionclient_request_method_raises_overlimit(   \n            self, mock_request, mock_log):","commit_id":"7c7204a0abae2682b2c708afc9a47a9e0c29a392"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"1fa1e86e3de95b7075b9a2606bc1f44e46aa67bf","unresolved":false,"context_lines":[{"line_number":184,"context_line":"            session\u003dmock.Mock())"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":"        self.assertRaises(exceptions.OverLimit, session_client.request,"},{"line_number":187,"context_line":"                          mock.sentinel.url, \u0027GET\u0027)"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"    @mock.patch.object(exceptions, \u0027from_response\u0027)"},{"line_number":190,"context_line":"    def test_keystone_request_raises_auth_failure_exception("}],"source_content_type":"text/x-python","patch_set":14,"id":"1aa78d24_0e8cfe7d","line":187,"updated":"2016-07-06 07:13:02.000000000","message":"nit: Looking at the other tests, you should also add:\n\n self.assertEqual(1, mock_log.call_count)","commit_id":"9281e25abc0011b596336a87091c46eaeef050bc"}],"cinderclient/tests/unit/test_exceptions.py":[{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"8857719461a58d0c9f575e459ba229057552d2d1","unresolved":false,"context_lines":[{"line_number":38,"context_line":"        body \u003d {\u0027keys\u0027: ({})}"},{"line_number":39,"context_line":"        ex \u003d exceptions.from_response(response, body)"},{"line_number":40,"context_line":"        self.assertEqual(10, ex.retry_after)"},{"line_number":41,"context_line":"        self.assertIs(exceptions.OverLimit, type(ex))"}],"source_content_type":"text/x-python","patch_set":4,"id":"3aaa91ec_8f2600cc","line":41,"updated":"2016-06-30 11:38:53.000000000","message":"-1: Missing test for date/time","commit_id":"7d9f7914d19855b9408f54bb972af94ac5c010e7"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"e4bd815fec995ff106851fb76fed9b0a4ac82d67","unresolved":false,"context_lines":[{"line_number":47,"context_line":"    def test_from_response_overlimit_gmt(self, mock_utcnow):"},{"line_number":48,"context_line":"        response \u003d requests.Response()"},{"line_number":49,"context_line":"        response.status_code \u003d 413"},{"line_number":50,"context_line":"        response.headers \u003d {\"Retry-After\": \"Thursday, 30-Jun-16 12:43:20 GMT\"}"},{"line_number":51,"context_line":"        body \u003d {\u0027keys\u0027: ({})}"},{"line_number":52,"context_line":"        ex \u003d exceptions.from_response(response, body)"},{"line_number":53,"context_line":"        self.assertEqual(85, ex.retry_after)"}],"source_content_type":"text/x-python","patch_set":5,"id":"3aaa91ec_0e2967e6","line":50,"updated":"2016-06-30 14:38:10.000000000","message":"-1: This is obsolete RFC 850 format, not IMF-fixdate which is the preferred one.","commit_id":"3bbd8078f4004593ee6a03af301a3f2bd801e5d2"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"d9d5a2c6d3cd518e47f446a29db94621f1efdb87","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        ex \u003d exceptions.from_response(response, body)"},{"line_number":53,"context_line":"        self.assertEqual(85, ex.retry_after)"},{"line_number":54,"context_line":"        self.assertIs(exceptions.OverLimit, type(ex))"},{"line_number":55,"context_line":"        self.assertTrue(mock_utcnow.called)"}],"source_content_type":"text/x-python","patch_set":11,"id":"1aa78d24_aab6add9","line":55,"updated":"2016-07-05 09:29:54.000000000","message":"-1: We should also have a case without Retry-After header","commit_id":"63818281f796592610fb942836f0077ab23912d1"}],"cinderclient/tests/unit/test_http.py":[{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"8857719461a58d0c9f575e459ba229057552d2d1","unresolved":false,"context_lines":[{"line_number":180,"context_line":"        def test_get_call():"},{"line_number":181,"context_line":"            resp, body \u003d cl.get(\"/hi\")"},{"line_number":182,"context_line":"        self.assertRaises(exceptions.OverLimit, test_get_call)"},{"line_number":183,"context_line":"        self.assertEqual(self.requests, [mock_request])"},{"line_number":184,"context_line":""},{"line_number":185,"context_line":"    def test_rate_limit(self):"},{"line_number":186,"context_line":"        cl \u003d get_authed_client(retries\u003d1)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3aaa91ec_3243ef14","line":183,"updated":"2016-06-30 11:38:53.000000000","message":"-1: order is expected, observed","commit_id":"7d9f7914d19855b9408f54bb972af94ac5c010e7"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"8857719461a58d0c9f575e459ba229057552d2d1","unresolved":false,"context_lines":[{"line_number":198,"context_line":"            return resp, body"},{"line_number":199,"context_line":""},{"line_number":200,"context_line":"        resp, body \u003d test_get_call()"},{"line_number":201,"context_line":"        self.assertEqual(resp.status_code, 200)"},{"line_number":202,"context_line":"        self.assertEqual(self.requests, [])"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":"    def test_retry_limit(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"3aaa91ec_f23cc794","line":201,"updated":"2016-06-30 11:38:53.000000000","message":"-1: order is expected, observed","commit_id":"7d9f7914d19855b9408f54bb972af94ac5c010e7"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"8857719461a58d0c9f575e459ba229057552d2d1","unresolved":false,"context_lines":[{"line_number":199,"context_line":""},{"line_number":200,"context_line":"        resp, body \u003d test_get_call()"},{"line_number":201,"context_line":"        self.assertEqual(resp.status_code, 200)"},{"line_number":202,"context_line":"        self.assertEqual(self.requests, [])"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":"    def test_retry_limit(self):"},{"line_number":205,"context_line":"        cl \u003d get_authed_client(retries\u003d1)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3aaa91ec_72c29786","line":202,"updated":"2016-06-30 11:38:53.000000000","message":"-1: order is expected, observed","commit_id":"7d9f7914d19855b9408f54bb972af94ac5c010e7"}]}
