)]}'
{"tempest/lib/common/rest_client.py":[{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"f4fef230cbef5b467e14a0f9ef23aa6e687146e5","unresolved":false,"context_lines":[{"line_number":652,"context_line":"            date_timestamp \u003d self._parse_http_date(resp[\u0027date\u0027])"},{"line_number":653,"context_line":"            return int(retry_timestamp - date_timestamp)"},{"line_number":654,"context_line":"        except (ValueError, OverflowError) as e:"},{"line_number":655,"context_line":"            self.LOG.warning("},{"line_number":656,"context_line":"                \"failed to parse retry-after as http-date: %s\" % str(e)"},{"line_number":657,"context_line":"            )"},{"line_number":658,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9a061dce_8f40ae08","line":655,"updated":"2016-04-07 16:13:25.000000000","message":"This is wrong, I think, because in most Openstack deployments (i.e but not rackspace) retry-after is an integer, so you are going to log.warning() \"most of the time\".","commit_id":"fd5cea0a71da5835ab3f51dbf0a970c1ae7400f7"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"f4fef230cbef5b467e14a0f9ef23aa6e687146e5","unresolved":false,"context_lines":[{"line_number":660,"context_line":"            return int(resp[\u0027retry-after\u0027])"},{"line_number":661,"context_line":"        except ValueError as e:"},{"line_number":662,"context_line":"            self.LOG.error(\"also failed to parse retry-after as integer\")"},{"line_number":663,"context_line":"            self.LOG.exception(e)"},{"line_number":664,"context_line":"            raise"},{"line_number":665,"context_line":""},{"line_number":666,"context_line":"    def _parse_http_date(self, val):"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a061dce_4f77b69f","line":663,"updated":"2016-04-07 16:13:25.000000000","message":"Just use self.LOG.exception(\"also failed to parse retry-after as integer\"). LOG.exception automatically append a stack trace to the message.","commit_id":"fd5cea0a71da5835ab3f51dbf0a970c1ae7400f7"},{"author":{"_account_id":17716,"name":"Luz Cazares","email":"luz.cazares@intel.com","username":"luzcazares"},"change_message_id":"19ed57bed16c34edc2502216251f207d3876adbd","unresolved":false,"context_lines":[{"line_number":638,"context_line":"            delay \u003d self._get_retry_after_delay(resp)"},{"line_number":639,"context_line":"            self.LOG.debug("},{"line_number":640,"context_line":"                \"sleeping %s seconds based on retry-after header\", delay"},{"line_number":641,"context_line":"            )"},{"line_number":642,"context_line":"            time.sleep(delay)"},{"line_number":643,"context_line":"            resp, resp_body \u003d self._request(method, url,"},{"line_number":644,"context_line":"                                            headers\u003dheaders, body\u003dbody)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_ecb161e1","line":641,"range":{"start_line":641,"start_character":12,"end_line":641,"end_character":13},"updated":"2016-04-08 00:44:51.000000000","message":"In the sense to avoid extraneous whitespaces (PEP8).\nMove closing parenthesis to line 640 e.i \u0027delay)\u0027","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":11662,"name":"Paul Glass","email":"paul.glass@rackspace.com","username":"pglass"},"change_message_id":"114dc1bc50e0403bc66d86f74f4c4d0175f0c847","unresolved":false,"context_lines":[{"line_number":638,"context_line":"            delay \u003d self._get_retry_after_delay(resp)"},{"line_number":639,"context_line":"            self.LOG.debug("},{"line_number":640,"context_line":"                \"sleeping %s seconds based on retry-after header\", delay"},{"line_number":641,"context_line":"            )"},{"line_number":642,"context_line":"            time.sleep(delay)"},{"line_number":643,"context_line":"            resp, resp_body \u003d self._request(method, url,"},{"line_number":644,"context_line":"                                            headers\u003dheaders, body\u003dbody)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_d5ee7db3","line":641,"range":{"start_line":641,"start_character":12,"end_line":641,"end_character":13},"in_reply_to":"9a061dce_ecb161e1","updated":"2016-04-08 14:20:57.000000000","message":"There are already a set of pep8 checks that have passed on the code, so I\u0027m not going to change this.","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":17716,"name":"Luz Cazares","email":"luz.cazares@intel.com","username":"luzcazares"},"change_message_id":"19ed57bed16c34edc2502216251f207d3876adbd","unresolved":false,"context_lines":[{"line_number":647,"context_line":"        return resp, resp_body"},{"line_number":648,"context_line":""},{"line_number":649,"context_line":"    def _get_retry_after_delay(self, resp):"},{"line_number":650,"context_line":"        try:"},{"line_number":651,"context_line":"            return int(resp[\u0027retry-after\u0027])"},{"line_number":652,"context_line":"        except ValueError:"},{"line_number":653,"context_line":"            pass"},{"line_number":654,"context_line":""},{"line_number":655,"context_line":"        try:"},{"line_number":656,"context_line":"            retry_timestamp \u003d self._parse_http_date(resp[\u0027retry-after\u0027])"},{"line_number":657,"context_line":"            date_timestamp \u003d self._parse_http_date(resp[\u0027date\u0027])"},{"line_number":658,"context_line":"            return int(retry_timestamp - date_timestamp)"},{"line_number":659,"context_line":"        except (ValueError, OverflowError, KeyError):"},{"line_number":660,"context_line":"            pass"},{"line_number":661,"context_line":""},{"line_number":662,"context_line":"        raise ValueError("},{"line_number":663,"context_line":"            \"failed to parse retry-after header %r as either int or HTTP-date\""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_17f2de05","line":660,"range":{"start_line":650,"start_character":8,"end_line":660,"end_character":16},"updated":"2016-04-08 00:44:51.000000000","message":"Review Tempest coding guide section Exception Handling http://docs.openstack.org/developer/tempest/HACKING.html\n\nBasically try to avoid Try/catch blocks.\n\nIn this case, instead of try/catch blocks evaluate the variable first(avoid exception)\n if resp[\u0027retry-after\u0027] is integer\n    then return int value\n elif resp[\u0027retry-after\u0027] is a date\n    then process it as date","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":11662,"name":"Paul Glass","email":"paul.glass@rackspace.com","username":"pglass"},"change_message_id":"114dc1bc50e0403bc66d86f74f4c4d0175f0c847","unresolved":false,"context_lines":[{"line_number":647,"context_line":"        return resp, resp_body"},{"line_number":648,"context_line":""},{"line_number":649,"context_line":"    def _get_retry_after_delay(self, resp):"},{"line_number":650,"context_line":"        try:"},{"line_number":651,"context_line":"            return int(resp[\u0027retry-after\u0027])"},{"line_number":652,"context_line":"        except ValueError:"},{"line_number":653,"context_line":"            pass"},{"line_number":654,"context_line":""},{"line_number":655,"context_line":"        try:"},{"line_number":656,"context_line":"            retry_timestamp \u003d self._parse_http_date(resp[\u0027retry-after\u0027])"},{"line_number":657,"context_line":"            date_timestamp \u003d self._parse_http_date(resp[\u0027date\u0027])"},{"line_number":658,"context_line":"            return int(retry_timestamp - date_timestamp)"},{"line_number":659,"context_line":"        except (ValueError, OverflowError, KeyError):"},{"line_number":660,"context_line":"            pass"},{"line_number":661,"context_line":""},{"line_number":662,"context_line":"        raise ValueError("},{"line_number":663,"context_line":"            \"failed to parse retry-after header %r as either int or HTTP-date\""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_352539ae","line":660,"range":{"start_line":650,"start_character":8,"end_line":660,"end_character":16},"in_reply_to":"9a061dce_17f2de05","updated":"2016-04-08 14:20:57.000000000","message":"I\u0027m going to wait for more opinions on this, as any solution to avoid an exception on the date seems needlessly complicated and error-prone.","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"9c5638cd6d12b61f279afe413333f2226c3d6485","unresolved":false,"context_lines":[{"line_number":647,"context_line":"        return resp, resp_body"},{"line_number":648,"context_line":""},{"line_number":649,"context_line":"    def _get_retry_after_delay(self, resp):"},{"line_number":650,"context_line":"        try:"},{"line_number":651,"context_line":"            return int(resp[\u0027retry-after\u0027])"},{"line_number":652,"context_line":"        except ValueError:"},{"line_number":653,"context_line":"            pass"},{"line_number":654,"context_line":""},{"line_number":655,"context_line":"        try:"},{"line_number":656,"context_line":"            retry_timestamp \u003d self._parse_http_date(resp[\u0027retry-after\u0027])"},{"line_number":657,"context_line":"            date_timestamp \u003d self._parse_http_date(resp[\u0027date\u0027])"},{"line_number":658,"context_line":"            return int(retry_timestamp - date_timestamp)"},{"line_number":659,"context_line":"        except (ValueError, OverflowError, KeyError):"},{"line_number":660,"context_line":"            pass"},{"line_number":661,"context_line":""},{"line_number":662,"context_line":"        raise ValueError("},{"line_number":663,"context_line":"            \"failed to parse retry-after header %r as either int or HTTP-date\""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_c868a48a","line":660,"range":{"start_line":650,"start_character":8,"end_line":660,"end_character":16},"in_reply_to":"9a061dce_352539ae","updated":"2016-04-08 14:39:00.000000000","message":"Checking type (as in \"if resp[\u0027retry-after\u0027] is integer\") is not always very pythonic. Better ask forgiveness than permission, blah blah.\n\nSo, I am fine with the try/catch here.","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"0e29abe1b3f8b7641c31dee5603e4c537346ef95","unresolved":false,"context_lines":[{"line_number":647,"context_line":"        return resp, resp_body"},{"line_number":648,"context_line":""},{"line_number":649,"context_line":"    def _get_retry_after_delay(self, resp):"},{"line_number":650,"context_line":"        try:"},{"line_number":651,"context_line":"            return int(resp[\u0027retry-after\u0027])"},{"line_number":652,"context_line":"        except ValueError:"},{"line_number":653,"context_line":"            pass"},{"line_number":654,"context_line":""},{"line_number":655,"context_line":"        try:"},{"line_number":656,"context_line":"            retry_timestamp \u003d self._parse_http_date(resp[\u0027retry-after\u0027])"},{"line_number":657,"context_line":"            date_timestamp \u003d self._parse_http_date(resp[\u0027date\u0027])"},{"line_number":658,"context_line":"            return int(retry_timestamp - date_timestamp)"},{"line_number":659,"context_line":"        except (ValueError, OverflowError, KeyError):"},{"line_number":660,"context_line":"            pass"},{"line_number":661,"context_line":""},{"line_number":662,"context_line":"        raise ValueError("},{"line_number":663,"context_line":"            \"failed to parse retry-after header %r as either int or HTTP-date\""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_6e086492","line":660,"range":{"start_line":650,"start_character":8,"end_line":660,"end_character":16},"in_reply_to":"9a061dce_bc73e9e6","updated":"2016-04-09 13:31:23.000000000","message":"try/catch is a perf concern if an exception is raised often. This code ran for months without raising any ValueError, I don\"t know why it should raise a lot of errors now.\n\nThe current code doesn\"t catch the keyerror if \u0027retry-after\u0027 and so far no one complained about it.","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":8726,"name":"Victor Morales","email":"chipahuac@hotmail.com","username":"electrocucaracha"},"change_message_id":"efd3b515e683a636e725e42a1a7d6ae119f61390","unresolved":false,"context_lines":[{"line_number":647,"context_line":"        return resp, resp_body"},{"line_number":648,"context_line":""},{"line_number":649,"context_line":"    def _get_retry_after_delay(self, resp):"},{"line_number":650,"context_line":"        try:"},{"line_number":651,"context_line":"            return int(resp[\u0027retry-after\u0027])"},{"line_number":652,"context_line":"        except ValueError:"},{"line_number":653,"context_line":"            pass"},{"line_number":654,"context_line":""},{"line_number":655,"context_line":"        try:"},{"line_number":656,"context_line":"            retry_timestamp \u003d self._parse_http_date(resp[\u0027retry-after\u0027])"},{"line_number":657,"context_line":"            date_timestamp \u003d self._parse_http_date(resp[\u0027date\u0027])"},{"line_number":658,"context_line":"            return int(retry_timestamp - date_timestamp)"},{"line_number":659,"context_line":"        except (ValueError, OverflowError, KeyError):"},{"line_number":660,"context_line":"            pass"},{"line_number":661,"context_line":""},{"line_number":662,"context_line":"        raise ValueError("},{"line_number":663,"context_line":"            \"failed to parse retry-after header %r as either int or HTTP-date\""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_bc73e9e6","line":660,"range":{"start_line":650,"start_character":8,"end_line":660,"end_character":16},"in_reply_to":"9a061dce_c868a48a","updated":"2016-04-08 16:56:24.000000000","message":"Usually try/catch blocks are well know to have performance impact during the execution. \n\nBy other hand, the first block is not covering the case where the \"retry-after\" is not present giving the possibility to raise a KeyError.","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":17716,"name":"Luz Cazares","email":"luz.cazares@intel.com","username":"luzcazares"},"change_message_id":"19ed57bed16c34edc2502216251f207d3876adbd","unresolved":false,"context_lines":[{"line_number":659,"context_line":"        except (ValueError, OverflowError, KeyError):"},{"line_number":660,"context_line":"            pass"},{"line_number":661,"context_line":""},{"line_number":662,"context_line":"        raise ValueError("},{"line_number":663,"context_line":"            \"failed to parse retry-after header %r as either int or HTTP-date\""},{"line_number":664,"context_line":"            % resp[\u0027retry-after\u0027]"},{"line_number":665,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_77b87a11","line":662,"range":{"start_line":662,"start_character":8,"end_line":662,"end_character":24},"updated":"2016-04-08 00:44:51.000000000","message":"Instead raising ValueError raise a tempest exception, for instance \u0027exceptions.InvalidHTTPResponseBody\u0027\nReview exceptions class for additional reference","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"9c5638cd6d12b61f279afe413333f2226c3d6485","unresolved":false,"context_lines":[{"line_number":659,"context_line":"        except (ValueError, OverflowError, KeyError):"},{"line_number":660,"context_line":"            pass"},{"line_number":661,"context_line":""},{"line_number":662,"context_line":"        raise ValueError("},{"line_number":663,"context_line":"            \"failed to parse retry-after header %r as either int or HTTP-date\""},{"line_number":664,"context_line":"            % resp[\u0027retry-after\u0027]"},{"line_number":665,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_68a4f807","line":662,"range":{"start_line":662,"start_character":8,"end_line":662,"end_character":24},"in_reply_to":"9a061dce_7557b1ca","updated":"2016-04-08 14:39:00.000000000","message":"ValueError is good, imo. Python stdlib has dozen (maybe one hundred) alreade defined exceptions, its good to use them when it makes sense. Here, imo, it makes sense: we got a value that we couldn\u0027t understand, it\u0027s a value error.","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":11662,"name":"Paul Glass","email":"paul.glass@rackspace.com","username":"pglass"},"change_message_id":"114dc1bc50e0403bc66d86f74f4c4d0175f0c847","unresolved":false,"context_lines":[{"line_number":659,"context_line":"        except (ValueError, OverflowError, KeyError):"},{"line_number":660,"context_line":"            pass"},{"line_number":661,"context_line":""},{"line_number":662,"context_line":"        raise ValueError("},{"line_number":663,"context_line":"            \"failed to parse retry-after header %r as either int or HTTP-date\""},{"line_number":664,"context_line":"            % resp[\u0027retry-after\u0027]"},{"line_number":665,"context_line":"        )"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_7557b1ca","line":662,"range":{"start_line":662,"start_character":8,"end_line":662,"end_character":24},"in_reply_to":"9a061dce_77b87a11","updated":"2016-04-08 14:20:57.000000000","message":"Honestly, none of those exceptions seem appropriate, other than the base TempestException.","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":17716,"name":"Luz Cazares","email":"luz.cazares@intel.com","username":"luzcazares"},"change_message_id":"19ed57bed16c34edc2502216251f207d3876adbd","unresolved":false,"context_lines":[{"line_number":664,"context_line":"            % resp[\u0027retry-after\u0027]"},{"line_number":665,"context_line":"        )"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"    def _parse_http_date(self, val):"},{"line_number":668,"context_line":"        \"\"\"Parse an HTTP date, like \u0027Fri, 31 Dec 1999 23:59:59 GMT\u0027."},{"line_number":669,"context_line":""},{"line_number":670,"context_line":"        Return an epoch timestamp (float), as returned by time.mktime()."},{"line_number":671,"context_line":"        \"\"\""},{"line_number":672,"context_line":"        parts \u003d email.utils.parsedate(val)"},{"line_number":673,"context_line":"        if not parts:"},{"line_number":674,"context_line":"            raise ValueError(\"Failed to parse date %s\" % val)"},{"line_number":675,"context_line":"        return time.mktime(parts)"},{"line_number":676,"context_line":""},{"line_number":677,"context_line":"    def _error_checker(self, method, url,"},{"line_number":678,"context_line":"                       headers, body, resp, resp_body):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_121f8c5b","line":675,"range":{"start_line":667,"start_character":4,"end_line":675,"end_character":33},"updated":"2016-04-08 00:44:51.000000000","message":"explore other parser options (not email.utils library)","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":11662,"name":"Paul Glass","email":"paul.glass@rackspace.com","username":"pglass"},"change_message_id":"114dc1bc50e0403bc66d86f74f4c4d0175f0c847","unresolved":false,"context_lines":[{"line_number":664,"context_line":"            % resp[\u0027retry-after\u0027]"},{"line_number":665,"context_line":"        )"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"    def _parse_http_date(self, val):"},{"line_number":668,"context_line":"        \"\"\"Parse an HTTP date, like \u0027Fri, 31 Dec 1999 23:59:59 GMT\u0027."},{"line_number":669,"context_line":""},{"line_number":670,"context_line":"        Return an epoch timestamp (float), as returned by time.mktime()."},{"line_number":671,"context_line":"        \"\"\""},{"line_number":672,"context_line":"        parts \u003d email.utils.parsedate(val)"},{"line_number":673,"context_line":"        if not parts:"},{"line_number":674,"context_line":"            raise ValueError(\"Failed to parse date %s\" % val)"},{"line_number":675,"context_line":"        return time.mktime(parts)"},{"line_number":676,"context_line":""},{"line_number":677,"context_line":"    def _error_checker(self, method, url,"},{"line_number":678,"context_line":"                       headers, body, resp, resp_body):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_f2759732","line":675,"range":{"start_line":667,"start_character":4,"end_line":675,"end_character":33},"in_reply_to":"9a061dce_121f8c5b","updated":"2016-04-08 14:20:57.000000000","message":"Why? The function in email.utils is explicitly designed for parsing http date formatted headers. It exists and works in both python 2 and 3.\n\nUsing the time (or datetime) module would be easy, but doesn\u0027t seem any better.","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"0e29abe1b3f8b7641c31dee5603e4c537346ef95","unresolved":false,"context_lines":[{"line_number":664,"context_line":"            % resp[\u0027retry-after\u0027]"},{"line_number":665,"context_line":"        )"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"    def _parse_http_date(self, val):"},{"line_number":668,"context_line":"        \"\"\"Parse an HTTP date, like \u0027Fri, 31 Dec 1999 23:59:59 GMT\u0027."},{"line_number":669,"context_line":""},{"line_number":670,"context_line":"        Return an epoch timestamp (float), as returned by time.mktime()."},{"line_number":671,"context_line":"        \"\"\""},{"line_number":672,"context_line":"        parts \u003d email.utils.parsedate(val)"},{"line_number":673,"context_line":"        if not parts:"},{"line_number":674,"context_line":"            raise ValueError(\"Failed to parse date %s\" % val)"},{"line_number":675,"context_line":"        return time.mktime(parts)"},{"line_number":676,"context_line":""},{"line_number":677,"context_line":"    def _error_checker(self, method, url,"},{"line_number":678,"context_line":"                       headers, body, resp, resp_body):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_4eada087","line":675,"range":{"start_line":667,"start_character":4,"end_line":675,"end_character":33},"in_reply_to":"9a061dce_66fd496e","updated":"2016-04-09 13:31:23.000000000","message":"I prefer to import module not class. No need for some custom code for parsing RFC standard format, it\u0027s just that you mentioned `time` or `datetime` as an alternative solution. But if this modules don\u0027t provide a solution out of the box, I am fine with `emails.utils`","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":11662,"name":"Paul Glass","email":"paul.glass@rackspace.com","username":"pglass"},"change_message_id":"20b885c13c521715895f2d596ba3431504149b42","unresolved":false,"context_lines":[{"line_number":664,"context_line":"            % resp[\u0027retry-after\u0027]"},{"line_number":665,"context_line":"        )"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"    def _parse_http_date(self, val):"},{"line_number":668,"context_line":"        \"\"\"Parse an HTTP date, like \u0027Fri, 31 Dec 1999 23:59:59 GMT\u0027."},{"line_number":669,"context_line":""},{"line_number":670,"context_line":"        Return an epoch timestamp (float), as returned by time.mktime()."},{"line_number":671,"context_line":"        \"\"\""},{"line_number":672,"context_line":"        parts \u003d email.utils.parsedate(val)"},{"line_number":673,"context_line":"        if not parts:"},{"line_number":674,"context_line":"            raise ValueError(\"Failed to parse date %s\" % val)"},{"line_number":675,"context_line":"        return time.mktime(parts)"},{"line_number":676,"context_line":""},{"line_number":677,"context_line":"    def _error_checker(self, method, url,"},{"line_number":678,"context_line":"                       headers, body, resp, resp_body):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_66fd496e","line":675,"range":{"start_line":667,"start_character":4,"end_line":675,"end_character":33},"in_reply_to":"9a061dce_c89b8471","updated":"2016-04-08 15:09:09.000000000","message":"Does tempest really want to use custom code for parsing an RFC standard format? It would be one thing if it was an external dependency, but the `email` module is in the standard library.\n\nWhat if I commented the email.utils import, and/or did `from email.utils import parsedate` so it\u0027s clearer why we\u0027re using that module?","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"9c5638cd6d12b61f279afe413333f2226c3d6485","unresolved":false,"context_lines":[{"line_number":664,"context_line":"            % resp[\u0027retry-after\u0027]"},{"line_number":665,"context_line":"        )"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":"    def _parse_http_date(self, val):"},{"line_number":668,"context_line":"        \"\"\"Parse an HTTP date, like \u0027Fri, 31 Dec 1999 23:59:59 GMT\u0027."},{"line_number":669,"context_line":""},{"line_number":670,"context_line":"        Return an epoch timestamp (float), as returned by time.mktime()."},{"line_number":671,"context_line":"        \"\"\""},{"line_number":672,"context_line":"        parts \u003d email.utils.parsedate(val)"},{"line_number":673,"context_line":"        if not parts:"},{"line_number":674,"context_line":"            raise ValueError(\"Failed to parse date %s\" % val)"},{"line_number":675,"context_line":"        return time.mktime(parts)"},{"line_number":676,"context_line":""},{"line_number":677,"context_line":"    def _error_checker(self, method, url,"},{"line_number":678,"context_line":"                       headers, body, resp, resp_body):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_c89b8471","line":675,"range":{"start_line":667,"start_character":4,"end_line":675,"end_character":33},"in_reply_to":"9a061dce_f2759732","updated":"2016-04-08 14:39:00.000000000","message":"I agree with Luz here. If you can make it work with time or datetime it would be better. Those 2 modules are more well known that the email one, and it looks strange to import an email related module in Tempest.","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"9c5638cd6d12b61f279afe413333f2226c3d6485","unresolved":false,"context_lines":[{"line_number":800,"context_line":"        if (not isinstance(resp_body, collections.Mapping) or"},{"line_number":801,"context_line":"                \u0027retry-after\u0027 not in resp):"},{"line_number":802,"context_line":"            return True"},{"line_number":803,"context_line":"        return \u0027exceed\u0027 in resp_body.get(\u0027message\u0027, \u0027blabla\u0027)"},{"line_number":804,"context_line":""},{"line_number":805,"context_line":"    def wait_for_resource_deletion(self, id):"},{"line_number":806,"context_line":"        \"\"\"Waits for a resource to be deleted"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_08645c47","line":803,"updated":"2016-04-08 14:39:00.000000000","message":"Are you sure about this one ? I mean I read the commit message but as we have no unit tests nor func tests for this code, I just want to check with you whether you actually tested this. (your simple answer will be enough).","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":11662,"name":"Paul Glass","email":"paul.glass@rackspace.com","username":"pglass"},"change_message_id":"20b885c13c521715895f2d596ba3431504149b42","unresolved":false,"context_lines":[{"line_number":800,"context_line":"        if (not isinstance(resp_body, collections.Mapping) or"},{"line_number":801,"context_line":"                \u0027retry-after\u0027 not in resp):"},{"line_number":802,"context_line":"            return True"},{"line_number":803,"context_line":"        return \u0027exceed\u0027 in resp_body.get(\u0027message\u0027, \u0027blabla\u0027)"},{"line_number":804,"context_line":""},{"line_number":805,"context_line":"    def wait_for_resource_deletion(self, id):"},{"line_number":806,"context_line":"        \"\"\"Waits for a resource to be deleted"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_8b222600","line":803,"in_reply_to":"9a061dce_08645c47","updated":"2016-04-08 15:09:09.000000000","message":"I\u0027m pretty confident about it, and it works for me, verifying via log statements.\n\nI tracked down https://github.com/openstack/tempest/commit/55f6d8c0fb401a825f4721410612a57a29a3c36e. You\u0027ll notice that before that fix, the call was:\n\n    self.is_absolute_limit(resp_body[\u0027overLimit\u0027])\n\nThey switched this to:\n\n    self.is_absolute_limit(resp, self._parse_resp(resp_body))\n\nself._parse_resp does the same \"unwrapping\" as resp_body[\u0027overLimit\u0027].\n\nBUT they also put a resp_body.get(\u0027overLimit\u0027, None) inside the is_absolute_limit function, effectively doing the \"unwrapping\" twice, which always produced an error.\n\nThis is on response bodies that look like:\n\n    { \"overLimit\": { \"message\": \"...\" }}","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":11662,"name":"Paul Glass","email":"paul.glass@rackspace.com","username":"pglass"},"change_message_id":"a2591cc7c1655e0b4096596ddacfe3292dea25fa","unresolved":false,"context_lines":[{"line_number":800,"context_line":"        if (not isinstance(resp_body, collections.Mapping) or"},{"line_number":801,"context_line":"                \u0027retry-after\u0027 not in resp):"},{"line_number":802,"context_line":"            return True"},{"line_number":803,"context_line":"        return \u0027exceed\u0027 in resp_body.get(\u0027message\u0027, \u0027blabla\u0027)"},{"line_number":804,"context_line":""},{"line_number":805,"context_line":"    def wait_for_resource_deletion(self, id):"},{"line_number":806,"context_line":"        \"\"\"Waits for a resource to be deleted"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a061dce_e6a95926","line":803,"in_reply_to":"9a061dce_8b222600","updated":"2016-04-08 15:10:49.000000000","message":"I can certainly add a test case to avoid regressions, of course.","commit_id":"bc5320977e0e4264092a5591969739fa0c2c58c5"},{"author":{"_account_id":7428,"name":"Yaroslav Lobankov","email":"lobankovyv@gmail.com","username":"ylobankov"},"change_message_id":"f34012452244912ef6674b611dcfa7eed511a0b8","unresolved":false,"context_lines":[{"line_number":636,"context_line":"            retry +\u003d 1"},{"line_number":637,"context_line":"            delay \u003d self._get_retry_after_delay(resp)"},{"line_number":638,"context_line":"            self.LOG.debug("},{"line_number":639,"context_line":"                \"sleeping %s seconds based on retry-after header\", delay"},{"line_number":640,"context_line":"            )"},{"line_number":641,"context_line":"            time.sleep(delay)"},{"line_number":642,"context_line":"            resp, resp_body \u003d self._request(method, url,"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_9cb9e9ce","line":639,"range":{"start_line":639,"start_character":65,"end_line":639,"end_character":72},"updated":"2016-04-21 13:54:58.000000000","message":"It looks like it should be \u0027% delay\u0027.","commit_id":"2915a7de48972e775cd1a695f6bfeb38fe75956b"},{"author":{"_account_id":7428,"name":"Yaroslav Lobankov","email":"lobankovyv@gmail.com","username":"ylobankov"},"change_message_id":"f34012452244912ef6674b611dcfa7eed511a0b8","unresolved":false,"context_lines":[{"line_number":636,"context_line":"            retry +\u003d 1"},{"line_number":637,"context_line":"            delay \u003d self._get_retry_after_delay(resp)"},{"line_number":638,"context_line":"            self.LOG.debug("},{"line_number":639,"context_line":"                \"sleeping %s seconds based on retry-after header\", delay"},{"line_number":640,"context_line":"            )"},{"line_number":641,"context_line":"            time.sleep(delay)"},{"line_number":642,"context_line":"            resp, resp_body \u003d self._request(method, url,"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_0d6da5cc","line":639,"range":{"start_line":639,"start_character":17,"end_line":639,"end_character":18},"updated":"2016-04-21 13:54:58.000000000","message":"s -\u003e S","commit_id":"2915a7de48972e775cd1a695f6bfeb38fe75956b"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"4d042f48de38ba3164958cf57c934d155f6937ba","unresolved":false,"context_lines":[{"line_number":636,"context_line":"            retry +\u003d 1"},{"line_number":637,"context_line":"            delay \u003d self._get_retry_after_delay(resp)"},{"line_number":638,"context_line":"            self.LOG.debug("},{"line_number":639,"context_line":"                \"sleeping %s seconds based on retry-after header\", delay"},{"line_number":640,"context_line":"            )"},{"line_number":641,"context_line":"            time.sleep(delay)"},{"line_number":642,"context_line":"            resp, resp_body \u003d self._request(method, url,"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_ca069c84","line":639,"range":{"start_line":639,"start_character":65,"end_line":639,"end_character":72},"in_reply_to":"1a122d0e_9cb9e9ce","updated":"2016-04-23 17:11:21.000000000","message":"\", delay\" is actually better. http://docs.openstack.org/developer/oslo.i18n/guidelines.html#adding-variables-to-log-messages","commit_id":"2915a7de48972e775cd1a695f6bfeb38fe75956b"},{"author":{"_account_id":7428,"name":"Yaroslav Lobankov","email":"lobankovyv@gmail.com","username":"ylobankov"},"change_message_id":"9aaeca7c3cf3398a9b0c090b171d6abdd20f7e8f","unresolved":false,"context_lines":[{"line_number":636,"context_line":"            retry +\u003d 1"},{"line_number":637,"context_line":"            delay \u003d self._get_retry_after_delay(resp)"},{"line_number":638,"context_line":"            self.LOG.debug("},{"line_number":639,"context_line":"                \"sleeping %s seconds based on retry-after header\", delay"},{"line_number":640,"context_line":"            )"},{"line_number":641,"context_line":"            time.sleep(delay)"},{"line_number":642,"context_line":"            resp, resp_body \u003d self._request(method, url,"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_537d20b0","line":639,"range":{"start_line":639,"start_character":65,"end_line":639,"end_character":72},"in_reply_to":"1a122d0e_ca069c84","updated":"2016-04-24 16:30:18.000000000","message":"Thanks, Jordan :) For some reason, I thought that it wouldn\u0027t work.","commit_id":"2915a7de48972e775cd1a695f6bfeb38fe75956b"},{"author":{"_account_id":5803,"name":"Attila Fazekas","email":"afazekas@redhat.com","username":"afazekas"},"change_message_id":"bf3668a462b1e60660ce1487df75d38e7534f279","unresolved":false,"context_lines":[{"line_number":638,"context_line":"            self.LOG.debug("},{"line_number":639,"context_line":"                \"sleeping %s seconds based on retry-after header\", delay"},{"line_number":640,"context_line":"            )"},{"line_number":641,"context_line":"            time.sleep(delay)"},{"line_number":642,"context_line":"            resp, resp_body \u003d self._request(method, url,"},{"line_number":643,"context_line":"                                            headers\u003dheaders, body\u003dbody)"},{"line_number":644,"context_line":"        self._error_checker(method, url, headers, body,"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_1e763bd8","line":641,"updated":"2016-05-03 11:03:32.000000000","message":"If this is a negtive number it will raise an exception here.","commit_id":"2915a7de48972e775cd1a695f6bfeb38fe75956b"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"562f5a6e0de2c4c3fa7c2f368e00b1c15bd6d5ed","unresolved":false,"context_lines":[{"line_number":648,"context_line":"    def _get_retry_after_delay(self, resp):"},{"line_number":649,"context_line":"        try:"},{"line_number":650,"context_line":"            return int(resp[\u0027retry-after\u0027])"},{"line_number":651,"context_line":"        except (ValueError, KeyError):"},{"line_number":652,"context_line":"            pass"},{"line_number":653,"context_line":""},{"line_number":654,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_af5bed20","line":651,"updated":"2016-04-28 22:41:04.000000000","message":"I don\u0027t think KeyError can ever be raised here, as you use get().\nAttributeError could be raised if resp is None.","commit_id":"2915a7de48972e775cd1a695f6bfeb38fe75956b"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"aac668ccfebc49da03eba3fbd9064f5f0e063adc","unresolved":false,"context_lines":[{"line_number":648,"context_line":"    def _get_retry_after_delay(self, resp):"},{"line_number":649,"context_line":"        try:"},{"line_number":650,"context_line":"            return int(resp[\u0027retry-after\u0027])"},{"line_number":651,"context_line":"        except (ValueError, KeyError):"},{"line_number":652,"context_line":"            pass"},{"line_number":653,"context_line":""},{"line_number":654,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_228407d1","line":651,"in_reply_to":"1a122d0e_af5bed20","updated":"2016-04-29 13:32:49.000000000","message":"But if `resp` is a dict without a `retry-after` key, then a KeyError is going to be raised, isn\u0027t it ?","commit_id":"2915a7de48972e775cd1a695f6bfeb38fe75956b"},{"author":{"_account_id":5803,"name":"Attila Fazekas","email":"afazekas@redhat.com","username":"afazekas"},"change_message_id":"bf3668a462b1e60660ce1487df75d38e7534f279","unresolved":false,"context_lines":[{"line_number":653,"context_line":""},{"line_number":654,"context_line":"        try:"},{"line_number":655,"context_line":"            retry_timestamp \u003d self._parse_http_date(resp[\u0027retry-after\u0027])"},{"line_number":656,"context_line":"            date_timestamp \u003d self._parse_http_date(resp[\u0027date\u0027])"},{"line_number":657,"context_line":"            return int(retry_timestamp - date_timestamp)"},{"line_number":658,"context_line":"        except (ValueError, OverflowError, KeyError):"},{"line_number":659,"context_line":"            pass"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_5efb9347","line":656,"updated":"2016-05-03 11:03:32.000000000","message":"The date header is not mandatory, wouldn\u0027t be better to try to use the local timestamp at least in case of the date is missing ?","commit_id":"2915a7de48972e775cd1a695f6bfeb38fe75956b"},{"author":{"_account_id":7428,"name":"Yaroslav Lobankov","email":"lobankovyv@gmail.com","username":"ylobankov"},"change_message_id":"f34012452244912ef6674b611dcfa7eed511a0b8","unresolved":false,"context_lines":[{"line_number":656,"context_line":"            date_timestamp \u003d self._parse_http_date(resp[\u0027date\u0027])"},{"line_number":657,"context_line":"            return int(retry_timestamp - date_timestamp)"},{"line_number":658,"context_line":"        except (ValueError, OverflowError, KeyError):"},{"line_number":659,"context_line":"            pass"},{"line_number":660,"context_line":""},{"line_number":661,"context_line":"        raise ValueError("},{"line_number":662,"context_line":"            \"failed to parse retry-after header %r as either int or HTTP-date.\""}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_cd160d58","line":659,"range":{"start_line":659,"start_character":12,"end_line":659,"end_character":16},"updated":"2016-04-21 13:54:58.000000000","message":"raise ValueError(...) can be put here.","commit_id":"2915a7de48972e775cd1a695f6bfeb38fe75956b"},{"author":{"_account_id":7428,"name":"Yaroslav Lobankov","email":"lobankovyv@gmail.com","username":"ylobankov"},"change_message_id":"9aaeca7c3cf3398a9b0c090b171d6abdd20f7e8f","unresolved":false,"context_lines":[{"line_number":656,"context_line":"            date_timestamp \u003d self._parse_http_date(resp[\u0027date\u0027])"},{"line_number":657,"context_line":"            return int(retry_timestamp - date_timestamp)"},{"line_number":658,"context_line":"        except (ValueError, OverflowError, KeyError):"},{"line_number":659,"context_line":"            pass"},{"line_number":660,"context_line":""},{"line_number":661,"context_line":"        raise ValueError("},{"line_number":662,"context_line":"            \"failed to parse retry-after header %r as either int or HTTP-date.\""}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_9334d8fb","line":659,"range":{"start_line":659,"start_character":12,"end_line":659,"end_character":16},"in_reply_to":"1a122d0e_6af8287d","updated":"2016-04-24 16:30:18.000000000","message":"Jordan, I meant we could move\n\n\nraise ValueError(\n            \"failed to parse retry-after header %r as either int or HTTP-date.\"\n            % resp.get(\u0027retry-after\u0027)\n        )\n\n\nto here not to write \"pass\" here and not to raise the exception in L661.","commit_id":"2915a7de48972e775cd1a695f6bfeb38fe75956b"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"4d042f48de38ba3164958cf57c934d155f6937ba","unresolved":false,"context_lines":[{"line_number":656,"context_line":"            date_timestamp \u003d self._parse_http_date(resp[\u0027date\u0027])"},{"line_number":657,"context_line":"            return int(retry_timestamp - date_timestamp)"},{"line_number":658,"context_line":"        except (ValueError, OverflowError, KeyError):"},{"line_number":659,"context_line":"            pass"},{"line_number":660,"context_line":""},{"line_number":661,"context_line":"        raise ValueError("},{"line_number":662,"context_line":"            \"failed to parse retry-after header %r as either int or HTTP-date.\""}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_6af8287d","line":659,"range":{"start_line":659,"start_character":12,"end_line":659,"end_character":16},"in_reply_to":"1a122d0e_cd160d58","updated":"2016-04-23 17:11:21.000000000","message":"If we do so, we would duplicate the \"raise ValueError\" line.","commit_id":"2915a7de48972e775cd1a695f6bfeb38fe75956b"},{"author":{"_account_id":7428,"name":"Yaroslav Lobankov","email":"lobankovyv@gmail.com","username":"ylobankov"},"change_message_id":"f34012452244912ef6674b611dcfa7eed511a0b8","unresolved":false,"context_lines":[{"line_number":659,"context_line":"            pass"},{"line_number":660,"context_line":""},{"line_number":661,"context_line":"        raise ValueError("},{"line_number":662,"context_line":"            \"failed to parse retry-after header %r as either int or HTTP-date.\""},{"line_number":663,"context_line":"            % resp.get(\u0027retry-after\u0027)"},{"line_number":664,"context_line":"        )"},{"line_number":665,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_e80c973d","line":662,"range":{"start_line":662,"start_character":13,"end_line":662,"end_character":14},"updated":"2016-04-21 13:54:58.000000000","message":"f -\u003e F","commit_id":"2915a7de48972e775cd1a695f6bfeb38fe75956b"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"562f5a6e0de2c4c3fa7c2f368e00b1c15bd6d5ed","unresolved":false,"context_lines":[{"line_number":660,"context_line":""},{"line_number":661,"context_line":"        raise ValueError("},{"line_number":662,"context_line":"            \"failed to parse retry-after header %r as either int or HTTP-date.\""},{"line_number":663,"context_line":"            % resp.get(\u0027retry-after\u0027)"},{"line_number":664,"context_line":"        )"},{"line_number":665,"context_line":""},{"line_number":666,"context_line":"    def _parse_http_date(self, val):"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a122d0e_cf490962","line":663,"updated":"2016-04-28 22:41:04.000000000","message":"Is the KeyError is raised here, then the exception above is skipped. But in fact KeyError should never be raised as you use get()","commit_id":"2915a7de48972e775cd1a695f6bfeb38fe75956b"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"882bc4422a71bfc0cbe95c85a0a8032609b36c1e","unresolved":false,"context_lines":[{"line_number":663,"context_line":"            pass"},{"line_number":664,"context_line":""},{"line_number":665,"context_line":"        try:"},{"line_number":666,"context_line":"            retry_timestamp \u003d self._parse_http_date(resp[\u0027retry-after\u0027])"},{"line_number":667,"context_line":"            date_timestamp \u003d self._parse_http_date(resp[\u0027date\u0027])"},{"line_number":668,"context_line":"            delay \u003d int(retry_timestamp - date_timestamp)"},{"line_number":669,"context_line":"        except (ValueError, OverflowError, KeyError):"}],"source_content_type":"text/x-python","patch_set":6,"id":"bab6814e_cbd92d59","line":666,"updated":"2016-05-20 14:54:02.000000000","message":"I\u0027d probably prefer if this was an if else or something like that. But, this works fine since it can\u0027t be an int and a parsable datetime","commit_id":"119565acc6f7e275028369a08413e93e1152784c"}],"tempest/tests/lib/test_rest_client.py":[{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"f4fef230cbef5b467e14a0f9ef23aa6e687146e5","unresolved":false,"context_lines":[{"line_number":552,"context_line":"        super(TestRetryAfter, self).setUp()"},{"line_number":553,"context_line":""},{"line_number":554,"context_line":"    def test__get_retry_after_delay_with_integer(self):"},{"line_number":555,"context_line":"        resp \u003d httplib2.Response({\u0027retry-after\u0027: \u0027123\u0027})"},{"line_number":556,"context_line":"        self.assertEqual(123, self.rest_client._get_retry_after_delay(resp))"},{"line_number":557,"context_line":""},{"line_number":558,"context_line":"    def test__get_retry_after_delay_with_http_date(self):"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a061dce_efa7aaa4","line":555,"updated":"2016-04-07 16:13:25.000000000","message":"We are in the process of removing the dependency on httplib2 (see https://review.openstack.org/#/c/295900/). Just do\n  resp \u003d {\u0027retry-after\u0027: \u0027123\u0027}","commit_id":"fd5cea0a71da5835ab3f51dbf0a970c1ae7400f7"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"f4fef230cbef5b467e14a0f9ef23aa6e687146e5","unresolved":false,"context_lines":[{"line_number":556,"context_line":"        self.assertEqual(123, self.rest_client._get_retry_after_delay(resp))"},{"line_number":557,"context_line":""},{"line_number":558,"context_line":"    def test__get_retry_after_delay_with_http_date(self):"},{"line_number":559,"context_line":"        resp \u003d httplib2.Response({"},{"line_number":560,"context_line":"            \u0027date\u0027: \u0027Mon, 4 Apr 2016 21:56:23 GMT\u0027,"},{"line_number":561,"context_line":"            \u0027retry-after\u0027: \u0027Mon, 4 Apr 2016 21:58:26 GMT\u0027,"},{"line_number":562,"context_line":"        })"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a061dce_4fb976cb","line":559,"updated":"2016-04-07 16:13:25.000000000","message":"same","commit_id":"fd5cea0a71da5835ab3f51dbf0a970c1ae7400f7"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"f4fef230cbef5b467e14a0f9ef23aa6e687146e5","unresolved":false,"context_lines":[{"line_number":563,"context_line":"        self.assertEqual(123, self.rest_client._get_retry_after_delay(resp))"},{"line_number":564,"context_line":""},{"line_number":565,"context_line":"    def test__get_retry_after_delay_with_invalid_http_date(self):"},{"line_number":566,"context_line":"        resp \u003d httplib2.Response({"},{"line_number":567,"context_line":"            \u0027retry-after\u0027: \u0027Mon, 4 AAA 2016 21:58:26 GMT\u0027,"},{"line_number":568,"context_line":"        })"},{"line_number":569,"context_line":"        self.assertRaises(ValueError, self.rest_client._get_retry_after_delay,"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a061dce_8faf0e7c","line":566,"updated":"2016-04-07 16:13:25.000000000","message":"same","commit_id":"fd5cea0a71da5835ab3f51dbf0a970c1ae7400f7"}]}
