)]}'
{"tools/hacking.py":[{"author":{"_account_id":642,"name":"Matt Dietz","email":"matthew.dietz@gmail.com","username":"cerberus"},"change_message_id":"6e3a7ef775a5bd09350c9f7b60074a46a15dcd11","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    N301"},{"line_number":71,"context_line":"    \"\"\""},{"line_number":72,"context_line":"    pos \u003d logical_line.find(\u0027,\u0027)"},{"line_number":73,"context_line":"    if pos \u003e -1  and (logical_line.startswith(\"import\") or"},{"line_number":74,"context_line":"       (logical_line.startswith(\"from\") and\\"},{"line_number":75,"context_line":"       logical_line.split()[2] \u003d\u003d \"import\")):"},{"line_number":76,"context_line":"        return pos, \"NOVA N301: one import per line\""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F8EQ%3D","line":73,"updated":"2012-01-20 17:49:42.000000000","message":"Extra space between \"-1\" and \"and\"","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"62c43f3c6936417e64b55a0cb299b8ea5cb18d8e","unresolved":false,"context_lines":[{"line_number":71,"context_line":"    \"\"\""},{"line_number":72,"context_line":"    pos \u003d logical_line.find(\u0027,\u0027)"},{"line_number":73,"context_line":"    if pos \u003e -1  and (logical_line.startswith(\"import\") or"},{"line_number":74,"context_line":"       (logical_line.startswith(\"from\") and\\"},{"line_number":75,"context_line":"       logical_line.split()[2] \u003d\u003d \"import\")):"},{"line_number":76,"context_line":"        return pos, \"NOVA N301: one import per line\""},{"line_number":77,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F8G0%3D","line":74,"updated":"2012-01-20 16:33:17.000000000","message":"No need for \\ here","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"62c43f3c6936417e64b55a0cb299b8ea5cb18d8e","unresolved":false,"context_lines":[{"line_number":85,"context_line":"    try:"},{"line_number":86,"context_line":"        split_line \u003d logical_line.split()"},{"line_number":87,"context_line":"        # handle \"import x\""},{"line_number":88,"context_line":"        if logical_line.startswith(\"import\") and len(logical_line) \u003d\u003d 2 and \\"},{"line_number":89,"context_line":"                \",\" not in logical_line:"},{"line_number":90,"context_line":"            mod \u003d split_line[1]"},{"line_number":91,"context_line":"            exec logical_line"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F8Gw%3D","line":88,"updated":"2012-01-20 16:33:17.000000000","message":"I\u0027d prefer if you surrounded this in parentheses so that you don\u0027t need to use backslash continuation.  Also, I don\u0027t understand the \"len(logical_line) \u003d\u003d 2\"; that can\u0027t ever be true.","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"62c43f3c6936417e64b55a0cb299b8ea5cb18d8e","unresolved":false,"context_lines":[{"line_number":88,"context_line":"        if logical_line.startswith(\"import\") and len(logical_line) \u003d\u003d 2 and \\"},{"line_number":89,"context_line":"                \",\" not in logical_line:"},{"line_number":90,"context_line":"            mod \u003d split_line[1]"},{"line_number":91,"context_line":"            exec logical_line"},{"line_number":92,"context_line":"            if not inspect.ismodule(eval(mod)):"},{"line_number":93,"context_line":"                return 1, \"NOVA N302: import only modules\""},{"line_number":94,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F8GU%3D","line":91,"updated":"2012-01-20 16:33:17.000000000","message":"There\u0027s better ways of handling this than using exec.  I\u0027d advocate using __import__() to import the name, then look up the name in sys.modules.  The same goes for the remaining exec\u0027s in this function...","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":642,"name":"Matt Dietz","email":"matthew.dietz@gmail.com","username":"cerberus"},"change_message_id":"6e3a7ef775a5bd09350c9f7b60074a46a15dcd11","unresolved":false,"context_lines":[{"line_number":88,"context_line":"        if logical_line.startswith(\"import\") and len(logical_line) \u003d\u003d 2 and \\"},{"line_number":89,"context_line":"                \",\" not in logical_line:"},{"line_number":90,"context_line":"            mod \u003d split_line[1]"},{"line_number":91,"context_line":"            exec logical_line"},{"line_number":92,"context_line":"            if not inspect.ismodule(eval(mod)):"},{"line_number":93,"context_line":"                return 1, \"NOVA N302: import only modules\""},{"line_number":94,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F8EM%3D","line":91,"in_reply_to":"AAAAD3%2F%2F8GU%3D","updated":"2012-01-20 17:49:42.000000000","message":"In fact, that\u0027s basically how the utils.import_module and import_class stuff works...","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"62c43f3c6936417e64b55a0cb299b8ea5cb18d8e","unresolved":false,"context_lines":[{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        # handle \"import x as y\""},{"line_number":96,"context_line":"        elif logical_line.startswith(\"import\") and \\"},{"line_number":97,"context_line":"                len(split_line) \u003d\u003d 4 and split_line[2] \u003d\u003d \"as\" \\"},{"line_number":98,"context_line":"                \",\" not in logical_line:"},{"line_number":99,"context_line":"            print logical_line"},{"line_number":100,"context_line":"            mod \u003d split_line[3]"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F8Gs%3D","line":97,"updated":"2012-01-20 16:33:17.000000000","message":"Again, parentheses instead of backslash.  Also, the boolean logic doesn\u0027t make sense, and I suspect you\u0027ll get a syntax error from this.","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"62c43f3c6936417e64b55a0cb299b8ea5cb18d8e","unresolved":false,"context_lines":[{"line_number":105,"context_line":"        # handle \"from x import y\""},{"line_number":106,"context_line":"        elif logical_line.startswith(\"from\") and \\"},{"line_number":107,"context_line":"               split_line[2] \u003d\u003d \"import\" and \\"},{"line_number":108,"context_line":"               len(split_line) \u003c 5 and \\"},{"line_number":109,"context_line":"               \",\" not in logical_line:"},{"line_number":110,"context_line":"            exec logical_line"},{"line_number":111,"context_line":"            mod \u003d split_line[3]"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F8Gk%3D","line":108,"updated":"2012-01-20 16:33:17.000000000","message":"Again, parentheses.","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"62c43f3c6936417e64b55a0cb299b8ea5cb18d8e","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        # handle \"from x import y as z\""},{"line_number":117,"context_line":"        elif logical_line.startswith(\"from\") and \\"},{"line_number":118,"context_line":"                split_line[2] \u003d\u003d \"import\" and \\"},{"line_number":119,"context_line":"                len(split_line) \u003e 4 and split_line[4] \u003d\u003d \"as\" and \\"},{"line_number":120,"context_line":"                \",\" not in logical_line:"},{"line_number":121,"context_line":"            exec logical_line"},{"line_number":122,"context_line":"            mod \u003d split_line[5]"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F8Gg%3D","line":119,"updated":"2012-01-20 16:33:17.000000000","message":"Again, parentheses.","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":642,"name":"Matt Dietz","email":"matthew.dietz@gmail.com","username":"cerberus"},"change_message_id":"6e3a7ef775a5bd09350c9f7b60074a46a15dcd11","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                \",\" not in logical_line:"},{"line_number":121,"context_line":"            exec logical_line"},{"line_number":122,"context_line":"            mod \u003d split_line[5]"},{"line_number":123,"context_line":"            if not inspect.ismodule(eval(mod)):"},{"line_number":124,"context_line":"                return 1, \"NOVA N302: import only modules. \" \\"},{"line_number":125,"context_line":"                \"%s is not a module\" % mod"},{"line_number":126,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F8D8%3D","line":123,"updated":"2012-01-20 17:49:42.000000000","message":"I hate seeing eval in any code. Can you look into refactoring this based on the __import__ stuff?","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"62c43f3c6936417e64b55a0cb299b8ea5cb18d8e","unresolved":false,"context_lines":[{"line_number":122,"context_line":"            mod \u003d split_line[5]"},{"line_number":123,"context_line":"            if not inspect.ismodule(eval(mod)):"},{"line_number":124,"context_line":"                return 1, \"NOVA N302: import only modules. \" \\"},{"line_number":125,"context_line":"                \"%s is not a module\" % mod"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        # TODO(jogo) handle \"from x import *\""},{"line_number":128,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F8GQ%3D","line":125,"updated":"2012-01-20 16:33:17.000000000","message":"And again, parentheses.","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"62c43f3c6936417e64b55a0cb299b8ea5cb18d8e","unresolved":false,"context_lines":[{"line_number":124,"context_line":"                return 1, \"NOVA N302: import only modules. \" \\"},{"line_number":125,"context_line":"                \"%s is not a module\" % mod"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        # TODO(jogo) handle \"from x import *\""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    except Exception:"},{"line_number":130,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F8GM%3D","line":127,"updated":"2012-01-20 16:33:17.000000000","message":"I thought we prohibited all forms of \"import *\"?","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"cfff5eda95031e45b366610737e65728e49e8a36","unresolved":false,"context_lines":[{"line_number":124,"context_line":"                return 1, \"NOVA N302: import only modules. \" \\"},{"line_number":125,"context_line":"                \"%s is not a module\" % mod"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        # TODO(jogo) handle \"from x import *\""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    except Exception:"},{"line_number":130,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F74s%3D","line":127,"in_reply_to":"AAAAD3%2F%2F75Y%3D","updated":"2012-01-20 23:33:00.000000000","message":"Maybe not, but \"import *\" typically means, \"import all classes, functions, and other variables from this module,\" and as such is probably prohibited by implication :)","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":1849,"name":"Joe Gordon","email":"joe.gordon0@gmail.com","username":"jogo"},"change_message_id":"00359a51c30979e593d7c98946be315ff478d76f","unresolved":false,"context_lines":[{"line_number":124,"context_line":"                return 1, \"NOVA N302: import only modules. \" \\"},{"line_number":125,"context_line":"                \"%s is not a module\" % mod"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        # TODO(jogo) handle \"from x import *\""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    except Exception:"},{"line_number":130,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F75Y%3D","line":127,"in_reply_to":"AAAAD3%2F%2F8GM%3D","updated":"2012-01-20 23:04:13.000000000","message":"while I like the idea of prohibiting all forms of \"import *\", I didn\u0027t see that anywhere in HACKING/","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"62c43f3c6936417e64b55a0cb299b8ea5cb18d8e","unresolved":false,"context_lines":[{"line_number":127,"context_line":"        # TODO(jogo) handle \"from x import *\""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    except Exception:"},{"line_number":130,"context_line":"        pass"},{"line_number":131,"context_line":"        #print \u003e\u003e sys.stderr, \"exec \u0027%s\u0027 failed, missing module\" % logical_line"},{"line_number":132,"context_line":"        #traceback.print_exc(file\u003dsys.stderr)"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F8GI%3D","line":130,"updated":"2012-01-20 16:33:17.000000000","message":"This explains why you didn\u0027t see the syntax error I pointed out above :)","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"cfff5eda95031e45b366610737e65728e49e8a36","unresolved":false,"context_lines":[{"line_number":127,"context_line":"        # TODO(jogo) handle \"from x import *\""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    except Exception:"},{"line_number":130,"context_line":"        pass"},{"line_number":131,"context_line":"        #print \u003e\u003e sys.stderr, \"exec \u0027%s\u0027 failed, missing module\" % logical_line"},{"line_number":132,"context_line":"        #traceback.print_exc(file\u003dsys.stderr)"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F74o%3D","line":130,"in_reply_to":"AAAAD3%2F%2F75U%3D","updated":"2012-01-20 23:33:00.000000000","message":"Well, I\u0027d prefer to see the exception handling around smaller sections of code.  You could create an auxiliary function that you pass an import name and an optional symbol name, then use __import__() and sys.modules to perform your tests there.  The exception handling would likely only need to be around the small section of code in that helper function, and you gain the benefit of DRY-compliance.","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":1849,"name":"Joe Gordon","email":"joe.gordon0@gmail.com","username":"jogo"},"change_message_id":"00359a51c30979e593d7c98946be315ff478d76f","unresolved":false,"context_lines":[{"line_number":127,"context_line":"        # TODO(jogo) handle \"from x import *\""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    except Exception:"},{"line_number":130,"context_line":"        pass"},{"line_number":131,"context_line":"        #print \u003e\u003e sys.stderr, \"exec \u0027%s\u0027 failed, missing module\" % logical_line"},{"line_number":132,"context_line":"        #traceback.print_exc(file\u003dsys.stderr)"},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAD3%2F%2F75U%3D","line":130,"in_reply_to":"AAAAD3%2F%2F8GI%3D","updated":"2012-01-20 23:04:13.000000000","message":"I wasn\u0027t sure if I should remove the \u0027pass\u0027 and  enable these two lines or not.   Keven \u0026 Matt, what do you think?","commit_id":"ca3ecf93b4292b2e04d82395660d3cf4568546e2"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"94111dac6c05772840cc899b9da3b3fb03a313df","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    N201"},{"line_number":57,"context_line":"    \"\"\""},{"line_number":58,"context_line":"    if logical_line.startswith(\"except:\"):"},{"line_number":59,"context_line":"        return pos, \"NOVA N201: no \u0027except:\u0027 at least use except \u0027Exception:\u0027\""},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def nova_one_import_per_line(logical_line):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAEH%2F%2F%2F00%3D","line":59,"updated":"2012-01-23 17:09:59.000000000","message":"Where does \"pos\" come from?","commit_id":"9fb066aa623b0bee4843ee9115657309d3718733"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"94111dac6c05772840cc899b9da3b3fb03a313df","unresolved":false,"context_lines":[{"line_number":88,"context_line":"        if (logical_line.startswith(\"import\") and len(split_line) \u003d\u003d 2 and"},{"line_number":89,"context_line":"                \",\" not in logical_line):"},{"line_number":90,"context_line":"            mod \u003d split_line[1]"},{"line_number":91,"context_line":"            exec logical_line"},{"line_number":92,"context_line":"            if not inspect.ismodule(eval(mod)):"},{"line_number":93,"context_line":"                return 1, \"NOVA N302: import only modules\""},{"line_number":94,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAEH%2F%2F%2F0c%3D","line":91,"updated":"2012-01-23 17:09:59.000000000","message":"I still would prefer to see \"exec\" avoided in favor of direct use of __import__()","commit_id":"9fb066aa623b0bee4843ee9115657309d3718733"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"94111dac6c05772840cc899b9da3b3fb03a313df","unresolved":false,"context_lines":[{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        # handle \"import x as y\""},{"line_number":96,"context_line":"        elif (logical_line.startswith(\"import\") and"},{"line_number":97,"context_line":"                len(split_line) \u003d\u003d 4 and split_line[2] \u003d\u003d \"as\""},{"line_number":98,"context_line":"                \",\" not in logical_line):"},{"line_number":99,"context_line":"            print logical_line"},{"line_number":100,"context_line":"            mod \u003d split_line[3]"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAEH%2F%2F%2F0s%3D","line":97,"updated":"2012-01-23 17:09:59.000000000","message":"You still have a logic error here.  This would read to the interpreter as:\n\n    elif (logical_line.startswith(\"import\") and len(split_line) \u003d\u003d 4 and split_line[2] \u003d\u003d \"as,\" not in logical_line):\n\nI believe you mean to have another \"and\" between \"as\" and \",\".","commit_id":"9fb066aa623b0bee4843ee9115657309d3718733"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"94111dac6c05772840cc899b9da3b3fb03a313df","unresolved":false,"context_lines":[{"line_number":110,"context_line":"            exec logical_line"},{"line_number":111,"context_line":"            mod \u003d split_line[3]"},{"line_number":112,"context_line":"            if not inspect.ismodule(eval(mod)):"},{"line_number":113,"context_line":"                return 1, \"NOVA N302: import only modules. \" \\"},{"line_number":114,"context_line":"                \"%s is not a module\" % mod"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"        # handle \"from x import y as z\""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAEH%2F%2F%2F0o%3D","line":113,"updated":"2012-01-23 17:09:59.000000000","message":"Please avoid backslash continuation; you can surround the string with parentheses.","commit_id":"9fb066aa623b0bee4843ee9115657309d3718733"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"94111dac6c05772840cc899b9da3b3fb03a313df","unresolved":false,"context_lines":[{"line_number":121,"context_line":"            exec logical_line"},{"line_number":122,"context_line":"            mod \u003d split_line[5]"},{"line_number":123,"context_line":"            if not inspect.ismodule(eval(mod)):"},{"line_number":124,"context_line":"                return 1, \"NOVA N302: import only modules. \" \\"},{"line_number":125,"context_line":"                \"%s is not a module\" % mod"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        # TODO(jogo) handle \"from x import *\""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAEH%2F%2F%2F0k%3D","line":124,"updated":"2012-01-23 17:09:59.000000000","message":"Ibid.","commit_id":"9fb066aa623b0bee4843ee9115657309d3718733"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"e916a268d577b5d20d1b0ad0951caef178b8331c","unresolved":false,"context_lines":[{"line_number":20,"context_line":"built on top of pep8.py"},{"line_number":21,"context_line":"\"\"\""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"import fnmatch"},{"line_number":24,"context_line":"import os"},{"line_number":25,"context_line":"import sys"},{"line_number":26,"context_line":"import re"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAEH%2F%2F%2FgY%3D","line":23,"updated":"2012-01-23 23:19:47.000000000","message":"Do you use fnmatch anywhere?","commit_id":"753761dea774148bff97f6da05c1a54d999caee7"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"e916a268d577b5d20d1b0ad0951caef178b8331c","unresolved":false,"context_lines":[{"line_number":26,"context_line":"import re"},{"line_number":27,"context_line":"import traceback"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"import inspect"},{"line_number":30,"context_line":"import pep8"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"#N1xx comments"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAEH%2F%2F%2FgU%3D","line":29,"updated":"2012-01-23 23:19:47.000000000","message":"\"inspect\" is a standard module and should be in the previous set of imports…","commit_id":"753761dea774148bff97f6da05c1a54d999caee7"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"e916a268d577b5d20d1b0ad0951caef178b8331c","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    N201"},{"line_number":58,"context_line":"    \"\"\""},{"line_number":59,"context_line":"    if logical_line.startswith(\"except: \"):"},{"line_number":60,"context_line":"        return 6, \"NOVA N201: no \u0027except:\u0027 at least use except \u0027Exception:\u0027\""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"def nova_one_import_per_line(logical_line):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAEH%2F%2F%2Fg8%3D","line":60,"updated":"2012-01-23 23:19:47.000000000","message":"Quoting suggestion:  Put the quotes around \"except Exception\", not just \"Exception\"…","commit_id":"753761dea774148bff97f6da05c1a54d999caee7"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"e916a268d577b5d20d1b0ad0951caef178b8331c","unresolved":false,"context_lines":[{"line_number":72,"context_line":"    \"\"\""},{"line_number":73,"context_line":"    pos \u003d logical_line.find(\u0027,\u0027)"},{"line_number":74,"context_line":"    if (pos \u003e -1 and (logical_line.startswith(\"import \") or"},{"line_number":75,"context_line":"       (logical_line.startswith(\"from\") and"},{"line_number":76,"context_line":"       logical_line.split()[2] \u003d\u003d \"import\"))):"},{"line_number":77,"context_line":"        return pos, \"NOVA N301: one import per line\""},{"line_number":78,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAEH%2F%2F%2Fgw%3D","line":75,"updated":"2012-01-23 23:19:47.000000000","message":"You probably want to add the same whitespace here, i.e., \"from \" instead of \"from\".","commit_id":"753761dea774148bff97f6da05c1a54d999caee7"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"e916a268d577b5d20d1b0ad0951caef178b8331c","unresolved":false,"context_lines":[{"line_number":95,"context_line":"            valid \u003d True"},{"line_number":96,"context_line":"            if parent:"},{"line_number":97,"context_line":"                __import__(parent, globals(), locals(), [mod], -1)"},{"line_number":98,"context_line":"                valid \u003d inspect.ismodule(eval(\"sys.modules[parent].%s\" % mod))"},{"line_number":99,"context_line":"            else:"},{"line_number":100,"context_line":"                __import__(mod, globals(), locals(), [], -1)"},{"line_number":101,"context_line":"                valid \u003d inspect.ismodule(sys.modules[mod])"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAEH%2F%2F%2Fgo%3D","line":98,"updated":"2012-01-23 23:19:47.000000000","message":"I still don\u0027t want to see eval used, and it\u0027s not really necessary:\n\n    parent_mod \u003d sys.modules[parent]\n    valid \u003d inspect.ismodule(getattr(parent_mod, mod, None))","commit_id":"753761dea774148bff97f6da05c1a54d999caee7"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"e916a268d577b5d20d1b0ad0951caef178b8331c","unresolved":false,"context_lines":[{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    split_line \u003d logical_line.split()"},{"line_number":130,"context_line":"    # handle \"import x\""},{"line_number":131,"context_line":"    if (logical_line.startswith(\"import\") and len(split_line) \u003d\u003d 2 and"},{"line_number":132,"context_line":"            \",\" not in logical_line):"},{"line_number":133,"context_line":"        mod \u003d split_line[1]"},{"line_number":134,"context_line":"        return importModuleCheck(mod)"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAEH%2F%2F%2Fgg%3D","line":131,"updated":"2012-01-23 23:19:47.000000000","message":"Since you\u0027ve already split the logical line, and since you want to ensure you only apply this to lines doing imports and not lines starting with, say, \"import_ok\", I\u0027d suggest changing the \"startswith()\" clause to a direct test: \"split_line[0] \u003d\u003d \u0027import\u0027\"","commit_id":"753761dea774148bff97f6da05c1a54d999caee7"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"c8ecc305c60069361e3f04470d5ca2e6302f2c2c","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        try:"},{"line_number":94,"context_line":"            valid \u003d True"},{"line_number":95,"context_line":"            if parent:"},{"line_number":96,"context_line":"                parent_mod \u003d __import__(parent, globals(), locals(), [mod], -1)"},{"line_number":97,"context_line":"                valid \u003d inspect.ismodule(getattr(parent_mod, mod))"},{"line_number":98,"context_line":"            else:"},{"line_number":99,"context_line":"                __import__(mod, globals(), locals(), [], -1)"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAEH%2F%2F%2Fdc%3D","line":96,"updated":"2012-01-24 00:06:02.000000000","message":"One unfortunate subtlety about __import__(): if you __import__(\u0027foo.bar\"), you get back the module descriptor for \u0027foo\u0027, not \u0027foo.bar\u0027.  You need to use sys.modules to get parent_mod here.","commit_id":"a9aa71caf404e31e3e1cb0bbe89d514e053a1754"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"39327966a8c0987479e8361c1427cc4646ec9d5b","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        try:"},{"line_number":94,"context_line":"            valid \u003d True"},{"line_number":95,"context_line":"            if parent:"},{"line_number":96,"context_line":"                parent_mod \u003d __import__(parent, globals(), locals(), [mod], -1)"},{"line_number":97,"context_line":"                valid \u003d inspect.ismodule(getattr(parent_mod, mod))"},{"line_number":98,"context_line":"            else:"},{"line_number":99,"context_line":"                __import__(mod, globals(), locals(), [], -1)"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAEH%2F%2F%2FZM%3D","line":96,"in_reply_to":"AAAAEH%2F%2F%2FZs%3D","updated":"2012-01-24 00:51:53.000000000","message":"Interesting.  That could be due to the other arguments you\u0027re using; I generally only use the one-argument form (which is likely all you need, too, actually).  I get:\n\n    \u003e\u003e\u003e a \u003d __import__(\u0027xml.dom\u0027)\n    \u003e\u003e\u003e a\n    \u003cmodule \u0027_xmlplus\u0027 from \u0027/usr/lib64/python2.7/site-packages/_xmlplus/__init__.pyc\u0027\u003e\n    \u003e\u003e\u003e import sys\n    \u003e\u003e\u003e sys.modules[\u0027xml\u0027]\n    \u003cmodule \u0027_xmlplus\u0027 from \u0027/usr/lib64/python2.7/site-packages/_xmlplus/__init__.pyc\u0027\u003e\n\n(This is Python 2.7.)","commit_id":"a9aa71caf404e31e3e1cb0bbe89d514e053a1754"},{"author":{"_account_id":1849,"name":"Joe Gordon","email":"joe.gordon0@gmail.com","username":"jogo"},"change_message_id":"ea41c6e83adc1c3332a8f204b530d78df221930e","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        try:"},{"line_number":94,"context_line":"            valid \u003d True"},{"line_number":95,"context_line":"            if parent:"},{"line_number":96,"context_line":"                parent_mod \u003d __import__(parent, globals(), locals(), [mod], -1)"},{"line_number":97,"context_line":"                valid \u003d inspect.ismodule(getattr(parent_mod, mod))"},{"line_number":98,"context_line":"            else:"},{"line_number":99,"context_line":"                __import__(mod, globals(), locals(), [], -1)"}],"source_content_type":"text/x-python","patch_set":4,"id":"AAAAEH%2F%2F%2FZs%3D","line":96,"in_reply_to":"AAAAEH%2F%2F%2Fdc%3D","updated":"2012-01-24 00:43:13.000000000","message":"In python 2.7.1 when I try __import__, I get:  \n\n\n\u003e\u003e\u003e pm \u003d __import__(\u0027nova.compute.api\u0027,globals(), locals(), [\u0027API\u0027],-1)\n\u003e\u003e\u003e pm\n\u003cmodule \u0027nova.compute.api\u0027 from \u0027nova/compute/api.pyc\u0027\u003e","commit_id":"a9aa71caf404e31e3e1cb0bbe89d514e053a1754"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"f38d63e546b7e94d876ff206a2bb2123550e9da9","unresolved":false,"context_lines":[{"line_number":55,"context_line":"    Do not write \"except:\", use \"except Exception:\" at the very least"},{"line_number":56,"context_line":"    N201"},{"line_number":57,"context_line":"    \"\"\""},{"line_number":58,"context_line":"    if logical_line.startswith(\"except: \"):"},{"line_number":59,"context_line":"        return 6, \"NOVA N201: no \u0027except:\u0027 at least use \u0027except Exception:\u0027\""},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAEH%2F%2F%2FAw%3D","line":58,"updated":"2012-01-24 16:02:22.000000000","message":"You know, there\u0027s likely never going to be a space after \"except:\"…","commit_id":"c7522c7ac5903090d6aada054e8eb61f954c59bf"},{"author":{"_account_id":679,"name":"Kevin L. Mitchell","email":"klmitch@mit.edu","username":"klmitch"},"change_message_id":"f38d63e546b7e94d876ff206a2bb2123550e9da9","unresolved":false,"context_lines":[{"line_number":132,"context_line":"    if (logical_line.startswith(\"import \") and \",\" not in logical_line and"},{"line_number":133,"context_line":"            (len(split_line) \u003d\u003d 2 or"},{"line_number":134,"context_line":"            (len(split_line) \u003d\u003d 4 and split_line[2] \u003d\u003d \"as\"))):"},{"line_number":135,"context_line":"            mod \u003d split_line[1]"},{"line_number":136,"context_line":"            return importModuleCheck(mod)"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    # handle \"from x import y\""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAEH%2F%2F%2FAs%3D","line":135,"updated":"2012-01-24 16:02:22.000000000","message":"Could you update the indentation here?","commit_id":"c7522c7ac5903090d6aada054e8eb61f954c59bf"}]}
