)]}'
{"nova/hacking/checks.py":[{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"2aa5aad8ea1339a74304f480fa555691e1115514","unresolved":false,"context_lines":[{"line_number":302,"context_line":"    \"\"\"Check for \u0027from nova.i18n import _\u0027"},{"line_number":303,"context_line":"    N337"},{"line_number":304,"context_line":"    \"\"\""},{"line_number":305,"context_line":"    if pep8.noqa(physical_line):"},{"line_number":306,"context_line":"        return"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    if \u0027nova/tests/\u0027 in filename:"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba15a1d1_4220e3f7","line":305,"updated":"2015-09-13 05:44:21.000000000","message":"can you add a unit test to check this update","commit_id":"ee47d7aa4749e34ba1b7490e3be6623e9b4bf516"}],"nova/tests/fixtures.py":[{"author":{"_account_id":16839,"name":"Cale Rath","email":"ctrath@us.ibm.com","username":"ctrath"},"change_message_id":"21e9782e0f40c5cb3728d6954e9523553a2efcf8","unresolved":false,"context_lines":[{"line_number":69,"context_line":"    def handle(self, record):"},{"line_number":70,"context_line":"        formatted \u003d self.format(record)"},{"line_number":71,"context_line":"        # check for unformatted messages"},{"line_number":72,"context_line":"        if re.search(\u0027.*[^%]%s.*\u0027, formatted):"},{"line_number":73,"context_line":"            raise TypeError(\u0027Log message is not properly formatted: %s\u0027 %"},{"line_number":74,"context_line":"                            formatted)"},{"line_number":75,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"da20952f_a31e585d","line":72,"updated":"2015-09-09 22:06:33.000000000","message":"I claim to not be a regex expert, but, I think this will match the kwargs as well as the plain %s\n\n.*[^%](%.*\\)s|%s).*","commit_id":"3fd10a877d720bdfa7b713d74d2104fbd0308d8d"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"321362feeb86f96da82e0eb4d129f2243220383a","unresolved":false,"context_lines":[{"line_number":69,"context_line":"    def handle(self, record):"},{"line_number":70,"context_line":"        formatted \u003d self.format(record)"},{"line_number":71,"context_line":"        # check for unformatted messages"},{"line_number":72,"context_line":"        if re.search(\u0027.*[^%]%s.*\u0027, formatted):"},{"line_number":73,"context_line":"            raise TypeError(\u0027Log message is not properly formatted: %s\u0027 %"},{"line_number":74,"context_line":"                            formatted)"},{"line_number":75,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"da20952f_18bc53da","line":72,"updated":"2015-09-09 21:49:22.000000000","message":"There is also the formatting type of {1}, {2}, etc we should detect","commit_id":"3fd10a877d720bdfa7b713d74d2104fbd0308d8d"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"92692618c8590fb25ad73bce57c22a2b62c1e226","unresolved":false,"context_lines":[{"line_number":69,"context_line":"    def handle(self, record):"},{"line_number":70,"context_line":"        formatted \u003d self.format(record)"},{"line_number":71,"context_line":"        # check for unformatted messages"},{"line_number":72,"context_line":"        if re.search(\u0027.*[^%]%s.*\u0027, formatted):"},{"line_number":73,"context_line":"            raise TypeError(\u0027Log message is not properly formatted: %s\u0027 %"},{"line_number":74,"context_line":"                            formatted)"},{"line_number":75,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"da20952f_d827bb61","line":72,"range":{"start_line":72,"start_character":29,"end_line":72,"end_character":30},"updated":"2015-09-09 21:45:49.000000000","message":"also, i, d, f, r at least I think. Just checking for %( would catch the kwargs I think.","commit_id":"3fd10a877d720bdfa7b713d74d2104fbd0308d8d"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"24174db5f6c827485009cf31fde6ff0c4b31432e","unresolved":false,"context_lines":[{"line_number":70,"context_line":"        formatted \u003d self.format(record)"},{"line_number":71,"context_line":"        # check for unformatted messages; this checks for unformatted"},{"line_number":72,"context_line":"        # %i, %d, %r, %s and kwargs, e.g. %(foo)s; %% is ignored"},{"line_number":73,"context_line":"        if (re.search(\u0027.*[^%]%([idrs]|\\(.*\\)s).*\u0027, formatted) or"},{"line_number":74,"context_line":"                # check for unformatted %f usage"},{"line_number":75,"context_line":"                re.search(\u0027.*[^%]%\\d?(.\\d+)f.*\u0027, formatted)):"},{"line_number":76,"context_line":"            raise TypeError(\u0027Log message is not properly formatted: %s\u0027 %"}],"source_content_type":"text/x-python","patch_set":3,"id":"da20952f_24da4e18","line":73,"updated":"2015-09-10 02:32:44.000000000","message":"This isn\u0027t detecting an unformatted message such as \u0027%s things\u0027\n\nI think you need a * after [^%]","commit_id":"ed4d90d41e3d0ed208a480a3994f3f304d0cdce4"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"d94459bcd5c46a763830fbfd90b664095d0af215","unresolved":false,"context_lines":[{"line_number":70,"context_line":"        formatted \u003d self.format(record)"},{"line_number":71,"context_line":"        # check for unformatted messages; this checks for unformatted"},{"line_number":72,"context_line":"        # %i, %d, %r, %s and kwargs, e.g. %(foo)s; %% is ignored"},{"line_number":73,"context_line":"        if (re.search(\u0027.*[^%]%([idrs]|\\(.*\\)s).*\u0027, formatted) or"},{"line_number":74,"context_line":"                # check for unformatted %f usage"},{"line_number":75,"context_line":"                re.search(\u0027.*[^%]%\\d?(.\\d+)f.*\u0027, formatted)):"},{"line_number":76,"context_line":"            raise TypeError(\u0027Log message is not properly formatted: %s\u0027 %"}],"source_content_type":"text/x-python","patch_set":3,"id":"da20952f_7166c5bc","line":73,"in_reply_to":"da20952f_24da4e18","updated":"2015-09-10 03:34:41.000000000","message":"I\u0027ll add a test for it.","commit_id":"ed4d90d41e3d0ed208a480a3994f3f304d0cdce4"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"24174db5f6c827485009cf31fde6ff0c4b31432e","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        # %i, %d, %r, %s and kwargs, e.g. %(foo)s; %% is ignored"},{"line_number":73,"context_line":"        if (re.search(\u0027.*[^%]%([idrs]|\\(.*\\)s).*\u0027, formatted) or"},{"line_number":74,"context_line":"                # check for unformatted %f usage"},{"line_number":75,"context_line":"                re.search(\u0027.*[^%]%\\d?(.\\d+)f.*\u0027, formatted)):"},{"line_number":76,"context_line":"            raise TypeError(\u0027Log message is not properly formatted: %s\u0027 %"},{"line_number":77,"context_line":"                            formatted)"},{"line_number":78,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"da20952f_84679a50","line":75,"updated":"2015-09-10 02:32:44.000000000","message":"Same","commit_id":"ed4d90d41e3d0ed208a480a3994f3f304d0cdce4"},{"author":{"_account_id":2750,"name":"Sean Dague","email":"sean@dague.net","username":"sdague"},"change_message_id":"a2a42278932f3b64ffd7efb65c3cf5166f74bf01","unresolved":false,"context_lines":[{"line_number":67,"context_line":"    debug level logs without saving the logs."},{"line_number":68,"context_line":"    \"\"\""},{"line_number":69,"context_line":"    def handle(self, record):"},{"line_number":70,"context_line":"        formatted \u003d self.format(record)"},{"line_number":71,"context_line":"        # check for unformatted messages; this checks for unformatted"},{"line_number":72,"context_line":"        # %i, %d, %r, %s and kwargs, e.g. %(foo)s; %% is ignored"},{"line_number":73,"context_line":"        if (re.search(\u0027.*[^%]%([idrs]|\\(.*\\)s).*\u0027, formatted) or"}],"source_content_type":"text/x-python","patch_set":4,"id":"da20952f_32e04296","line":70,"updated":"2015-09-10 10:52:39.000000000","message":"I feel like regex is never going to solve this for real.\n\nWhy not take the formatted thing then do the following:\n\nfind_kwargs \u003d formatted % {\u0027a\u0027: \u0027b\u0027}\nfind_strays \u003d formatted % ()\n\nfind_kwards will trigger a KeyError if there are kwargs still out there.\n\nIn [6]: a \u003d \"This is a string %(string)s\" % {\u0027a\u0027: \u0027b\u0027}\n---------------------------------------------------------------------------\nKeyError                                  Traceback (most recent call last)\n\u003cipython-input-6-9c49e10615e4\u003e in \u003cmodule\u003e()\n----\u003e 1 a \u003d \"This is a string %(string)s\" % {\u0027a\u0027: \u0027b\u0027}\n\nKeyError: \u0027string\u0027\n\nfind_strays will trigger a Type error if there are still strays in there.\n\nIn [10]: a \u003d \"This is a string %s\" % ()\n---------------------------------------------------------------------------\nTypeError                                 Traceback (most recent call last)\n\u003cipython-input-10-9785c840bdff\u003e in \u003cmodule\u003e()\n----\u003e 1 a \u003d \"This is a string %s\" % ()\n\nTypeError: not enough arguments for format string","commit_id":"c27acc6b590034453c2a68d694fbf103c30efea8"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"595506db8691984da375efb447f3d164213d716b","unresolved":false,"context_lines":[{"line_number":67,"context_line":"    debug level logs without saving the logs."},{"line_number":68,"context_line":"    \"\"\""},{"line_number":69,"context_line":"    def handle(self, record):"},{"line_number":70,"context_line":"        formatted \u003d self.format(record)"},{"line_number":71,"context_line":"        # check for unformatted messages; this checks for unformatted"},{"line_number":72,"context_line":"        # %i, %d, %r, %s and kwargs, e.g. %(foo)s; %% is ignored"},{"line_number":73,"context_line":"        if (re.search(\u0027.*[^%]%([idrs]|\\(.*\\)s).*\u0027, formatted) or"}],"source_content_type":"text/x-python","patch_set":4,"id":"da20952f_bfbded03","line":70,"in_reply_to":"da20952f_32e04296","updated":"2015-09-10 16:00:43.000000000","message":"I like this approach better, but I think that find_kwargs should be:\n\n   formatted % {}\n\nas there is a chance that the format key will be \u0027a\u0027 or whatever other key is used.","commit_id":"c27acc6b590034453c2a68d694fbf103c30efea8"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"57ad4413c85f564993c2941d329889c3f73da5de","unresolved":false,"context_lines":[{"line_number":67,"context_line":"    debug level logs without saving the logs."},{"line_number":68,"context_line":"    \"\"\""},{"line_number":69,"context_line":"    def handle(self, record):"},{"line_number":70,"context_line":"        formatted \u003d self.format(record)"},{"line_number":71,"context_line":"        # check for unformatted messages; this checks for unformatted"},{"line_number":72,"context_line":"        # %i, %d, %r, %s and kwargs, e.g. %(foo)s; %% is ignored"},{"line_number":73,"context_line":"        if (re.search(\u0027.*[^%]%([idrs]|\\(.*\\)s).*\u0027, formatted) or"}],"source_content_type":"text/x-python","patch_set":4,"id":"da20952f_b7767104","line":70,"in_reply_to":"da20952f_32e04296","updated":"2015-09-10 18:37:14.000000000","message":"Thanks, I\u0027ll play with this.  I had noticed this yesterday:\n\nhttps://docs.python.org/2/library/string.html#string.Formatter\n\nThe check_unused_args method, but that\u0027s left up to sub-classes of Formatter, so not something I was going to just use right away.","commit_id":"c27acc6b590034453c2a68d694fbf103c30efea8"}]}
