)]}'
{".functests":[{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"ecd041029c4daf4e00eb78bf45d7856fe46992ad","unresolved":false,"context_lines":[{"line_number":3,"context_line":"# How-To debug functional tests:"},{"line_number":4,"context_line":"# SWIFT_TEST_IN_PROCESS\u003d1 tox -e func -- --pdb test.functional.tests.TestFile.testCopy"},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"SRC_DIR\u003d$(python -c \"import os; print(os.path.dirname(os.path.realpath(\u0027$0\u0027)))\")"},{"line_number":7,"context_line":""},{"line_number":8,"context_line":"cd ${SRC_DIR} \u003e /dev/null"},{"line_number":9,"context_line":"export TESTS_DIR\u003d${SRC_DIR}/test/functional"}],"source_content_type":"application/x-shellscript","patch_set":16,"id":"dfbec78f_8fafab28","line":6,"updated":"2019-05-15 23:47:50.000000000","message":"maybe invoke python3 here? or you think it\u0027s okay to rely on print printing a (), which is not a tuple as long as there aren\u0027t any commas?","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c55ede6851521deb69d4d0f46811baa6b8339139","unresolved":false,"context_lines":[{"line_number":3,"context_line":"# How-To debug functional tests:"},{"line_number":4,"context_line":"# SWIFT_TEST_IN_PROCESS\u003d1 tox -e func -- --pdb test.functional.tests.TestFile.testCopy"},{"line_number":5,"context_line":""},{"line_number":6,"context_line":"SRC_DIR\u003d$(python -c \"import os; print(os.path.dirname(os.path.realpath(\u0027$0\u0027)))\")"},{"line_number":7,"context_line":""},{"line_number":8,"context_line":"cd ${SRC_DIR} \u003e /dev/null"},{"line_number":9,"context_line":"export TESTS_DIR\u003d${SRC_DIR}/test/functional"}],"source_content_type":"application/x-shellscript","patch_set":16,"id":"dfbec78f_f8970feb","line":6,"in_reply_to":"dfbec78f_8fafab28","updated":"2019-05-16 04:36:59.000000000","message":"Yeah, relying on the py2/3 hack of print()ing a single value. It\u0027s the correct way to do py3, and works fine on py2. Maybe a little brittle, but I don\u0027t see us really needing to touch this again (except maybe to make it pure bash, and save us needing to start up python for something so simple).","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"}],"swift/common/bufferedhttp.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5946d11f4b00558cd7364e916a79cd48613bd236","unresolved":false,"context_lines":[{"line_number":192,"context_line":"        \u0027\u0027\u0027"},{"line_number":193,"context_line":"        self._method \u003d method"},{"line_number":194,"context_line":"        self._path \u003d url"},{"line_number":195,"context_line":"        return HTTPConnection.putrequest(self, method, url, skip_host,"},{"line_number":196,"context_line":"                                         skip_accept_encoding)"},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"    def getexpect(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_ffbf425e","line":195,"range":{"start_line":195,"start_character":15,"end_line":195,"end_character":40},"updated":"2019-03-12 17:39:08.000000000","message":"I should see how bad it is to inline this, so we don\u0027t have to try to convince upstream CPython to change https://github.com/python/cpython/blob/v3.7.2/Lib/http/client.py#L1106-L1107 ...","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"20660620eca55cfa78427caef6772182f132b379","unresolved":false,"context_lines":[{"line_number":192,"context_line":"        \u0027\u0027\u0027"},{"line_number":193,"context_line":"        self._method \u003d method"},{"line_number":194,"context_line":"        self._path \u003d url"},{"line_number":195,"context_line":"        return HTTPConnection.putrequest(self, method, url, skip_host,"},{"line_number":196,"context_line":"                                         skip_accept_encoding)"},{"line_number":197,"context_line":""},{"line_number":198,"context_line":"    def getexpect(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_ad32d4f0","line":195,"range":{"start_line":195,"start_character":15,"end_line":195,"end_character":40},"in_reply_to":"5fc1f717_ffbf425e","updated":"2019-03-13 19:37:43.000000000","message":"Done as https://review.openstack.org/#/c/642893/ ... though in retrospect, I\u0027m not actually sure it should matter... The func test client isn\u0027t using bufferedhttp, is it? And by the time that we\u0027re making backend requests, we (should be) URL-quoting the path; Robustness Principle and all...","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1aed722ce962e8f89b1f2781f94b37235defe4d","unresolved":false,"context_lines":[{"line_number":45,"context_line":"# Apparently http.server uses this to decide when/whether to send a 431."},{"line_number":46,"context_line":"# Give it some slack, so the app is more likely to get the chance to reject"},{"line_number":47,"context_line":"# with a 400 instead."},{"line_number":48,"context_line":"httplib._MAXHEADERS \u003d constraints.MAX_HEADER_COUNT * 1.6"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"class BufferedHTTPResponse(HTTPResponse):"}],"source_content_type":"text/x-python","patch_set":16,"id":"bfb3d3c7_e3e3a2a3","line":48,"updated":"2019-05-17 19:16:35.000000000","message":"I still don\u0027t really like how much magic this implies :-(\n\nWhy 1.6? Why not 1.5 or 1.7 or 2? Plus I went and changed the type of the thing...","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"}],"swift/common/middleware/s3api/controllers/multi_upload.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5946d11f4b00558cd7364e916a79cd48613bd236","unresolved":false,"context_lines":[{"line_number":533,"context_line":"            if six.PY2:"},{"line_number":534,"context_line":"                obj \u003d obj.encode(\u0027utf-8\u0027)"},{"line_number":535,"context_line":"            # TODO: or should ^^^ be more like vvv (with no py2-guard)?"},{"line_number":536,"context_line":"            # obj \u003d bytes_to_wsgi(o[\u0027name\u0027].encode(\u0027utf-8\u0027))"},{"line_number":537,"context_line":"            req.get_response(self.app, container\u003dcontainer, obj\u003dobj)"},{"line_number":538,"context_line":""},{"line_number":539,"context_line":"        return HTTPNoContent()"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_7c2600d1","line":536,"updated":"2019-03-12 17:39:08.000000000","message":"Needed because of the changes in swob. 99% sure this *should* be doing the WSGI dance that I commented out...","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"20660620eca55cfa78427caef6772182f132b379","unresolved":false,"context_lines":[{"line_number":533,"context_line":"            if six.PY2:"},{"line_number":534,"context_line":"                obj \u003d obj.encode(\u0027utf-8\u0027)"},{"line_number":535,"context_line":"            # TODO: or should ^^^ be more like vvv (with no py2-guard)?"},{"line_number":536,"context_line":"            # obj \u003d bytes_to_wsgi(o[\u0027name\u0027].encode(\u0027utf-8\u0027))"},{"line_number":537,"context_line":"            req.get_response(self.app, container\u003dcontainer, obj\u003dobj)"},{"line_number":538,"context_line":""},{"line_number":539,"context_line":"        return HTTPNoContent()"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_cd2f2086","line":536,"in_reply_to":"5fc1f717_7c2600d1","updated":"2019-03-13 19:37:43.000000000","message":"Done","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1aed722ce962e8f89b1f2781f94b37235defe4d","unresolved":false,"context_lines":[{"line_number":529,"context_line":"        objects \u003d json.loads(resp.body)"},{"line_number":530,"context_line":"        for o in objects:"},{"line_number":531,"context_line":"            container \u003d req.container_name + MULTIUPLOAD_SUFFIX"},{"line_number":532,"context_line":"            obj \u003d bytes_to_wsgi(o[\u0027name\u0027].encode(\u0027utf-8\u0027))"},{"line_number":533,"context_line":"            req.get_response(self.app, container\u003dcontainer, obj\u003dobj)"},{"line_number":534,"context_line":""},{"line_number":535,"context_line":"        return HTTPNoContent()"}],"source_content_type":"text/x-python","patch_set":16,"id":"bfb3d3c7_03fa7641","line":532,"updated":"2019-05-17 19:16:35.000000000","message":"Incidental fix; not sure why this didn\u0027t come up when I originally ported s3api...","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"}],"swift/common/middleware/s3api/controllers/service.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1aed722ce962e8f89b1f2781f94b37235defe4d","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        buckets \u003d SubElement(elem, \u0027Buckets\u0027)"},{"line_number":53,"context_line":"        for c in containers:"},{"line_number":54,"context_line":"            if self.conf.s3_acl and self.conf.check_bucket_owner:"},{"line_number":55,"context_line":"                container \u003d bytes_to_wsgi(c[\u0027name\u0027].encode(\u0027utf8\u0027))"},{"line_number":56,"context_line":"                try:"},{"line_number":57,"context_line":"                    req.get_response(self.app, \u0027HEAD\u0027, container)"},{"line_number":58,"context_line":"                except AccessDenied:"}],"source_content_type":"text/x-python","patch_set":16,"id":"bfb3d3c7_a394cae9","line":55,"updated":"2019-05-17 19:16:35.000000000","message":"ditto","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"}],"swift/common/swob.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1aed722ce962e8f89b1f2781f94b37235defe4d","unresolved":false,"context_lines":[{"line_number":945,"context_line":"            \u0027REQUEST_METHOD\u0027: \u0027GET\u0027,"},{"line_number":946,"context_line":"            \u0027SCRIPT_NAME\u0027: \u0027\u0027,"},{"line_number":947,"context_line":"            \u0027QUERY_STRING\u0027: parsed_path.query,"},{"line_number":948,"context_line":"            \u0027PATH_INFO\u0027: wsgi_unquote(parsed_path.path),"},{"line_number":949,"context_line":"            \u0027SERVER_NAME\u0027: server_name,"},{"line_number":950,"context_line":"            \u0027SERVER_PORT\u0027: str(server_port),"},{"line_number":951,"context_line":"            \u0027HTTP_HOST\u0027: \u0027%s:%d\u0027 % (server_name, server_port),"}],"source_content_type":"text/x-python","patch_set":16,"id":"bfb3d3c7_c399be1f","line":948,"updated":"2019-05-17 19:16:35.000000000","message":"Just a simplification.","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1aed722ce962e8f89b1f2781f94b37235defe4d","unresolved":false,"context_lines":[{"line_number":1033,"context_line":"    def path(self):"},{"line_number":1034,"context_line":"        \"Provides the full path of the request, excluding the QUERY_STRING\""},{"line_number":1035,"context_line":"        return wsgi_quote(self.environ.get(\u0027SCRIPT_NAME\u0027, \u0027\u0027) +"},{"line_number":1036,"context_line":"                          self.environ[\u0027PATH_INFO\u0027])"},{"line_number":1037,"context_line":""},{"line_number":1038,"context_line":"    @property"},{"line_number":1039,"context_line":"    def swift_entity_path(self):"}],"source_content_type":"text/x-python","patch_set":16,"id":"bfb3d3c7_83a3c64f","line":1036,"updated":"2019-05-17 19:16:35.000000000","message":"ditto","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1aed722ce962e8f89b1f2781f94b37235defe4d","unresolved":false,"context_lines":[{"line_number":1471,"context_line":"                realm \u003d \u0027unknown\u0027"},{"line_number":1472,"context_line":"        except (AttributeError, ValueError):"},{"line_number":1473,"context_line":"            realm \u003d \u0027unknown\u0027"},{"line_number":1474,"context_line":"        return \u0027Swift realm\u003d\"%s\"\u0027 % wsgi_quote(realm)"},{"line_number":1475,"context_line":""},{"line_number":1476,"context_line":"    @property"},{"line_number":1477,"context_line":"    def is_success(self):"}],"source_content_type":"text/x-python","patch_set":16,"id":"bfb3d3c7_c3c21eea","line":1474,"updated":"2019-05-17 19:16:35.000000000","message":"This was a legit problem, though. On py3 it\u0027d take the WSGI string, encode it in utf8, and quote *that*.","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"}],"swift/common/wsgi.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5946d11f4b00558cd7364e916a79cd48613bd236","unresolved":false,"context_lines":[{"line_number":458,"context_line":"                parts[1] \u003d path + q + query"},{"line_number":459,"context_line":"                self.raw_requestline \u003d b\u0027 \u0027.join(parts)"},{"line_number":460,"context_line":"            # else, mangled protocol, most likely; let base class deal with it"},{"line_number":461,"context_line":"        return wsgi.HttpProtocol.parse_request(self)"},{"line_number":462,"context_line":""},{"line_number":463,"context_line":""},{"line_number":464,"context_line":"class SwiftHttpProxiedProtocol(SwiftHttpProtocol):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_7f14b244","line":461,"updated":"2019-03-12 17:39:08.000000000","message":"I should consider breaking this out to a separate change. *Definitely* needs tests.","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"}],"swift/proxy/controllers/base.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5946d11f4b00558cd7364e916a79cd48613bd236","unresolved":false,"context_lines":[{"line_number":691,"context_line":"    :param env: the environment used by the current request"},{"line_number":692,"context_line":"    :param account: The unquoted, WSGI-str name of the account"},{"line_number":693,"context_line":"    :param container: The unquoted, WSGI-str name of the container"},{"line_number":694,"context_line":"    :param obj: The unquoted, WSGI-str name of the object"},{"line_number":695,"context_line":"    :returns: the cached info or None if cannot be retrieved"},{"line_number":696,"context_line":"    \"\"\""},{"line_number":697,"context_line":"    cache_key \u003d get_cache_key(account, container, obj)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_7fdef26d","line":694,"updated":"2019-03-12 17:39:08.000000000","message":"IDK that these actually *should* be WSGI strings -- that seems to break from the general rule established here that a function with the path broken out as account, container, object should be native... but the caller was already passing WSGI strings, and it felt weird to do go back to native for the function call when I\u0027d need to flop back to WSGI for _prepare_pre_auth_info_request().","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"}],"swift/proxy/controllers/container.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5946d11f4b00558cd7364e916a79cd48613bd236","unresolved":false,"context_lines":[{"line_number":272,"context_line":"        if len(self.container_name) \u003e length_limit:"},{"line_number":273,"context_line":"            body \u003d \u0027Container name length of %d longer than %d\u0027 % ("},{"line_number":274,"context_line":"                len(self.container_name), length_limit)"},{"line_number":275,"context_line":"            resp \u003d HTTPBadRequest(request\u003dreq, body\u003dbody)"},{"line_number":276,"context_line":"            return resp"},{"line_number":277,"context_line":"        account_partition, accounts, container_count \u003d \\"},{"line_number":278,"context_line":"            self.account_info(self.account_name, req)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_ff0662ce","line":275,"updated":"2019-03-12 17:39:08.000000000","message":"Done so we get the auto-encoding.","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"}],"swift/proxy/server.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1aed722ce962e8f89b1f2781f94b37235defe4d","unresolved":false,"context_lines":[{"line_number":466,"context_line":"                                      body\u003d\u0027Invalid Content-Length\u0027)"},{"line_number":467,"context_line":""},{"line_number":468,"context_line":"            try:"},{"line_number":469,"context_line":"                if not check_utf8(wsgi_to_str(req.path_info)):"},{"line_number":470,"context_line":"                    self.logger.increment(\u0027errors\u0027)"},{"line_number":471,"context_line":"                    return HTTPPreconditionFailed("},{"line_number":472,"context_line":"                        request\u003dreq, body\u003d\u0027Invalid UTF8 or contains NULL\u0027)"}],"source_content_type":"text/x-python","patch_set":16,"id":"bfb3d3c7_e3aac217","line":469,"updated":"2019-05-17 19:16:35.000000000","message":"I think Pete\u0027s SLO patch did something similar :-)","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"}],"test/functional/__init__.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1aed722ce962e8f89b1f2781f94b37235defe4d","unresolved":false,"context_lines":[{"line_number":852,"context_line":"                \u0027auth_host\u0027: parsed.hostname,"},{"line_number":853,"context_line":"                \u0027auth_port\u0027: str("},{"line_number":854,"context_line":"                    parsed.port if parsed.port is not None else"},{"line_number":855,"context_line":"                    443 if parsed.scheme \u003d\u003d \u0027https\u0027 else 80),"},{"line_number":856,"context_line":"                \u0027auth_prefix\u0027: parsed.path,"},{"line_number":857,"context_line":"            })"},{"line_number":858,"context_line":"        elif \u0027auth_host\u0027 in config:"}],"source_content_type":"text/x-python","patch_set":16,"id":"bfb3d3c7_636c9208","line":855,"updated":"2019-05-17 19:16:35.000000000","message":"Config values need to be strings on py3, apparently. Something to do with value interpolation?","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"}],"test/functional/swift_test_client.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5946d11f4b00558cd7364e916a79cd48613bd236","unresolved":false,"context_lines":[{"line_number":416,"context_line":"            )"},{"line_number":417,"context_line":""},{"line_number":418,"context_line":"        # NB: on py2, headers are always lower; on py3, they are title case"},{"line_number":419,"context_line":"        # (or maybe match the bytes on the wire?)"},{"line_number":420,"context_line":"        headers \u003d dict((wsgi_to_str(h.lower()), wsgi_to_str(v))"},{"line_number":421,"context_line":"                       for h, v in self.conn.response.getheaders())"},{"line_number":422,"context_line":"        ret \u003d {}"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_df2a862a","line":419,"range":{"start_line":419,"start_character":20,"end_line":419,"end_character":47},"updated":"2019-03-12 17:39:08.000000000","message":"It\u0027s this one; I should maybe update the comment.","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"20660620eca55cfa78427caef6772182f132b379","unresolved":false,"context_lines":[{"line_number":416,"context_line":"            )"},{"line_number":417,"context_line":""},{"line_number":418,"context_line":"        # NB: on py2, headers are always lower; on py3, they are title case"},{"line_number":419,"context_line":"        # (or maybe match the bytes on the wire?)"},{"line_number":420,"context_line":"        headers \u003d dict((wsgi_to_str(h.lower()), wsgi_to_str(v))"},{"line_number":421,"context_line":"                       for h, v in self.conn.response.getheaders())"},{"line_number":422,"context_line":"        ret \u003d {}"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_8a201eae","line":419,"range":{"start_line":419,"start_character":20,"end_line":419,"end_character":47},"in_reply_to":"5fc1f717_df2a862a","updated":"2019-03-13 19:37:43.000000000","message":"Done","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5946d11f4b00558cd7364e916a79cd48613bd236","unresolved":false,"context_lines":[{"line_number":417,"context_line":""},{"line_number":418,"context_line":"        # NB: on py2, headers are always lower; on py3, they are title case"},{"line_number":419,"context_line":"        # (or maybe match the bytes on the wire?)"},{"line_number":420,"context_line":"        headers \u003d dict((wsgi_to_str(h.lower()), wsgi_to_str(v))"},{"line_number":421,"context_line":"                       for h, v in self.conn.response.getheaders())"},{"line_number":422,"context_line":"        ret \u003d {}"},{"line_number":423,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_9fe5de0b","line":420,"range":{"start_line":420,"start_character":37,"end_line":420,"end_character":45},"updated":"2019-03-12 17:39:08.000000000","message":"Oh! And the .lower() should almost certainly happen *after* the wsgi_to_str()!","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"20660620eca55cfa78427caef6772182f132b379","unresolved":false,"context_lines":[{"line_number":417,"context_line":""},{"line_number":418,"context_line":"        # NB: on py2, headers are always lower; on py3, they are title case"},{"line_number":419,"context_line":"        # (or maybe match the bytes on the wire?)"},{"line_number":420,"context_line":"        headers \u003d dict((wsgi_to_str(h.lower()), wsgi_to_str(v))"},{"line_number":421,"context_line":"                       for h, v in self.conn.response.getheaders())"},{"line_number":422,"context_line":"        ret \u003d {}"},{"line_number":423,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_2a11ea5d","line":420,"range":{"start_line":420,"start_character":37,"end_line":420,"end_character":45},"in_reply_to":"5fc1f717_9fe5de0b","updated":"2019-03-13 19:37:43.000000000","message":"Done","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5946d11f4b00558cd7364e916a79cd48613bd236","unresolved":false,"context_lines":[{"line_number":483,"context_line":"        if status \u003d\u003d 200:"},{"line_number":484,"context_line":"            if format_type \u003d\u003d \u0027json\u0027:"},{"line_number":485,"context_line":"                body \u003d self.conn.response.read()"},{"line_number":486,"context_line":"                conts \u003d json.loads(body)"},{"line_number":487,"context_line":"                if six.PY2:"},{"line_number":488,"context_line":"                    for cont in conts:"},{"line_number":489,"context_line":"                        cont[\u0027name\u0027] \u003d cont[\u0027name\u0027].encode(\u0027utf-8\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_bf81bafd","line":486,"updated":"2019-03-12 17:39:08.000000000","message":"I think this was leftover from debugging some non-json response I somehow managed to get... can back out.","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"20660620eca55cfa78427caef6772182f132b379","unresolved":false,"context_lines":[{"line_number":483,"context_line":"        if status \u003d\u003d 200:"},{"line_number":484,"context_line":"            if format_type \u003d\u003d \u0027json\u0027:"},{"line_number":485,"context_line":"                body \u003d self.conn.response.read()"},{"line_number":486,"context_line":"                conts \u003d json.loads(body)"},{"line_number":487,"context_line":"                if six.PY2:"},{"line_number":488,"context_line":"                    for cont in conts:"},{"line_number":489,"context_line":"                        cont[\u0027name\u0027] \u003d cont[\u0027name\u0027].encode(\u0027utf-8\u0027)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_ea0e8239","line":486,"in_reply_to":"5fc1f717_bf81bafd","updated":"2019-03-13 19:37:43.000000000","message":"Done","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5946d11f4b00558cd7364e916a79cd48613bd236","unresolved":false,"context_lines":[{"line_number":885,"context_line":"                                self.conn.make_path(self.path))"},{"line_number":886,"context_line":""},{"line_number":887,"context_line":"        for hdr, val in self.conn.response.getheaders():"},{"line_number":888,"context_line":"            hdr \u003d wsgi_to_str(hdr.lower())"},{"line_number":889,"context_line":"            val \u003d wsgi_to_str(val)"},{"line_number":890,"context_line":"            if hdr.lower() \u003d\u003d \u0027content-type\u0027:"},{"line_number":891,"context_line":"                self.content_type \u003d val"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_dfada69b","line":888,"range":{"start_line":888,"start_character":33,"end_line":888,"end_character":41},"updated":"2019-03-12 17:39:08.000000000","message":"Again, should happen *After* wsgi_to_str()","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"20660620eca55cfa78427caef6772182f132b379","unresolved":false,"context_lines":[{"line_number":885,"context_line":"                                self.conn.make_path(self.path))"},{"line_number":886,"context_line":""},{"line_number":887,"context_line":"        for hdr, val in self.conn.response.getheaders():"},{"line_number":888,"context_line":"            hdr \u003d wsgi_to_str(hdr.lower())"},{"line_number":889,"context_line":"            val \u003d wsgi_to_str(val)"},{"line_number":890,"context_line":"            if hdr.lower() \u003d\u003d \u0027content-type\u0027:"},{"line_number":891,"context_line":"                self.content_type \u003d val"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_aa04fa18","line":888,"range":{"start_line":888,"start_character":33,"end_line":888,"end_character":41},"in_reply_to":"5fc1f717_dfada69b","updated":"2019-03-13 19:37:43.000000000","message":"Done","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5946d11f4b00558cd7364e916a79cd48613bd236","unresolved":false,"context_lines":[{"line_number":895,"context_line":"                self.etag \u003d val"},{"line_number":896,"context_line":"            if hdr.lower() \u003d\u003d \u0027content-length\u0027:"},{"line_number":897,"context_line":"                self.size \u003d int(val)"},{"line_number":898,"context_line":"            if hdr.lower() \u003d\u003d \u0027last-modified\u0027:"},{"line_number":899,"context_line":"                self.last_modified \u003d val"},{"line_number":900,"context_line":""},{"line_number":901,"context_line":"        return True"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_7f96f24e","line":898,"range":{"start_line":898,"start_character":19,"end_line":898,"end_character":24},"updated":"2019-03-12 17:39:08.000000000","message":"None of these .lower()s are necessary any more","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"20660620eca55cfa78427caef6772182f132b379","unresolved":false,"context_lines":[{"line_number":895,"context_line":"                self.etag \u003d val"},{"line_number":896,"context_line":"            if hdr.lower() \u003d\u003d \u0027content-length\u0027:"},{"line_number":897,"context_line":"                self.size \u003d int(val)"},{"line_number":898,"context_line":"            if hdr.lower() \u003d\u003d \u0027last-modified\u0027:"},{"line_number":899,"context_line":"                self.last_modified \u003d val"},{"line_number":900,"context_line":""},{"line_number":901,"context_line":"        return True"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_ca014608","line":898,"range":{"start_line":898,"start_character":19,"end_line":898,"end_character":24},"in_reply_to":"5fc1f717_7f96f24e","updated":"2019-03-13 19:37:43.000000000","message":"Done","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1aed722ce962e8f89b1f2781f94b37235defe4d","unresolved":false,"context_lines":[{"line_number":325,"context_line":"        if path:"},{"line_number":326,"context_line":"            quote \u003d urllib.parse.quote"},{"line_number":327,"context_line":"            if cfg.get(\u0027no_quote\u0027) or cfg.get(\u0027no_path_quote\u0027):"},{"line_number":328,"context_line":"                quote \u003d str_to_wsgi"},{"line_number":329,"context_line":"            return \u0027%s/%s\u0027 % (self.storage_path,"},{"line_number":330,"context_line":"                              \u0027/\u0027.join([quote(i) for i in path]))"},{"line_number":331,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":16,"id":"bfb3d3c7_633a52e8","line":328,"updated":"2019-05-17 19:16:35.000000000","message":"From https://review.opendev.org/#/c/571908/, this should probably also swap \u0027%\u0027 for \u0027%25\u0027, but that can be done later.","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"}],"test/functional/tests.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5946d11f4b00558cd7364e916a79cd48613bd236","unresolved":false,"context_lines":[{"line_number":2089,"context_line":"                byteranges[0][\u0027Content-Range\u0027],"},{"line_number":2090,"context_line":"                \"bytes %d-%d/%d\" % (i, i + subrange_size - 1, file_length))"},{"line_number":2091,"context_line":"            self.assertEqual("},{"line_number":2092,"context_line":"                byteranges[0].get_payload(decode\u003dTrue),"},{"line_number":2093,"context_line":"                data[i:(i + subrange_size)])"},{"line_number":2094,"context_line":""},{"line_number":2095,"context_line":"            self.assertEqual(byteranges[1][\u0027Content-Type\u0027],"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_9ff87e7b","line":2092,"range":{"start_line":2092,"start_character":42,"end_line":2092,"end_character":53},"updated":"2019-03-12 17:39:08.000000000","message":"I don\u0027t entirely understand their use of the word \"decode\" here, but apparently this is how you say \"just give me the raw bytes.\"","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5946d11f4b00558cd7364e916a79cd48613bd236","unresolved":false,"context_lines":[{"line_number":2171,"context_line":"            if six.PY2:"},{"line_number":2172,"context_line":"                parser \u003d email.parser.FeedParser()"},{"line_number":2173,"context_line":"            else:"},{"line_number":2174,"context_line":"                parser \u003d email.parser.BytesFeedParser()"},{"line_number":2175,"context_line":"            parser.feed(b\"Content-Type: %s\\r\\n\\r\\n\" % content_type.encode())"},{"line_number":2176,"context_line":"            parser.feed(fetched)"},{"line_number":2177,"context_line":"            root_message \u003d parser.close()"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_5f1c56c0","line":2174,"updated":"2019-03-12 17:39:08.000000000","message":"Maybe there should be a\n\nif six.PY2:\n    from email.parser import FeedParser\nelse:\n    from email.parser import BytesFeedParser as FeedParser\n\nat the top instead of littering these about?","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"20660620eca55cfa78427caef6772182f132b379","unresolved":false,"context_lines":[{"line_number":2171,"context_line":"            if six.PY2:"},{"line_number":2172,"context_line":"                parser \u003d email.parser.FeedParser()"},{"line_number":2173,"context_line":"            else:"},{"line_number":2174,"context_line":"                parser \u003d email.parser.BytesFeedParser()"},{"line_number":2175,"context_line":"            parser.feed(b\"Content-Type: %s\\r\\n\\r\\n\" % content_type.encode())"},{"line_number":2176,"context_line":"            parser.feed(fetched)"},{"line_number":2177,"context_line":"            root_message \u003d parser.close()"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_6d294c88","line":2174,"in_reply_to":"5fc1f717_5f1c56c0","updated":"2019-03-13 19:37:43.000000000","message":"Done","commit_id":"0ef5485f6c74e7aa699a26766532d390ea16bf24"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"ecd041029c4daf4e00eb78bf45d7856fe46992ad","unresolved":false,"context_lines":[{"line_number":1946,"context_line":""},{"line_number":1947,"context_line":"                if len(key) \u003e j:"},{"line_number":1948,"context_line":"                    key \u003d key[:j]"},{"line_number":1949,"context_line":"                    if isinstance(val, bytes):"},{"line_number":1950,"context_line":"                        val \u003d val[:j]"},{"line_number":1951,"context_line":"                    else:"},{"line_number":1952,"context_line":"                        val \u003d val.encode(\u0027utf8\u0027)[:j].decode("}],"source_content_type":"text/x-python","patch_set":16,"id":"dfbec78f_92acb4ed","line":1949,"updated":"2019-05-15 23:47:50.000000000","message":"Isn\u0027t this a masquerading six.PY2?","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1aed722ce962e8f89b1f2781f94b37235defe4d","unresolved":false,"context_lines":[{"line_number":1946,"context_line":""},{"line_number":1947,"context_line":"                if len(key) \u003e j:"},{"line_number":1948,"context_line":"                    key \u003d key[:j]"},{"line_number":1949,"context_line":"                    if isinstance(val, bytes):"},{"line_number":1950,"context_line":"                        val \u003d val[:j]"},{"line_number":1951,"context_line":"                    else:"},{"line_number":1952,"context_line":"                        val \u003d val.encode(\u0027utf8\u0027)[:j].decode("}],"source_content_type":"text/x-python","patch_set":16,"id":"bfb3d3c7_83398642","line":1949,"in_reply_to":"bfb3d3c7_cf724e12","updated":"2019-05-17 19:16:35.000000000","message":"Submitted https://review.opendev.org/#/c/659851/ as a follow-up.","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c55ede6851521deb69d4d0f46811baa6b8339139","unresolved":false,"context_lines":[{"line_number":1946,"context_line":""},{"line_number":1947,"context_line":"                if len(key) \u003e j:"},{"line_number":1948,"context_line":"                    key \u003d key[:j]"},{"line_number":1949,"context_line":"                    if isinstance(val, bytes):"},{"line_number":1950,"context_line":"                        val \u003d val[:j]"},{"line_number":1951,"context_line":"                    else:"},{"line_number":1952,"context_line":"                        val \u003d val.encode(\u0027utf8\u0027)[:j].decode("}],"source_content_type":"text/x-python","patch_set":16,"id":"dfbec78f_988613b9","line":1949,"in_reply_to":"dfbec78f_92acb4ed","updated":"2019-05-16 04:36:59.000000000","message":"Yeah, I suppose so. Maybe better to phrase it that way so we can easily find and remove the dead code path when we drop py2...","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"e1973b745c99a83d99212b5144ff5d7700ea012a","unresolved":false,"context_lines":[{"line_number":1946,"context_line":""},{"line_number":1947,"context_line":"                if len(key) \u003e j:"},{"line_number":1948,"context_line":"                    key \u003d key[:j]"},{"line_number":1949,"context_line":"                    if isinstance(val, bytes):"},{"line_number":1950,"context_line":"                        val \u003d val[:j]"},{"line_number":1951,"context_line":"                    else:"},{"line_number":1952,"context_line":"                        val \u003d val.encode(\u0027utf8\u0027)[:j].decode("}],"source_content_type":"text/x-python","patch_set":16,"id":"bfb3d3c7_cf724e12","line":1949,"in_reply_to":"dfbec78f_988613b9","updated":"2019-05-17 06:05:29.000000000","message":"Is this something we want to address before we land this? or should we just do a follow up?","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"}],"test/unit/common/test_wsgi.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5946d11f4b00558cd7364e916a79cd48613bd236","unresolved":false,"context_lines":[{"line_number":1041,"context_line":""},{"line_number":1042,"context_line":"        self.assertEqual(False, proto_obj.parse_request())"},{"line_number":1043,"context_line":""},{"line_number":1044,"context_line":"        self.assertEqual([], self.mock_super.mock_calls)"},{"line_number":1045,"context_line":"        self.assertEqual(["},{"line_number":1046,"context_line":"            mock.call(400, \"Bad HTTP/0.9 request type (\u0027jimmy\u0027)\"),"},{"line_number":1047,"context_line":"        ], proto_obj.send_error.mock_calls)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5fc1f717_5fdf76d5","side":"PARENT","line":1044,"updated":"2019-03-12 17:39:08.000000000","message":"I\u0027m not really clear on *what* this was trying to demonstrate... we *very much* were relying on the parent class\u0027s implementation actually working.","commit_id":"7ca900b04d587fc6493e5ef5dd815523cf3c6c5c"}],"tox.ini":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"e1973b745c99a83d99212b5144ff5d7700ea012a","unresolved":false,"context_lines":[{"line_number":122,"context_line":"# Need to pick up (unreleased as of 2019-03) commit:"},{"line_number":123,"context_line":"# https://github.com/eventlet/eventlet/commit/f0bc79e"},{"line_number":124,"context_line":"commands \u003d"},{"line_number":125,"context_line":"  pip install -U eventlet@git+https://github.com/eventlet/eventlet.git"},{"line_number":126,"context_line":"  nosetests {posargs: \\"},{"line_number":127,"context_line":"    test/functional/tests.py}"},{"line_number":128,"context_line":""}],"source_content_type":"text/x-properties","patch_set":16,"id":"bfb3d3c7_af759afc","line":125,"updated":"2019-05-17 06:05:29.000000000","message":"Carrying this on master is a little unnerving. It\u0027s obviously not something we want long term.\n\nBecause I know your working on poking them to make a release before our next release I think this is fine.","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1aed722ce962e8f89b1f2781f94b37235defe4d","unresolved":false,"context_lines":[{"line_number":122,"context_line":"# Need to pick up (unreleased as of 2019-03) commit:"},{"line_number":123,"context_line":"# https://github.com/eventlet/eventlet/commit/f0bc79e"},{"line_number":124,"context_line":"commands \u003d"},{"line_number":125,"context_line":"  pip install -U eventlet@git+https://github.com/eventlet/eventlet.git"},{"line_number":126,"context_line":"  nosetests {posargs: \\"},{"line_number":127,"context_line":"    test/functional/tests.py}"},{"line_number":128,"context_line":""}],"source_content_type":"text/x-properties","patch_set":16,"id":"bfb3d3c7_4352ae69","line":125,"in_reply_to":"bfb3d3c7_af759afc","updated":"2019-05-17 19:16:35.000000000","message":"Yeah, I agree that it\u0027s not great. Good new is,\n\n- this isn\u0027t a default tox env,\n- we aren\u0027t claiming a `Programming Language :: Python :: 3` classifier (so I don\u0027t really expect anyone except us to be running this), and\n- I have at least *some* influence over eventlet\u0027s code quality.\n\nI noticed that one of my recent eventlet patches would break our unit tests, though, so the point is well-taken. I\u0027ll\n\n- try to get https://github.com/eventlet/eventlet/pull/569 landed,\n- push eventlet for a fresh tag,\n- push requirements to use the new tag, and finally\n- bump our own requirements.txt\n\nbefore we declare py3 support. I *think* this is worth it to keep moving on func tests while we do that, though? Maybe I should\u0027ve pinned it to a particular hash...","commit_id":"506279235d12f1590bd928de51d991b7fb425e6e"}]}
