)]}'
{"swift/common/middleware/bulk.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a38aeb43e775b5d09286002bbcbaed880e8da185","unresolved":false,"context_lines":[{"line_number":295,"context_line":"def quote_x(s):"},{"line_number":296,"context_line":"    if six.PY3:"},{"line_number":297,"context_line":"        return quote(s, errors\u003d\u0027replace\u0027)"},{"line_number":298,"context_line":"    return quote(s)"},{"line_number":299,"context_line":""},{"line_number":300,"context_line":""},{"line_number":301,"context_line":"class Bulk(object):"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_517e5a1a","line":298,"updated":"2018-11-23 08:41:27.000000000","message":"really *sigh*. Yay py3 so much fun.","commit_id":"5182dc06f3832837c571adc6df161abb97615d1b"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a38aeb43e775b5d09286002bbcbaed880e8da185","unresolved":false,"context_lines":[{"line_number":354,"context_line":"        # We have to manipulate line in bytes because we\u0027re appending"},{"line_number":355,"context_line":"        # results of read() to it; if we were to attempt to decode the"},{"line_number":356,"context_line":"        # chunk, we\u0027d run a risk of running into an invalid code at the"},{"line_number":357,"context_line":"        # end of it."},{"line_number":358,"context_line":"        line \u003d b\u0027\u0027"},{"line_number":359,"context_line":"        data_remaining \u003d True"},{"line_number":360,"context_line":"        objs_to_delete \u003d []"}],"source_content_type":"text/x-python","patch_set":1,"id":"3f79a3b5_f1768640","line":357,"updated":"2018-11-23 08:41:27.000000000","message":"Thanks for these comments, that\u0027ll make maintenence much easier, nice one.","commit_id":"5182dc06f3832837c571adc6df161abb97615d1b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d1d0909ba749fa5590de917b227955945a0b7844","unresolved":false,"context_lines":[{"line_number":294,"context_line":"# ... in position 51: surrogates not allowed\". Le sigh."},{"line_number":295,"context_line":"def quote_x(s):"},{"line_number":296,"context_line":"    if six.PY3:"},{"line_number":297,"context_line":"        return quote(s, errors\u003d\u0027replace\u0027)"},{"line_number":298,"context_line":"    return quote(s)"},{"line_number":299,"context_line":""},{"line_number":300,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9fdfeff1_bc2e4cf7","line":297,"range":{"start_line":297,"start_character":32,"end_line":297,"end_character":39},"updated":"2019-03-01 23:35:18.000000000","message":"So... instead of giving the user the bad bytes, we give the a replacement character? I was just fighting this in eventlet over in https://github.com/eventlet/eventlet/pull/554 :-/\n\nWhat kind of mileage can we get with surrogateescape?","commit_id":"e21aa7364e39479722cc1b3f37f4a2e8ba77d922"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"69e6935c9f82bb38a2a34a91d31614e83f9e1c3c","unresolved":false,"context_lines":[{"line_number":294,"context_line":"# ... in position 51: surrogates not allowed\". Le sigh."},{"line_number":295,"context_line":"def quote_x(s):"},{"line_number":296,"context_line":"    if six.PY3:"},{"line_number":297,"context_line":"        return quote(s, errors\u003d\u0027replace\u0027)"},{"line_number":298,"context_line":"    return quote(s)"},{"line_number":299,"context_line":""},{"line_number":300,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9fdfeff1_09ab7d1e","line":297,"range":{"start_line":297,"start_character":32,"end_line":297,"end_character":39},"in_reply_to":"9fdfeff1_bc2e4cf7","updated":"2019-03-02 03:49:38.000000000","message":"Whoops, what a fool I was. I looked at the docs for the urllib, and that one only mentions the \u0027replace\u0027. However, it also says that any error definition works. I fixed this up, so we don\u0027t have API incompatibility anymore.","commit_id":"e21aa7364e39479722cc1b3f37f4a2e8ba77d922"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c186958d4600ec23de226ec0d6da76445036d2a6","unresolved":false,"context_lines":[{"line_number":223,"context_line":"                      \u0027text/xml\u0027]"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":""},{"line_number":226,"context_line":"def get_response_body(data_format, data_dict, error_list, root_tag):"},{"line_number":227,"context_line":"    \"\"\""},{"line_number":228,"context_line":"    Returns a properly formatted response body according to format."},{"line_number":229,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5fc1f717_acea0972","line":226,"updated":"2019-03-11 21:46:49.000000000","message":"Since this is explicitly for use in a Response body, should it return bytes?","commit_id":"ba7f345385c131028451862e42b7cbeb542c5f66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c186958d4600ec23de226ec0d6da76445036d2a6","unresolved":false,"context_lines":[{"line_number":274,"context_line":"    elif pax_key.startswith(u\"SCHILY.xattr.user.meta.\"):"},{"line_number":275,"context_line":"        useful_part \u003d pax_key[len(u\"SCHILY.xattr.user.meta.\"):]"},{"line_number":276,"context_line":"        if six.PY3:"},{"line_number":277,"context_line":"            return \"X-Object-Meta-\" + useful_part"},{"line_number":278,"context_line":"        return \"X-Object-Meta-\" + useful_part.encode(\"utf-8\")"},{"line_number":279,"context_line":"    elif pax_key.startswith(u\"LIBARCHIVE.xattr.user.meta.\"):"},{"line_number":280,"context_line":"        useful_part \u003d pax_key[len(u\"LIBARCHIVE.xattr.user.meta.\"):]"}],"source_content_type":"text/x-python","patch_set":4,"id":"5fc1f717_ec62513e","line":277,"updated":"2019-03-11 21:46:49.000000000","message":"How do PAX keys handle non-Latin-1 data?","commit_id":"ba7f345385c131028451862e42b7cbeb542c5f66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c186958d4600ec23de226ec0d6da76445036d2a6","unresolved":false,"context_lines":[{"line_number":374,"context_line":"                        obj_to_delete \u003d obj_to_delete.decode(\u0027utf-8\u0027)"},{"line_number":375,"context_line":"                    except UnicodeDecodeError:"},{"line_number":376,"context_line":"                        objs_to_delete.append("},{"line_number":377,"context_line":"                            {\u0027name\u0027: obj_to_delete.decode(\u0027utf-8\u0027, \u0027replace\u0027),"},{"line_number":378,"context_line":"                             \u0027error\u0027:"},{"line_number":379,"context_line":"                                {\u0027code\u0027: HTTP_PRECONDITION_FAILED,"},{"line_number":380,"context_line":"                                 \u0027message\u0027: HTTPPreconditionFailed().status}})"}],"source_content_type":"text/x-python","patch_set":4,"id":"5fc1f717_c05dd9e9","line":377,"range":{"start_line":377,"start_character":68,"end_line":377,"end_character":75},"updated":"2019-03-11 21:46:49.000000000","message":"Hmm... losing information again...","commit_id":"ba7f345385c131028451862e42b7cbeb542c5f66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c186958d4600ec23de226ec0d6da76445036d2a6","unresolved":false,"context_lines":[{"line_number":560,"context_line":"                     \u0027Response Body\u0027: \u0027\u0027, \u0027Number Files Created\u0027: 0}"},{"line_number":561,"context_line":"        failed_files \u003d []"},{"line_number":562,"context_line":"        last_yield \u003d time()"},{"line_number":563,"context_line":"        separator \u003d \u0027\u0027"},{"line_number":564,"context_line":"        containers_accessed \u003d set()"},{"line_number":565,"context_line":"        req.environ[\u0027eventlet.minimum_write_chunk_size\u0027] \u003d 0"},{"line_number":566,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5fc1f717_0c99dd1d","line":563,"updated":"2019-03-11 21:46:49.000000000","message":"If get_response_body() returned bytes, this could always be bytes too, and we wouldn\u0027t have the\n\n if six.PY3:\n\nbelow...","commit_id":"ba7f345385c131028451862e42b7cbeb542c5f66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c186958d4600ec23de226ec0d6da76445036d2a6","unresolved":false,"context_lines":[{"line_number":588,"context_line":"                    separator \u003d \u0027\\r\\n\\r\\n\u0027"},{"line_number":589,"context_line":"                    last_yield \u003d time()"},{"line_number":590,"context_line":"                    yield b\u0027 \u0027"},{"line_number":591,"context_line":"                tar_info \u003d tar.next()"},{"line_number":592,"context_line":"                if tar_info is None or \\"},{"line_number":593,"context_line":"                        len(failed_files) \u003e\u003d self.max_failed_extractions:"},{"line_number":594,"context_line":"                    break"}],"source_content_type":"text/x-python","patch_set":4,"id":"5fc1f717_8c094d32","line":591,"updated":"2019-03-11 21:46:49.000000000","message":"Wait, really? I\u0027d gotten so used to switching thing.next() to next(thing) after hitting\n\n AttributeError: \u0027generator\u0027 object has no attribute \u0027next\u0027\n\nall over the place... but yeah, looks like they don\u0027t implement a __next__... ugh.\n\nI\u0027m kinda tempted to switch this over to something like\n\n for tar_info in tar:\n\nI\u0027m not really clear on what the\n\n while True:\n\nbuys us...","commit_id":"ba7f345385c131028451862e42b7cbeb542c5f66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"76e02db917c26ac70c659c2418e48ad897316ccc","unresolved":false,"context_lines":[{"line_number":275,"context_line":"        useful_part \u003d pax_key[len(u\"SCHILY.xattr.user.meta.\"):]"},{"line_number":276,"context_line":"        if six.PY3:"},{"line_number":277,"context_line":"            return \"X-Object-Meta-\" + useful_part"},{"line_number":278,"context_line":"        return \"X-Object-Meta-\" + useful_part.encode(\"utf-8\")"},{"line_number":279,"context_line":"    elif pax_key.startswith(u\"LIBARCHIVE.xattr.user.meta.\"):"},{"line_number":280,"context_line":"        useful_part \u003d pax_key[len(u\"LIBARCHIVE.xattr.user.meta.\"):]"},{"line_number":281,"context_line":"        if six.PY3:"}],"source_content_type":"text/x-python","patch_set":6,"id":"5fc1f717_0d5c4849","line":278,"range":{"start_line":278,"start_character":54,"end_line":278,"end_character":59},"updated":"2019-04-09 15:08:41.000000000","message":"Well there\u0027s some good news: apparently tarfile only supports UTF-8, so we don\u0027t have to worry about other weird things:\n\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \"/usr/lib/python2.7/tarfile.py\", line 1587, in __init__\n    self.firstmember \u003d self.next()\n  File \"/usr/lib/python2.7/tarfile.py\", line 2358, in next\n    tarinfo \u003d self.tarinfo.fromtarfile(self)\n  File \"/usr/lib/python2.7/tarfile.py\", line 1254, in fromtarfile\n    return obj._proc_member(tarfile)\n  File \"/usr/lib/python2.7/tarfile.py\", line 1276, in _proc_member\n    return self._proc_pax(tarfile)\n  File \"/usr/lib/python2.7/tarfile.py\", line 1406, in _proc_pax\n    value \u003d value.decode(\"utf8\")\n  File \"/usr/lib/python2.7/encodings/utf_8.py\", line 16, in decode\n    return codecs.utf_8_decode(input, errors, True)\nUnicodeDecodeError: \u0027utf8\u0027 codec can\u0027t decode byte 0x80 in position 0: invalid start byte","commit_id":"6301bb854b94f8f980639c39c90123117f008009"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"76e02db917c26ac70c659c2418e48ad897316ccc","unresolved":false,"context_lines":[{"line_number":408,"context_line":"                    self.max_deletes_per_request)"},{"line_number":409,"context_line":"            if len(line) \u003e self.max_path_length * 2:"},{"line_number":410,"context_line":"                raise HTTPBadRequest(\u0027Invalid File Name\u0027)"},{"line_number":411,"context_line":"        return objs_to_delete"},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"    def handle_delete_iter(self, req, objs_to_delete\u003dNone,"},{"line_number":414,"context_line":"                           user_agent\u003d\u0027BulkDelete\u0027, swift_source\u003d\u0027BD\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"5fc1f717_000f2f2e","line":411,"updated":"2019-04-09 15:08:41.000000000","message":"Off-topic: So we carefully read the user input one chunk at a time, presumably out of memory concerns so we don\u0027t go slurping up some client-provided input of unknown size and getting OOM-killed... but then we assemble it all into one big list that we have to fit into memory anyway? *sigh*","commit_id":"6301bb854b94f8f980639c39c90123117f008009"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"76e02db917c26ac70c659c2418e48ad897316ccc","unresolved":false,"context_lines":[{"line_number":475,"context_line":"                                            obj_name.lstrip(\u0027/\u0027)])"},{"line_number":476,"context_line":"                    if not constraints.check_utf8(delete_path):"},{"line_number":477,"context_line":"                        failed_files.append([quote(obj_name),"},{"line_number":478,"context_line":"                                             HTTPPreconditionFailed().status])"},{"line_number":479,"context_line":"                        continue"},{"line_number":480,"context_line":"                    yield (obj_name, delete_path)"},{"line_number":481,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"5fc1f717_c3fff1ff","line":478,"updated":"2019-04-09 15:08:41.000000000","message":"So this is where non-UTF-8 names would get flagged on py2, yeah? But on py3 we do it up in get_objs_to_delete()","commit_id":"6301bb854b94f8f980639c39c90123117f008009"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9be147159c4b7d2789a4102e2f92ec398b0aee1e","unresolved":false,"context_lines":[{"line_number":484,"context_line":"                                            obj_name.lstrip(\u0027/\u0027)])"},{"line_number":485,"context_line":"                    if not constraints.check_utf8(delete_path):"},{"line_number":486,"context_line":"                        failed_files.append([quote(obj_name),"},{"line_number":487,"context_line":"                                             HTTPPreconditionFailed().status])"},{"line_number":488,"context_line":"                        continue"},{"line_number":489,"context_line":"                    yield (obj_name, delete_path)"},{"line_number":490,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"ffb9cba7_55d2205e","line":487,"updated":"2019-05-07 00:04:26.000000000","message":"Still weirds me out a little that we have two ways to flag non-UTF8 names.","commit_id":"0a54a53a11899df735b4576d99ca98059ab43c0d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9be147159c4b7d2789a4102e2f92ec398b0aee1e","unresolved":false,"context_lines":[{"line_number":608,"context_line":"                        obj_path \u003d obj_path[2:]"},{"line_number":609,"context_line":"                    obj_path \u003d obj_path.lstrip(\u0027/\u0027)"},{"line_number":610,"context_line":"                    if extract_base:"},{"line_number":611,"context_line":"                        obj_path \u003d extract_base + \u0027/\u0027 + obj_path"},{"line_number":612,"context_line":"                    if \u0027/\u0027 not in obj_path:"},{"line_number":613,"context_line":"                        continue  # ignore base level file"},{"line_number":614,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"dfbec78f_39547bca","line":611,"range":{"start_line":611,"start_character":35,"end_line":611,"end_character":64},"updated":"2019-05-07 00:04:26.000000000","message":"extract_base came from the request path (so it should be WSGI), but obj_path is native...","commit_id":"0a54a53a11899df735b4576d99ca98059ab43c0d"}],"test/unit/common/middleware/test_bulk.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c186958d4600ec23de226ec0d6da76445036d2a6","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    if isinstance(tree_obj, six.binary_type) or \\"},{"line_number":131,"context_line":"            isinstance(tree_obj, six.text_type):"},{"line_number":132,"context_line":"        obj_path \u003d os.path.join(start_path, tree_obj)"},{"line_number":133,"context_line":"        tar_info \u003d tarfile.TarInfo(\u0027./\u0027 + obj_path[len(base_path):])"},{"line_number":134,"context_line":"        tar.addfile(tar_info)"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5fc1f717_60d0a520","line":133,"updated":"2019-03-11 21:46:49.000000000","message":"I would\u0027ve expected this to throw a TypeError on py3 if tree_obj were bytes... are we sure we shouldn\u0027t be checking for just str?","commit_id":"ba7f345385c131028451862e42b7cbeb542c5f66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c186958d4600ec23de226ec0d6da76445036d2a6","unresolved":false,"context_lines":[{"line_number":182,"context_line":"            tar_info1.pax_headers[u\u0027SCHILY.xattr.user.mime_type\u0027] \u003d \\"},{"line_number":183,"context_line":"                u\u0027application/food-diary\u0027"},{"line_number":184,"context_line":"            tar_info1.pax_headers[u\u0027SCHILY.xattr.user.meta.lunch\u0027] \u003d \\"},{"line_number":185,"context_line":"                u\u0027sopa de albóndigas\u0027"},{"line_number":186,"context_line":"            tar_info1.pax_headers["},{"line_number":187,"context_line":"                u\u0027SCHILY.xattr.user.meta.afternoon-snack\u0027] \u003d \\"},{"line_number":188,"context_line":"                u\u0027gigantic bucket of coffee\u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"5fc1f717_a0dd2d43","line":185,"range":{"start_line":185,"start_character":26,"end_line":185,"end_character":36},"updated":"2019-03-11 21:46:49.000000000","message":"I\u0027d be very interested in having some *keys* that were non-ascii, too...","commit_id":"ba7f345385c131028451862e42b7cbeb542c5f66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c186958d4600ec23de226ec0d6da76445036d2a6","unresolved":false,"context_lines":[{"line_number":241,"context_line":""},{"line_number":242,"context_line":"    def tearDown(self):"},{"line_number":243,"context_line":"        self.app.calls \u003d 0"},{"line_number":244,"context_line":"        # rmtree(self.testdir, ignore_errors\u003d1)"},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"    def handle_extract_and_iter(self, req, compress_format,"},{"line_number":247,"context_line":"                                out_content_type\u003d\u0027application/json\u0027):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5fc1f717_80cb5170","line":244,"updated":"2019-03-11 21:46:49.000000000","message":"??","commit_id":"ba7f345385c131028451862e42b7cbeb542c5f66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c186958d4600ec23de226ec0d6da76445036d2a6","unresolved":false,"context_lines":[{"line_number":791,"context_line":"        if six.PY3:"},{"line_number":792,"context_line":"            self.assertEqual("},{"line_number":793,"context_line":"                Counter(self.app.delete_paths),"},{"line_number":794,"context_line":"                Counter([\u0027/delete_works/AUTH_Acc/c/ obj \\u2661\u0027,"},{"line_number":795,"context_line":"                         \u0027/delete_works/AUTH_Acc/c/ objbadutf8\u0027]))"},{"line_number":796,"context_line":"        else:"},{"line_number":797,"context_line":"            self.assertEqual("}],"source_content_type":"text/x-python","patch_set":4,"id":"5fc1f717_e08fb520","line":794,"range":{"start_line":794,"start_character":57,"end_line":794,"end_character":62},"updated":"2019-03-11 21:46:49.000000000","message":"I feel like our quoting or decoding must not be right -- aren\u0027t these delete_paths coming out of some env[\u0027PATH_INFO\u0027] (and so should be WSGI strings)?","commit_id":"ba7f345385c131028451862e42b7cbeb542c5f66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c186958d4600ec23de226ec0d6da76445036d2a6","unresolved":false,"context_lines":[{"line_number":808,"context_line":"                Counter(map(tuple, resp_data[\u0027Errors\u0027])),"},{"line_number":809,"context_line":"                Counter([(urllib.parse.quote(\u0027c/ objbadutf8\u0027),"},{"line_number":810,"context_line":"                          \u0027412 Precondition Failed\u0027),"},{"line_number":811,"context_line":"                         (\u0027/c/f%EF%BF%BDbadutf8\u0027,"},{"line_number":812,"context_line":"                          \u0027412 Precondition Failed\u0027)]))"},{"line_number":813,"context_line":"        else:"},{"line_number":814,"context_line":"            self.assertEqual("}],"source_content_type":"text/x-python","patch_set":4,"id":"5fc1f717_c0b5d9ce","line":811,"range":{"start_line":811,"start_character":31,"end_line":811,"end_character":40},"updated":"2019-03-11 21:46:49.000000000","message":"And this is a replacement char, right? I still feel like it\u0027d be better if we could preserve this as %DE to match what the client actually sent...","commit_id":"ba7f345385c131028451862e42b7cbeb542c5f66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"76e02db917c26ac70c659c2418e48ad897316ccc","unresolved":false,"context_lines":[{"line_number":241,"context_line":""},{"line_number":242,"context_line":"    def tearDown(self):"},{"line_number":243,"context_line":"        self.app.calls \u003d 0"},{"line_number":244,"context_line":"        # rmtree(self.testdir, ignore_errors\u003d1)"},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"    def handle_extract_and_iter(self, req, compress_format,"},{"line_number":247,"context_line":"                                out_content_type\u003d\u0027application/json\u0027):"}],"source_content_type":"text/x-python","patch_set":6,"id":"5fc1f717_2394b535","line":244,"updated":"2019-04-09 15:08:41.000000000","message":"Is this supposed to still be commented out?","commit_id":"6301bb854b94f8f980639c39c90123117f008009"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"a5222b65d0c6122b1ae9e0636e696e739ce38048","unresolved":false,"context_lines":[{"line_number":241,"context_line":""},{"line_number":242,"context_line":"    def tearDown(self):"},{"line_number":243,"context_line":"        self.app.calls \u003d 0"},{"line_number":244,"context_line":"        # rmtree(self.testdir, ignore_errors\u003d1)"},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"    def handle_extract_and_iter(self, req, compress_format,"},{"line_number":247,"context_line":"                                out_content_type\u003d\u0027application/json\u0027):"}],"source_content_type":"text/x-python","patch_set":6,"id":"ffb9cba7_ef127cb1","line":244,"in_reply_to":"5fc1f717_2394b535","updated":"2019-04-24 01:23:23.000000000","message":"Done","commit_id":"6301bb854b94f8f980639c39c90123117f008009"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"76e02db917c26ac70c659c2418e48ad897316ccc","unresolved":false,"context_lines":[{"line_number":798,"context_line":"            self.assertEqual("},{"line_number":799,"context_line":"                Counter(self.app.delete_paths),"},{"line_number":800,"context_line":"                Counter([\u0027/delete_works/AUTH_Acc/c/ obj \\xe2\\x99\\xa1\u0027,"},{"line_number":801,"context_line":"                         \u0027/delete_works/AUTH_Acc/c/ objbadutf8\u0027]))"},{"line_number":802,"context_line":""},{"line_number":803,"context_line":"        self.assertEqual(self.app.calls, 2)"},{"line_number":804,"context_line":"        resp_data \u003d utils.json.loads(resp_body)"}],"source_content_type":"text/x-python","patch_set":6,"id":"5fc1f717_c3d291fd","line":801,"updated":"2019-04-09 15:08:41.000000000","message":"I think I\u0027d rather keep the one code path and just flag that these are WSGI strings.","commit_id":"6301bb854b94f8f980639c39c90123117f008009"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"76e02db917c26ac70c659c2418e48ad897316ccc","unresolved":false,"context_lines":[{"line_number":809,"context_line":"                Counter(map(tuple, resp_data[\u0027Errors\u0027])),"},{"line_number":810,"context_line":"                Counter([(urllib.parse.quote(\u0027c/ objbadutf8\u0027),"},{"line_number":811,"context_line":"                          \u0027412 Precondition Failed\u0027),"},{"line_number":812,"context_line":"                         (\u0027/c/f%EF%BF%BDbadutf8\u0027,"},{"line_number":813,"context_line":"                          \u0027412 Precondition Failed\u0027)]))"},{"line_number":814,"context_line":"        else:"},{"line_number":815,"context_line":"            self.assertEqual("}],"source_content_type":"text/x-python","patch_set":6,"id":"5fc1f717_43b6a1fb","line":812,"range":{"start_line":812,"start_character":31,"end_line":812,"end_character":40},"updated":"2019-04-09 15:08:41.000000000","message":"I don\u0027t think we\u0027re doing clients any favors here -- they didn\u0027t send a replacement char, they sent a \u0027\\xde\u0027. I\u0027m OK with turning that into a %DE or something so we know what encoding our response is, but replacement chars (and only when the server is py3) aren\u0027t great for debugging -- particularly since the user *could* have included a request that actually involved a replacement char and *it would have worked*.","commit_id":"6301bb854b94f8f980639c39c90123117f008009"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9be147159c4b7d2789a4102e2f92ec398b0aee1e","unresolved":false,"context_lines":[{"line_number":809,"context_line":"                Counter(map(tuple, resp_data[\u0027Errors\u0027])),"},{"line_number":810,"context_line":"                Counter([(urllib.parse.quote(\u0027c/ objbadutf8\u0027),"},{"line_number":811,"context_line":"                          \u0027412 Precondition Failed\u0027),"},{"line_number":812,"context_line":"                         (\u0027/c/f%EF%BF%BDbadutf8\u0027,"},{"line_number":813,"context_line":"                          \u0027412 Precondition Failed\u0027)]))"},{"line_number":814,"context_line":"        else:"},{"line_number":815,"context_line":"            self.assertEqual("}],"source_content_type":"text/x-python","patch_set":7,"id":"ffb9cba7_753ac498","line":812,"range":{"start_line":812,"start_character":31,"end_line":812,"end_character":40},"updated":"2019-05-07 00:04:26.000000000","message":"Still passing back replacement chars, eh?","commit_id":"0a54a53a11899df735b4576d99ca98059ab43c0d"}]}
