)]}'
{"etc/proxy-server.conf-sample":[{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"aa48492d689e0d597c1f6bd4f6ec1e0cf37ae3e3","unresolved":false,"context_lines":[{"line_number":887,"context_line":"# log_anonymization_method \u003d MD5"},{"line_number":888,"context_line":"#"},{"line_number":889,"context_line":"# Salt added during log anonymization"},{"line_number":890,"context_line":"# log_anonymization_salt \u003d "},{"line_number":891,"context_line":"#"},{"line_number":892,"context_line":"# Template used to format access logs. All words surrounded by curly brackets"},{"line_number":893,"context_line":"# will be substituted with the appropriate values"}],"source_content_type":"application/octet-stream","patch_set":17,"id":"dfbec78f_e3116e55","line":890,"updated":"2019-05-02 20:44:35.000000000","message":"Aren\u0027t salts supposed to be unique (ie don\u0027t reuse them)? Then store the salt with the hashed value. So, something like\n\n    salt \u003d get_random_bytes(4)\n    hasher \u003d md5(salt)\n    hasher.update(plain_val)\n    anon_val \u003d \u0027%s:%s\u0027 % (salt, hashed.hex_digest())\n\nOf course, if the salt is different for every value, then you cannot match same IP addresses or anything else anonymized.","commit_id":"2d2c6dfcac2cee3756f7dc58d352f23e1ebd8863"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"48c4a3bd5a8b08f1b5a497a8fb213f15d916c60c","unresolved":false,"context_lines":[{"line_number":887,"context_line":"# log_anonymization_method \u003d MD5"},{"line_number":888,"context_line":"#"},{"line_number":889,"context_line":"# Salt added during log anonymization"},{"line_number":890,"context_line":"# log_anonymization_salt \u003d "},{"line_number":891,"context_line":"#"},{"line_number":892,"context_line":"# Template used to format access logs. All words surrounded by curly brackets"},{"line_number":893,"context_line":"# will be substituted with the appropriate values"}],"source_content_type":"application/octet-stream","patch_set":17,"id":"dfbec78f_523fe5d5","line":890,"in_reply_to":"dfbec78f_12c2cd86","updated":"2019-05-02 23:18:25.000000000","message":"yeah, that makes sense. I think \"salt\" is ok here, most likely","commit_id":"2d2c6dfcac2cee3756f7dc58d352f23e1ebd8863"},{"author":{"_account_id":13852,"name":"Romain LE DISEZ","email":"romain.le-disez@corp.ovh.com","username":"rledisez"},"change_message_id":"6b8fd314c1803ab4d9a6e3eeee7f7bb863466f52","unresolved":false,"context_lines":[{"line_number":887,"context_line":"# log_anonymization_method \u003d MD5"},{"line_number":888,"context_line":"#"},{"line_number":889,"context_line":"# Salt added during log anonymization"},{"line_number":890,"context_line":"# log_anonymization_salt \u003d "},{"line_number":891,"context_line":"#"},{"line_number":892,"context_line":"# Template used to format access logs. All words surrounded by curly brackets"},{"line_number":893,"context_line":"# will be substituted with the appropriate values"}],"source_content_type":"application/octet-stream","patch_set":17,"id":"dfbec78f_12c2cd86","line":890,"in_reply_to":"dfbec78f_e3116e55","updated":"2019-05-02 22:21:41.000000000","message":"Yeah, the idea of a static salt is to be able to do some meaningful statistics. Maybe it\u0027s a bad named variable (secret would be better?)","commit_id":"2d2c6dfcac2cee3756f7dc58d352f23e1ebd8863"}],"swift/common/middleware/proxy_logging.py":[{"author":{"_account_id":27887,"name":"Gilles Biannic","email":"gilles.biannic@corp.ovh.com","username":"gillesbiannic"},"change_message_id":"a23091198e46839e9191aa750c7d9e58709e9296","unresolved":false,"context_lines":[{"line_number":132,"context_line":"            \u0027log_name\u0027) or \u0027proxy-server\u0027"},{"line_number":133,"context_line":"        self.access_logger \u003d logger or get_logger(access_log_conf,"},{"line_number":134,"context_line":"                                                  log_route\u003d\u0027proxy-access\u0027,"},{"line_number":135,"context_line":"                                                  fmt\u003d\"%(message)s\")"},{"line_number":136,"context_line":"        self.access_logger.set_statsd_prefix(\u0027proxy-server\u0027)"},{"line_number":137,"context_line":"        self.reveal_sensitive_prefix \u003d int("},{"line_number":138,"context_line":"            conf.get(\u0027reveal_sensitive_prefix\u0027, 16))"}],"source_content_type":"text/x-python","patch_set":2,"id":"ff6b8bd7_ee0c0744","line":135,"updated":"2018-03-05 10:21:33.000000000","message":"Here we override the default fmt (from common/utils.py)","commit_id":"7b036ae3594d25009004de4a8de8c27c80e45bfb"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"767352ccf2f1174b2f3fbbbf520097769b9bc325","unresolved":false,"context_lines":[{"line_number":132,"context_line":"            \u0027log_name\u0027) or \u0027proxy-server\u0027"},{"line_number":133,"context_line":"        self.access_logger \u003d logger or get_logger(access_log_conf,"},{"line_number":134,"context_line":"                                                  log_route\u003d\u0027proxy-access\u0027,"},{"line_number":135,"context_line":"                                                  fmt\u003d\"%(message)s\")"},{"line_number":136,"context_line":"        self.access_logger.set_statsd_prefix(\u0027proxy-server\u0027)"},{"line_number":137,"context_line":"        self.reveal_sensitive_prefix \u003d int("},{"line_number":138,"context_line":"            conf.get(\u0027reveal_sensitive_prefix\u0027, 16))"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_feccb063","line":135,"in_reply_to":"ff6b8bd7_ee0c0744","updated":"2018-06-14 22:40:06.000000000","message":"Ah, interesting...\n\nNow I kinda want to get rid of fmt -- I don\u0027t think anyone actually *uses* it...","commit_id":"7b036ae3594d25009004de4a8de8c27c80e45bfb"},{"author":{"_account_id":13852,"name":"Romain LE DISEZ","email":"romain.le-disez@corp.ovh.com","username":"rledisez"},"change_message_id":"be74264c32aacbdc99645121e79982c37c3a5edc","unresolved":false,"context_lines":[{"line_number":96,"context_line":"    def __init__(self, app, conf, logger\u003dNone):"},{"line_number":97,"context_line":"        self.app \u003d app"},{"line_number":98,"context_line":"        self.log_msg_template \u003d conf.get("},{"line_number":99,"context_line":"            \u0027proxylogging_log_msg_template\u0027, ("},{"line_number":100,"context_line":"                \u0027{client_ip} {remote_addr} {ed}/{eb}/{eY}/{eH}/{eM}/{eS} \u0027"},{"line_number":101,"context_line":"                \u0027{request_method} {request_path} {protocol} {status_int} \u0027"},{"line_number":102,"context_line":"                \u0027{referer} {user_agent} {auth_token} {bytes_recvd} \u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_ecaf667a","line":99,"updated":"2018-05-30 21:54:07.000000000","message":"The variable name do not need to include proxylogging as it should be under the [filter:proxy-logging] section","commit_id":"f2a2db9660a35b7e0b177e2393605ca5c74a5b2d"},{"author":{"_account_id":13852,"name":"Romain LE DISEZ","email":"romain.le-disez@corp.ovh.com","username":"rledisez"},"change_message_id":"be74264c32aacbdc99645121e79982c37c3a5edc","unresolved":false,"context_lines":[{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def anonymize(self, info):"},{"line_number":138,"context_line":"        if info:"},{"line_number":139,"context_line":"            return md5(info).hexdigest()"},{"line_number":140,"context_line":"        else:"},{"line_number":141,"context_line":"            return \u0027-\u0027"},{"line_number":142,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_4cc3faed","line":139,"updated":"2018-05-30 21:54:07.000000000","message":"Do we care about dictionary attack? We might want to introduce some secret salt to avoid reversibility. Eg: prefix/suffix hash path?","commit_id":"f2a2db9660a35b7e0b177e2393605ca5c74a5b2d"},{"author":{"_account_id":13852,"name":"Romain LE DISEZ","email":"romain.le-disez@corp.ovh.com","username":"rledisez"},"change_message_id":"be74264c32aacbdc99645121e79982c37c3a5edc","unresolved":false,"context_lines":[{"line_number":248,"context_line":"            self.access_logger.info(self.log_msg_template.format("},{"line_number":249,"context_line":"                **replacements))"},{"line_number":250,"context_line":"        except KeyError as e:"},{"line_number":251,"context_line":"            raise ValueError(\u0027Cannot interpolate proxy_log_format, invalid\\"},{"line_number":252,"context_line":"                              variable: \u0027 \u0027%s\u0027 % e)"},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"        # Log timing and bytes-transferred data to StatsD"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_0c6e62ff","line":251,"range":{"start_line":251,"start_character":49,"end_line":251,"end_character":65},"updated":"2018-05-30 21:54:07.000000000","message":"wrong variable name. I guess it should be log_msg_template","commit_id":"f2a2db9660a35b7e0b177e2393605ca5c74a5b2d"},{"author":{"_account_id":13852,"name":"Romain LE DISEZ","email":"romain.le-disez@corp.ovh.com","username":"rledisez"},"change_message_id":"be74264c32aacbdc99645121e79982c37c3a5edc","unresolved":false,"context_lines":[{"line_number":249,"context_line":"                **replacements))"},{"line_number":250,"context_line":"        except KeyError as e:"},{"line_number":251,"context_line":"            raise ValueError(\u0027Cannot interpolate proxy_log_format, invalid\\"},{"line_number":252,"context_line":"                              variable: \u0027 \u0027%s\u0027 % e)"},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"        # Log timing and bytes-transferred data to StatsD"},{"line_number":255,"context_line":"        metric_name \u003d self.statsd_metric_name(req, status_int, method)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_4c369a05","line":252,"updated":"2018-05-30 21:54:07.000000000","message":"A wrong configuration might break the requests. Having a test in init would be nice to prevent the process to start if something is wrong. Not sure if it\u0027s a good idea or not...","commit_id":"f2a2db9660a35b7e0b177e2393605ca5c74a5b2d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"767352ccf2f1174b2f3fbbbf520097769b9bc325","unresolved":false,"context_lines":[{"line_number":220,"context_line":"            \u0027account\u0027: acc,"},{"line_number":221,"context_line":"            \u0027container\u0027: cont,"},{"line_number":222,"context_line":"            \u0027object\u0027: obj,"},{"line_number":223,"context_line":"            \u0027ea\u0027: time.strftime(\u0027%a\u0027, end_gmtime),"},{"line_number":224,"context_line":"            \u0027eb\u0027: time.strftime(\u0027%b\u0027, end_gmtime),"},{"line_number":225,"context_line":"            \u0027ed\u0027: time.strftime(\u0027%d\u0027, end_gmtime),"},{"line_number":226,"context_line":"            \u0027eH\u0027: time.strftime(\u0027%H\u0027, end_gmtime),"},{"line_number":227,"context_line":"            \u0027eI\u0027: time.strftime(\u0027%I\u0027, end_gmtime),"},{"line_number":228,"context_line":"            \u0027ej\u0027: time.strftime(\u0027%j\u0027, end_gmtime),"},{"line_number":229,"context_line":"            \u0027em\u0027: time.strftime(\u0027%m\u0027, end_gmtime),"},{"line_number":230,"context_line":"            \u0027eM\u0027: time.strftime(\u0027%M\u0027, end_gmtime),"},{"line_number":231,"context_line":"            \u0027ep\u0027: time.strftime(\u0027%p\u0027, end_gmtime),"},{"line_number":232,"context_line":"            \u0027eS\u0027: time.strftime(\u0027%S\u0027, end_gmtime),"},{"line_number":233,"context_line":"            \u0027eY\u0027: time.strftime(\u0027%Y\u0027, end_gmtime),"},{"line_number":234,"context_line":"            \u0027ems\u0027: end_time_str.split(\u0027.\u0027)[1][:3],"},{"line_number":235,"context_line":"            \u0027eus\u0027: end_time_str.split(\u0027.\u0027)[1][:6],"},{"line_number":236,"context_line":"            \u0027ens\u0027: end_time_str.split(\u0027.\u0027)[1]"},{"line_number":237,"context_line":"        }"},{"line_number":238,"context_line":"        for keyword, unsafe_data in replacements.iteritems():"},{"line_number":239,"context_line":"            replacements[keyword] \u003d quote(str(unsafe_data or \u0027-\u0027), QUOTE_SAFE)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_be1dd8bf","line":236,"range":{"start_line":223,"start_character":12,"end_line":236,"end_character":45},"updated":"2018-06-14 22:40:06.000000000","message":"It feels a little weird that we break these all out for the end time, but not the start time...\n\nUltimately, I think I mainly just dislike the {ed}/{eb}/{eY}/{eH}/{eM}/{eS} format :-(","commit_id":"bbb1c42e968559d4a40d21ac3935c6389c00d4ad"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"767352ccf2f1174b2f3fbbbf520097769b9bc325","unresolved":false,"context_lines":[{"line_number":238,"context_line":"        for keyword, unsafe_data in replacements.iteritems():"},{"line_number":239,"context_line":"            replacements[keyword] \u003d quote(str(unsafe_data or \u0027-\u0027), QUOTE_SAFE)"},{"line_number":240,"context_line":"        # Compute md5 only if anonymized infos are specified in the template"},{"line_number":241,"context_line":"        if \u0027{anonymized_request}\u0027 in self.log_msg_template:"},{"line_number":242,"context_line":"            replacements[\u0027anonymized_request\u0027] \u003d self.anonymize(the_request)"},{"line_number":243,"context_line":"        if \u0027{anonymized_container}\u0027 in self.log_msg_template:"},{"line_number":244,"context_line":"            replacements[\u0027anonymized_container\u0027] \u003d self.anonymize(cont)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_abb5b9ee","line":241,"range":{"start_line":241,"start_character":13,"end_line":241,"end_character":31},"updated":"2018-06-14 22:40:06.000000000","message":"Maybe better as anonymized_path? I suppose you\u0027re right that anonymized_request_path is too long...","commit_id":"bbb1c42e968559d4a40d21ac3935c6389c00d4ad"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"767352ccf2f1174b2f3fbbbf520097769b9bc325","unresolved":false,"context_lines":[{"line_number":243,"context_line":"        if \u0027{anonymized_container}\u0027 in self.log_msg_template:"},{"line_number":244,"context_line":"            replacements[\u0027anonymized_container\u0027] \u003d self.anonymize(cont)"},{"line_number":245,"context_line":"        if \u0027{anonymized_object}\u0027 in self.log_msg_template:"},{"line_number":246,"context_line":"            replacements[\u0027anonymized_object\u0027] \u003d self.anonymize(obj)"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"        try:"},{"line_number":249,"context_line":"            self.access_logger.info(self.log_msg_template.format("}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_0bc62d69","line":246,"updated":"2018-06-14 22:40:06.000000000","message":"A few others that may be interesting...\n\n- {anonymized_account}\n- {anonymized_referer}\n- {anonymized_user_agent}\n- {anonymized_client_ip}\n- {anonymized_remote_addr}\n\n...but that\u0027s just my gut feeling. You probably have more experience than me about what would be useful and worth anonymizing. *shrug*","commit_id":"bbb1c42e968559d4a40d21ac3935c6389c00d4ad"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"767352ccf2f1174b2f3fbbbf520097769b9bc325","unresolved":false,"context_lines":[{"line_number":250,"context_line":"                **replacements))"},{"line_number":251,"context_line":"        except KeyError as e:"},{"line_number":252,"context_line":"            raise ValueError(\u0027Cannot interpolate log_msg_template, invalid\\"},{"line_number":253,"context_line":"                              variable: \u0027 \u0027%s\u0027 % e)"},{"line_number":254,"context_line":""},{"line_number":255,"context_line":"        # Log timing and bytes-transferred data to StatsD"},{"line_number":256,"context_line":"        metric_name \u003d self.statsd_metric_name(req, status_int, method)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_6b6fa191","line":253,"updated":"2018-06-14 22:40:06.000000000","message":"Could we raise an error about this during service start, rather than in the request/response cycle? Seems like it\u0027d be preferable to fail fast than to not log requests and pollute logs until someone notices that the proxy-server config is bad...","commit_id":"bbb1c42e968559d4a40d21ac3935c6389c00d4ad"}],"swift/common/utils.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a569996a4cbfa3a70e7efd7e3bfd4a243f293009","unresolved":false,"context_lines":[{"line_number":653,"context_line":"            elif self.method \u003d\u003d \u0027SHA1\u0027:"},{"line_number":654,"context_line":"                h \u003d hashlib.sha1()"},{"line_number":655,"context_line":"            if self.salt:"},{"line_number":656,"context_line":"                h.update(self.salt)"},{"line_number":657,"context_line":"            h.update(six.b(self))"},{"line_number":658,"context_line":"            return \u0027{%s%s}%s\u0027 % (\u0027S\u0027 if self.salt else \u0027\u0027, self.method,"},{"line_number":659,"context_line":"                                 h.hexdigest())"}],"source_content_type":"text/x-python","patch_set":13,"id":"3f79a3b5_d29d5a6c","line":656,"range":{"start_line":656,"start_character":25,"end_line":656,"end_character":34},"updated":"2018-10-26 17:47:53.000000000","message":"Looks like this could use a six.b(), too.","commit_id":"cdafc6aadaf26435fd5e32011aefff7ca6df4bb7"},{"author":{"_account_id":13852,"name":"Romain LE DISEZ","email":"romain.le-disez@corp.ovh.com","username":"rledisez"},"change_message_id":"26e5b567d750ce46131f07750dbdec071dc24abf","unresolved":false,"context_lines":[{"line_number":653,"context_line":"            elif self.method \u003d\u003d \u0027SHA1\u0027:"},{"line_number":654,"context_line":"                h \u003d hashlib.sha1()"},{"line_number":655,"context_line":"            if self.salt:"},{"line_number":656,"context_line":"                h.update(self.salt)"},{"line_number":657,"context_line":"            h.update(six.b(self))"},{"line_number":658,"context_line":"            return \u0027{%s%s}%s\u0027 % (\u0027S\u0027 if self.salt else \u0027\u0027, self.method,"},{"line_number":659,"context_line":"                                 h.hexdigest())"}],"source_content_type":"text/x-python","patch_set":13,"id":"3f79a3b5_9a492667","line":656,"range":{"start_line":656,"start_character":25,"end_line":656,"end_character":34},"in_reply_to":"3f79a3b5_d29d5a6c","updated":"2018-10-29 10:03:36.000000000","message":"Done","commit_id":"cdafc6aadaf26435fd5e32011aefff7ca6df4bb7"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"aa48492d689e0d597c1f6bd4f6ec1e0cf37ae3e3","unresolved":false,"context_lines":[{"line_number":663,"context_line":"            if self.method \u003d\u003d \u0027MD5\u0027:"},{"line_number":664,"context_line":"                h \u003d hashlib.md5()"},{"line_number":665,"context_line":"            elif self.method \u003d\u003d \u0027SHA1\u0027:"},{"line_number":666,"context_line":"                h \u003d hashlib.sha1()"},{"line_number":667,"context_line":"            if self.salt:"},{"line_number":668,"context_line":"                h.update(six.b(self.salt))"},{"line_number":669,"context_line":"            h.update(six.b(self))"}],"source_content_type":"text/x-python","patch_set":17,"id":"dfbec78f_8388b271","line":666,"updated":"2019-05-02 20:44:35.000000000","message":"why not support anything that is in hashlib?\n\n    h \u003d getattr(hashlib, self.method)","commit_id":"2d2c6dfcac2cee3756f7dc58d352f23e1ebd8863"},{"author":{"_account_id":13852,"name":"Romain LE DISEZ","email":"romain.le-disez@corp.ovh.com","username":"rledisez"},"change_message_id":"6b8fd314c1803ab4d9a6e3eeee7f7bb863466f52","unresolved":false,"context_lines":[{"line_number":663,"context_line":"            if self.method \u003d\u003d \u0027MD5\u0027:"},{"line_number":664,"context_line":"                h \u003d hashlib.md5()"},{"line_number":665,"context_line":"            elif self.method \u003d\u003d \u0027SHA1\u0027:"},{"line_number":666,"context_line":"                h \u003d hashlib.sha1()"},{"line_number":667,"context_line":"            if self.salt:"},{"line_number":668,"context_line":"                h.update(six.b(self.salt))"},{"line_number":669,"context_line":"            h.update(six.b(self))"}],"source_content_type":"text/x-python","patch_set":17,"id":"dfbec78f_923b1d9b","line":666,"in_reply_to":"dfbec78f_8388b271","updated":"2019-05-02 22:21:41.000000000","message":"Done","commit_id":"2d2c6dfcac2cee3756f7dc58d352f23e1ebd8863"}],"test/unit/common/middleware/test_proxy_logging.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"78f8c96d08afd2ede6d8586ca67f56836a83d8d5","unresolved":false,"context_lines":[{"line_number":392,"context_line":"        self.assertEqual(log_parts[6], \u0027HTTP/1.0\u0027)"},{"line_number":393,"context_line":"        self.assertEqual(log_parts[7], \u0027200\u0027)"},{"line_number":394,"context_line":"        self.assertEqual(resp_body, \u0027FAKE APP\u0027)"},{"line_number":395,"context_line":"        self.assertEqual(log_parts[12], str(len(resp_body)))"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"    def test_basic_req_second_time(self):"},{"line_number":398,"context_line":"        app \u003d proxy_logging.ProxyLoggingMiddleware(FakeApp(), {})"}],"source_content_type":"text/x-python","patch_set":1,"id":"1f9dbf25_6d6c5836","line":395,"updated":"2018-03-02 01:06:10.000000000","message":"This shifting makes me nervous. It seems like we\u0027re adding the log name when it wasn\u0027t there before -- won\u0027t this break existing log-parsing solutions? I don\u0027t see anything about log name in https://docs.openstack.org/swift/latest/logs.html#proxy-logs\n\nI know I see that sort of a thing pretty often in my own logs, though -- maybe it typically gets configured (or defaulted in) on the rsyslog side of things?","commit_id":"cc91e7285071069983a3c9d0ba0008981c74b0ad"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a569996a4cbfa3a70e7efd7e3bfd4a243f293009","unresolved":false,"context_lines":[{"line_number":3507,"context_line":""},{"line_number":3508,"context_line":"        lf \u003d utils.LogStringFormatter(quote\u003dTrue)"},{"line_number":3509,"context_line":"        self.assertEqual(lf.format(\u0027{a} {b}\u0027, a\u003d\u0027Swift est\u0027, b\u003d\u0027g\\xc3nial ^^\u0027),"},{"line_number":3510,"context_line":"                         \u0027Swift%20est g%EF%BF%BDnial%20%5E%5E\u0027)"},{"line_number":3511,"context_line":""},{"line_number":3512,"context_line":"    def test_str_anonymizer(self):"},{"line_number":3513,"context_line":"        anon \u003d utils.StrAnonymizer(\u0027Swift is great!\u0027, \u0027md5\u0027, \u0027\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"3f79a3b5_32e4ce0a","line":3510,"range":{"start_line":3510,"start_character":39,"end_line":3510,"end_character":48},"updated":"2018-10-26 17:47:53.000000000","message":"u\u0027\\ufffd\u0027? The replacement character? I was kinda expecting just %C3...\n\nIf we\u0027re intentionally testing that a byte string that isn\u0027t valid UTF-8 gets a quoted replacement char, we should probably leave a comment about that. Otherwise, we might want to make `b` a unicode string.","commit_id":"cdafc6aadaf26435fd5e32011aefff7ca6df4bb7"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"6c29e5129fc977f4d652fd53e5333448ef4f20a0","unresolved":false,"context_lines":[{"line_number":3507,"context_line":""},{"line_number":3508,"context_line":"        lf \u003d utils.LogStringFormatter(quote\u003dTrue)"},{"line_number":3509,"context_line":"        self.assertEqual(lf.format(\u0027{a} {b}\u0027, a\u003d\u0027Swift est\u0027, b\u003d\u0027g\\xc3nial ^^\u0027),"},{"line_number":3510,"context_line":"                         \u0027Swift%20est g%EF%BF%BDnial%20%5E%5E\u0027)"},{"line_number":3511,"context_line":""},{"line_number":3512,"context_line":"    def test_str_anonymizer(self):"},{"line_number":3513,"context_line":"        anon \u003d utils.StrAnonymizer(\u0027Swift is great!\u0027, \u0027md5\u0027, \u0027\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"3f79a3b5_482e7a8d","line":3510,"range":{"start_line":3510,"start_character":39,"end_line":3510,"end_character":48},"in_reply_to":"3f79a3b5_32e4ce0a","updated":"2018-10-26 22:15:24.000000000","message":"Very suspicious and wrong-looking indeed. But usually something you don\u0027t see n py2.","commit_id":"cdafc6aadaf26435fd5e32011aefff7ca6df4bb7"},{"author":{"_account_id":13852,"name":"Romain LE DISEZ","email":"romain.le-disez@corp.ovh.com","username":"rledisez"},"change_message_id":"26e5b567d750ce46131f07750dbdec071dc24abf","unresolved":false,"context_lines":[{"line_number":3507,"context_line":""},{"line_number":3508,"context_line":"        lf \u003d utils.LogStringFormatter(quote\u003dTrue)"},{"line_number":3509,"context_line":"        self.assertEqual(lf.format(\u0027{a} {b}\u0027, a\u003d\u0027Swift est\u0027, b\u003d\u0027g\\xc3nial ^^\u0027),"},{"line_number":3510,"context_line":"                         \u0027Swift%20est g%EF%BF%BDnial%20%5E%5E\u0027)"},{"line_number":3511,"context_line":""},{"line_number":3512,"context_line":"    def test_str_anonymizer(self):"},{"line_number":3513,"context_line":"        anon \u003d utils.StrAnonymizer(\u0027Swift is great!\u0027, \u0027md5\u0027, \u0027\u0027)"}],"source_content_type":"text/x-python","patch_set":13,"id":"3f79a3b5_5a9dceb7","line":3510,"range":{"start_line":3510,"start_character":39,"end_line":3510,"end_character":48},"in_reply_to":"3f79a3b5_32e4ce0a","updated":"2018-10-29 10:03:36.000000000","message":"You\u0027re right. I used quote() to generate the expected result, but I made a mistake in the source string (g\\xc3nial, but the right spelling is g\\xc3\\xa9nial)\n\nGood catch.","commit_id":"cdafc6aadaf26435fd5e32011aefff7ca6df4bb7"}]}
