)]}'
{"swift/common/middleware/slo.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"71c2fac17ae3b9318833ad6346998ebdc74f9812","unresolved":false,"context_lines":[{"line_number":659,"context_line":"                        \"max recursion depth was exceeded\" % req.path)"},{"line_number":660,"context_line":""},{"line_number":661,"context_line":"                if six.PY2:"},{"line_number":662,"context_line":"                    sub_path \u003d get_valid_utf8_str(seg_dict[\u0027name\u0027])"},{"line_number":663,"context_line":"                else:"},{"line_number":664,"context_line":"                    sub_path \u003d str_to_wsgi(seg_dict[\u0027name\u0027])"},{"line_number":665,"context_line":"                sub_cont, sub_obj \u003d split_path(sub_path, 2, 2, True)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5fc1f717_b6646aba","line":662,"range":{"start_line":662,"start_character":31,"end_line":662,"end_character":49},"updated":"2019-04-08 19:01:37.000000000","message":"This might be better as a separate follow-on patch, but... I wonder if it\u0027d be better to just say\n\n seg_dict[\u0027name\u0027].encode(\u0027utf-8\u0027)\n\nhere. I seem to remember Sam poking at get_valid_utf8_str(), realizing it was a terrible hack of a thing, and wanting to excise it from the codebase...","commit_id":"3319b2a6b941a5f0f0416bb5275f28e849a8ba4f"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"7b0356271f6957ec6ad1206b990a6c55c394f0ef","unresolved":false,"context_lines":[{"line_number":659,"context_line":"                        \"max recursion depth was exceeded\" % req.path)"},{"line_number":660,"context_line":""},{"line_number":661,"context_line":"                if six.PY2:"},{"line_number":662,"context_line":"                    sub_path \u003d get_valid_utf8_str(seg_dict[\u0027name\u0027])"},{"line_number":663,"context_line":"                else:"},{"line_number":664,"context_line":"                    sub_path \u003d str_to_wsgi(seg_dict[\u0027name\u0027])"},{"line_number":665,"context_line":"                sub_cont, sub_obj \u003d split_path(sub_path, 2, 2, True)"}],"source_content_type":"text/x-python","patch_set":1,"id":"ffb9cba7_cf83f803","line":662,"range":{"start_line":662,"start_character":31,"end_line":662,"end_character":49},"in_reply_to":"5fc1f717_b6646aba","updated":"2019-04-24 00:26:25.000000000","message":"I prefer let these sleeping dogs lie if at all possible.","commit_id":"3319b2a6b941a5f0f0416bb5275f28e849a8ba4f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"71c2fac17ae3b9318833ad6346998ebdc74f9812","unresolved":false,"context_lines":[{"line_number":682,"context_line":"            else:"},{"line_number":683,"context_line":"                if six.PY2 and isinstance(seg_dict[\u0027name\u0027], six.text_type):"},{"line_number":684,"context_line":"                    seg_dict[\u0027name\u0027] \u003d seg_dict[\u0027name\u0027].encode(\"utf-8\")"},{"line_number":685,"context_line":"                yield dict(seg_dict,"},{"line_number":686,"context_line":"                           first_byte\u003dmax(0, first_byte) + range_start,"},{"line_number":687,"context_line":"                           last_byte\u003dmin(range_end, range_start + last_byte))"},{"line_number":688,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"5fc1f717_adfdf4b2","line":685,"updated":"2019-04-08 19:01:37.000000000","message":"OK, so we\u0027re going hard on SegmentedIterable taking native-string names? I\u0027ll try to adjust my mental model...","commit_id":"3319b2a6b941a5f0f0416bb5275f28e849a8ba4f"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"7b0356271f6957ec6ad1206b990a6c55c394f0ef","unresolved":false,"context_lines":[{"line_number":682,"context_line":"            else:"},{"line_number":683,"context_line":"                if six.PY2 and isinstance(seg_dict[\u0027name\u0027], six.text_type):"},{"line_number":684,"context_line":"                    seg_dict[\u0027name\u0027] \u003d seg_dict[\u0027name\u0027].encode(\"utf-8\")"},{"line_number":685,"context_line":"                yield dict(seg_dict,"},{"line_number":686,"context_line":"                           first_byte\u003dmax(0, first_byte) + range_start,"},{"line_number":687,"context_line":"                           last_byte\u003dmin(range_end, range_start + last_byte))"},{"line_number":688,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ffb9cba7_8f7d001e","line":685,"in_reply_to":"5fc1f717_adfdf4b2","updated":"2019-04-24 00:26:25.000000000","message":"Well... The name\u003d parameter is only used for logging, so I was lax in tracking it.","commit_id":"3319b2a6b941a5f0f0416bb5275f28e849a8ba4f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"71c2fac17ae3b9318833ad6346998ebdc74f9812","unresolved":false,"context_lines":[{"line_number":1287,"context_line":"                    resp_dict \u003d {}"},{"line_number":1288,"context_line":"                    resp_dict[\u0027Response Status\u0027] \u003d err.status"},{"line_number":1289,"context_line":"                    err_body \u003d err.body"},{"line_number":1290,"context_line":"                    if six.PY3 and isinstance(err_body, bytes):"},{"line_number":1291,"context_line":"                        err_body \u003d err_body.decode(\u0027utf-8\u0027, errors\u003d\u0027replace\u0027)"},{"line_number":1292,"context_line":"                    resp_dict[\u0027Response Body\u0027] \u003d err_body or \u0027\\n\u0027.join("},{"line_number":1293,"context_line":"                        RESPONSE_REASONS.get(err.status_int, [\u0027\u0027]))"}],"source_content_type":"text/x-python","patch_set":1,"id":"5fc1f717_7684c20b","line":1290,"range":{"start_line":1290,"start_character":35,"end_line":1290,"end_character":62},"updated":"2019-04-08 19:01:37.000000000","message":"This should always be true, yeah? I guess.. include it for safety, just in case?","commit_id":"3319b2a6b941a5f0f0416bb5275f28e849a8ba4f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"71c2fac17ae3b9318833ad6346998ebdc74f9812","unresolved":false,"context_lines":[{"line_number":1288,"context_line":"                    resp_dict[\u0027Response Status\u0027] \u003d err.status"},{"line_number":1289,"context_line":"                    err_body \u003d err.body"},{"line_number":1290,"context_line":"                    if six.PY3 and isinstance(err_body, bytes):"},{"line_number":1291,"context_line":"                        err_body \u003d err_body.decode(\u0027utf-8\u0027, errors\u003d\u0027replace\u0027)"},{"line_number":1292,"context_line":"                    resp_dict[\u0027Response Body\u0027] \u003d err_body or \u0027\\n\u0027.join("},{"line_number":1293,"context_line":"                        RESPONSE_REASONS.get(err.status_int, [\u0027\u0027]))"},{"line_number":1294,"context_line":"                    s \u003d separator + get_response_body("}],"source_content_type":"text/x-python","patch_set":1,"id":"5fc1f717_96b7eed8","line":1291,"range":{"start_line":1291,"start_character":60,"end_line":1291,"end_character":76},"updated":"2019-04-08 19:01:37.000000000","message":"Did we have any tests that actually trip this?","commit_id":"3319b2a6b941a5f0f0416bb5275f28e849a8ba4f"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"7b0356271f6957ec6ad1206b990a6c55c394f0ef","unresolved":false,"context_lines":[{"line_number":1288,"context_line":"                    resp_dict[\u0027Response Status\u0027] \u003d err.status"},{"line_number":1289,"context_line":"                    err_body \u003d err.body"},{"line_number":1290,"context_line":"                    if six.PY3 and isinstance(err_body, bytes):"},{"line_number":1291,"context_line":"                        err_body \u003d err_body.decode(\u0027utf-8\u0027, errors\u003d\u0027replace\u0027)"},{"line_number":1292,"context_line":"                    resp_dict[\u0027Response Body\u0027] \u003d err_body or \u0027\\n\u0027.join("},{"line_number":1293,"context_line":"                        RESPONSE_REASONS.get(err.status_int, [\u0027\u0027]))"},{"line_number":1294,"context_line":"                    s \u003d separator + get_response_body("}],"source_content_type":"text/x-python","patch_set":1,"id":"ffb9cba7_efb6fcd9","line":1291,"range":{"start_line":1291,"start_character":60,"end_line":1291,"end_character":76},"in_reply_to":"5fc1f717_96b7eed8","updated":"2019-04-24 00:26:25.000000000","message":"I don\u0027t remember, but I think we have some. I\u0027ll check through the coverage line numbers.","commit_id":"3319b2a6b941a5f0f0416bb5275f28e849a8ba4f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"91e6f84ec7515dab25e6b99713fe2a7a39deb296","unresolved":false,"context_lines":[{"line_number":1288,"context_line":"                    resp_dict[\u0027Response Status\u0027] \u003d err.status"},{"line_number":1289,"context_line":"                    err_body \u003d err.body"},{"line_number":1290,"context_line":"                    if six.PY3 and isinstance(err_body, bytes):"},{"line_number":1291,"context_line":"                        err_body \u003d err_body.decode(\u0027utf-8\u0027, errors\u003d\u0027replace\u0027)"},{"line_number":1292,"context_line":"                    resp_dict[\u0027Response Body\u0027] \u003d err_body or \u0027\\n\u0027.join("},{"line_number":1293,"context_line":"                        RESPONSE_REASONS.get(err.status_int, [\u0027\u0027]))"},{"line_number":1294,"context_line":"                    s \u003d separator + get_response_body("}],"source_content_type":"text/x-python","patch_set":1,"id":"ffb9cba7_c37e4818","line":1291,"range":{"start_line":1291,"start_character":60,"end_line":1291,"end_character":76},"in_reply_to":"ffb9cba7_efb6fcd9","updated":"2019-05-09 20:07:22.000000000","message":"It just worries me is all -- errors\u003d\u0027replace\u0027 seems almost uniformly a Bad Idea.","commit_id":"3319b2a6b941a5f0f0416bb5275f28e849a8ba4f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"71c2fac17ae3b9318833ad6346998ebdc74f9812","unresolved":false,"context_lines":[{"line_number":1295,"context_line":"                        out_content_type, resp_dict, problem_segments,"},{"line_number":1296,"context_line":"                        \u0027upload\u0027)"},{"line_number":1297,"context_line":"                    if six.PY3:"},{"line_number":1298,"context_line":"                        s \u003d s.encode(\u0027utf-8\u0027)"},{"line_number":1299,"context_line":"                    yield s"},{"line_number":1300,"context_line":"                else:"},{"line_number":1301,"context_line":"                    for chunk in err(req.environ, start_response):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5fc1f717_56a666c2","line":1298,"updated":"2019-04-08 19:01:37.000000000","message":"This probably belongs on the bulk review, but this smells weird to me -- everywhere that we would call get_response_body, we\u0027re going to be using it as part of a response body, which needs to be bytes -- so why wouldn\u0027t we push the encoding into the function, and have its contract say that it must return bytes?","commit_id":"3319b2a6b941a5f0f0416bb5275f28e849a8ba4f"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"7b0356271f6957ec6ad1206b990a6c55c394f0ef","unresolved":false,"context_lines":[{"line_number":1295,"context_line":"                        out_content_type, resp_dict, problem_segments,"},{"line_number":1296,"context_line":"                        \u0027upload\u0027)"},{"line_number":1297,"context_line":"                    if six.PY3:"},{"line_number":1298,"context_line":"                        s \u003d s.encode(\u0027utf-8\u0027)"},{"line_number":1299,"context_line":"                    yield s"},{"line_number":1300,"context_line":"                else:"},{"line_number":1301,"context_line":"                    for chunk in err(req.environ, start_response):"}],"source_content_type":"text/x-python","patch_set":1,"id":"ffb9cba7_ef391c41","line":1298,"in_reply_to":"5fc1f717_56a666c2","updated":"2019-04-24 00:26:25.000000000","message":"Okay, let me try get_response_body() return bytes.","commit_id":"3319b2a6b941a5f0f0416bb5275f28e849a8ba4f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"71c2fac17ae3b9318833ad6346998ebdc74f9812","unresolved":false,"context_lines":[{"line_number":1435,"context_line":"            new_env[\u0027PATH_INFO\u0027] \u003d ("},{"line_number":1436,"context_line":"                \u0027/%s/%s/%s\u0027 % (vrs, account, str_to_wsgi(obj_name.lstrip(\u0027/\u0027)))"},{"line_number":1437,"context_line":"            )"},{"line_number":1438,"context_line":"        resp \u003d Request.blank(\u0027\u0027, new_env).get_response(self.app)"},{"line_number":1439,"context_line":""},{"line_number":1440,"context_line":"        if resp.is_success:"},{"line_number":1441,"context_line":"            if config_true_value(resp.headers.get(\u0027X-Static-Large-Object\u0027)):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5fc1f717_ad1654f1","line":1438,"updated":"2019-04-08 19:01:37.000000000","message":"Off-topic: it seems so weird to me that we don\u0027t use make_subrequest or the like... *shrug*","commit_id":"3319b2a6b941a5f0f0416bb5275f28e849a8ba4f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"91e6f84ec7515dab25e6b99713fe2a7a39deb296","unresolved":false,"context_lines":[{"line_number":1400,"context_line":"                segments.append(seg_data)"},{"line_number":1401,"context_line":"            else:"},{"line_number":1402,"context_line":"                if six.PY2:"},{"line_number":1403,"context_line":"                    seg_data[\u0027name\u0027] \u003d seg_data[\u0027name\u0027].encode(\u0027utf-8\u0027)"},{"line_number":1404,"context_line":"                yield seg_data"},{"line_number":1405,"context_line":""},{"line_number":1406,"context_line":"    def get_slo_segments(self, obj_name, req):"}],"source_content_type":"text/x-python","patch_set":3,"id":"dfbec78f_5b223a02","line":1403,"updated":"2019-05-09 20:07:22.000000000","message":"So this is where my current approach on bulk is awkward -- objs_to_delete is expected to be a list of wsgi strings, so we\u0027d want something like\n\n seg_data[\u0027name\u0027] \u003d bytes_to_Wsgi(seg_data[\u0027name\u0027].encode(\u0027utf-8\u0027))\n\non both py2 and py3.","commit_id":"39c20a6f3abb2233c335ca4e43895355d37b1941"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a8155b5909da08c9fef7801b30d3066f9011d017","unresolved":false,"context_lines":[{"line_number":500,"context_line":"                              % (seg_index,))"},{"line_number":501,"context_line":"                continue"},{"line_number":502,"context_line":"            # re-encode to normalize padding"},{"line_number":503,"context_line":"            seg_dict[\u0027data\u0027] \u003d base64.b64encode(data)"},{"line_number":504,"context_line":""},{"line_number":505,"context_line":"    if parsed_data and all(\u0027data\u0027 in d for d in parsed_data):"},{"line_number":506,"context_line":"        errors.append(b\"Inline data segments require at least one \""}],"source_content_type":"text/x-python","patch_set":4,"id":"bfb3d3c7_689fa3b4","line":503,"updated":"2019-05-16 21:44:49.000000000","message":"So b64encode returns byte strings... which will cause json.dumps to barf on py3:\n\n\u003e\u003e\u003e import base64\n\u003e\u003e\u003e base64.b64encode(b\u0027asdf\u0027)\nb\u0027YXNkZg\u003d\u003d\u0027\n\u003e\u003e\u003e import json\n\u003e\u003e\u003e json.dumps(base64.b64encode(b\u0027asdf\u0027))\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \"/usr/lib64/python3.7/json/__init__.py\", line 231, in dumps\n    return _default_encoder.encode(obj)\n  File \"/usr/lib64/python3.7/json/encoder.py\", line 199, in encode\n    chunks \u003d self.iterencode(o, _one_shot\u003dTrue)\n  File \"/usr/lib64/python3.7/json/encoder.py\", line 257, in iterencode\n    return _iterencode(o, 0)\n  File \"/usr/lib64/python3.7/json/encoder.py\", line 179, in default\n    raise TypeError(f\u0027Object of type {o.__class__.__name__} \u0027\nTypeError: Object of type bytes is not JSON serializable\n\u003e\u003e\u003e json.dumps(base64.b64encode(b\u0027asdf\u0027).decode(\u0027ascii\u0027))\n\u0027\"YXNkZg\u003d\u003d\"\u0027\n\nNot sure how that wasn\u0027t caught by a unit test...","commit_id":"4b93b91629cc76a4705758679b14f26de7829cda"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a8155b5909da08c9fef7801b30d3066f9011d017","unresolved":false,"context_lines":[{"line_number":923,"context_line":"                    r \u003d \u0027%s:%s;\u0027 % (seg_dict[\u0027hash\u0027], seg_dict[\u0027range\u0027])"},{"line_number":924,"context_line":"                else:"},{"line_number":925,"context_line":"                    r \u003d seg_dict[\u0027hash\u0027]"},{"line_number":926,"context_line":"                calculated_etag.update(r.encode(\u0027ascii\u0027) if six.PY3 else r)"},{"line_number":927,"context_line":""},{"line_number":928,"context_line":"            if content_length is None:"},{"line_number":929,"context_line":"                if config_true_value(seg_dict.get(\u0027sub_slo\u0027)):"}],"source_content_type":"text/x-python","patch_set":4,"id":"bfb3d3c7_51a046a6","line":926,"updated":"2019-05-16 21:44:49.000000000","message":"Should be safe to always encode.","commit_id":"4b93b91629cc76a4705758679b14f26de7829cda"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a8155b5909da08c9fef7801b30d3066f9011d017","unresolved":false,"context_lines":[{"line_number":1261,"context_line":"                resp_dict \u003d {}"},{"line_number":1262,"context_line":"                if heartbeat:"},{"line_number":1263,"context_line":"                    resp_dict[\u0027Response Status\u0027] \u003d err.status"},{"line_number":1264,"context_line":"                    err_body \u003d err.body"},{"line_number":1265,"context_line":"                    if six.PY3:"},{"line_number":1266,"context_line":"                        err_body \u003d err_body.decode(\u0027utf-8\u0027, errors\u003d\u0027replace\u0027)"},{"line_number":1267,"context_line":"                    resp_dict[\u0027Response Body\u0027] \u003d err_body or \u0027\\n\u0027.join("}],"source_content_type":"text/x-python","patch_set":4,"id":"bfb3d3c7_31b6f2db","line":1264,"updated":"2019-05-16 21:44:49.000000000","message":"I\u0027m partial toward always decoding, even on py2; if there\u0027s non-ASCII, it\u0027d cause us to blow up later when we go to serialize a JSON response.","commit_id":"4b93b91629cc76a4705758679b14f26de7829cda"}],"swift/common/utils.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"71c2fac17ae3b9318833ad6346998ebdc74f9812","unresolved":false,"context_lines":[{"line_number":4343,"context_line":"    :param read_chunk_size: size of strings read via input_file.read()"},{"line_number":4344,"context_line":"    \"\"\""},{"line_number":4345,"context_line":"    if six.PY3 and isinstance(boundary, str):"},{"line_number":4346,"context_line":"        # Since the boundary is in client-supplied headers, it can contain"},{"line_number":4347,"context_line":"        # garbage that trips us and we don\u0027t like client-induced 500."},{"line_number":4348,"context_line":"        boundary \u003d boundary.encode(\u0027latin-1\u0027, errors\u003d\u0027replace\u0027)"},{"line_number":4349,"context_line":"    doc_files \u003d iter_multipart_mime_documents(input_file, boundary,"},{"line_number":4350,"context_line":"                                              read_chunk_size)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5fc1f717_ca7866c2","line":4347,"range":{"start_line":4346,"start_character":10,"end_line":4347,"end_character":69},"updated":"2019-04-08 19:01:37.000000000","message":"Wait, who\u0027s the \"client\" here? I thought we only used the multipart mime docs for EC PUTs and multi-range GETs... in the first case, the proxy-server\u0027s the client, but it shouldn\u0027t be generating garbage, just hex [1], and in the second case, we don\u0027t use the client\u0027s boundary; the object-server picks one by way of swob.Response [2]. So how could we get garbage that trips us up?\n\n[1] https://github.com/openstack/swift/blob/2.21.0/swift/proxy/controllers/obj.py#L1852\n\n[2] https://github.com/openstack/swift/blob/2.21.0/swift/common/swob.py#L1251","commit_id":"3319b2a6b941a5f0f0416bb5275f28e849a8ba4f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"71c2fac17ae3b9318833ad6346998ebdc74f9812","unresolved":false,"context_lines":[{"line_number":4345,"context_line":"    if six.PY3 and isinstance(boundary, str):"},{"line_number":4346,"context_line":"        # Since the boundary is in client-supplied headers, it can contain"},{"line_number":4347,"context_line":"        # garbage that trips us and we don\u0027t like client-induced 500."},{"line_number":4348,"context_line":"        boundary \u003d boundary.encode(\u0027latin-1\u0027, errors\u003d\u0027replace\u0027)"},{"line_number":4349,"context_line":"    doc_files \u003d iter_multipart_mime_documents(input_file, boundary,"},{"line_number":4350,"context_line":"                                              read_chunk_size)"},{"line_number":4351,"context_line":"    for i, doc_file in enumerate(doc_files):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5fc1f717_ea544256","line":4348,"range":{"start_line":4348,"start_character":54,"end_line":4348,"end_character":61},"updated":"2019-04-08 19:01:37.000000000","message":"If we *do* manage to get non-Latin-1, this makes me nervous that we\u0027ll never find a boundary...","commit_id":"3319b2a6b941a5f0f0416bb5275f28e849a8ba4f"}]}
