Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheck.py

branch
BgService
changeset 3412
9364dab2d472
parent 3228
f489068e51e8
child 3456
96232974dcdb
equal deleted inserted replaced
3241:957673fc463a 3412:9364dab2d472
69 flags = [f.strip() for f in comment.split() 69 flags = [f.strip() for f in comment.split()
70 if (f.startswith("__") and f.endswith("__"))] 70 if (f.startswith("__") and f.endswith("__"))]
71 return flags 71 return flags
72 72
73 73
74 def syntaxAndPyflakesCheck(filename, codestring="", checkFlakes=True, 74 def syntaxAndPyflakesCheck(filename, codestring, checkFlakes=True,
75 ignoreStarImportWarnings=False): 75 ignoreStarImportWarnings=False):
76 """ 76 """
77 Function to compile one Python source file to Python bytecode 77 Function to compile one Python source file to Python bytecode
78 and to perform a pyflakes check. 78 and to perform a pyflakes check.
79 79
80 @param filename source filename (string) 80 @param filename source filename (string)
81 @keyparam codestring string containing the code to compile (string) 81 @param codestring string containing the code to compile (string)
82 @keyparam checkFlakes flag indicating to do a pyflakes check (boolean) 82 @keyparam checkFlakes flag indicating to do a pyflakes check (boolean)
83 @keyparam ignoreStarImportWarnings flag indicating to 83 @keyparam ignoreStarImportWarnings flag indicating to
84 ignore 'star import' warnings (boolean) 84 ignore 'star import' warnings (boolean)
85 @return A tuple indicating status (True = an error was found), the 85 @return dictionary with the keys 'error' and 'warnings' which
86 file name, the line number, the index number, the code string 86 hold a list containing details about the error/ warnings
87 and the error message (boolean, string, string, string, string, 87 (file name, line number, column, codestring (only at syntax
88 string). If checkFlakes is True, a list of strings containing the 88 errors), the message, a list with arguments for the message)
89 warnings (marker, file name, line number, message)
90 The values are only valid, if the status is True.
91 """ 89 """
92 try: 90 try:
93 import builtins 91 import builtins
94 except ImportError: 92 except ImportError:
95 import __builtin__ as builtins #__IGNORE_WARNING__ 93 import __builtin__ as builtins #__IGNORE_WARNING__
98 if sys.version_info[0] == 2: 96 if sys.version_info[0] == 2:
99 file_enc = filename.encode(sys.getfilesystemencoding()) 97 file_enc = filename.encode(sys.getfilesystemencoding())
100 else: 98 else:
101 file_enc = filename 99 file_enc = filename
102 100
103 # It also encoded the code back to avoid 'Encoding declaration in 101 # It also encode the code back to avoid 'Encoding declaration in
104 # unicode string' exception on Python2 102 # unicode string' exception on Python2
105 codestring = normalizeCode(codestring) 103 codestring = normalizeCode(codestring)
106 104
107 if filename.endswith('.ptl'): 105 if filename.endswith('.ptl'):
108 try: 106 try:
109 import quixote.ptl_compile 107 import quixote.ptl_compile
110 except ImportError: 108 except ImportError:
111 return (True, filename, 0, 0, '', 109 return [{'error': (filename, 0, 0, '',
112 'Quixote plugin not found.', []) 110 'Quixote plugin not found.')}]
113 template = quixote.ptl_compile.Template(codestring, file_enc) 111 template = quixote.ptl_compile.Template(codestring, file_enc)
114 template.compile() 112 template.compile()
115 113 else:
116 # ast.PyCF_ONLY_AST = 1024, speed optimisation 114 # ast.PyCF_ONLY_AST = 1024, speed optimisation
117 module = builtins.compile(codestring, file_enc, 'exec', 1024) 115 module = builtins.compile(codestring, file_enc, 'exec', 1024)
118 except SyntaxError as detail: 116 except SyntaxError as detail:
119 index = 0 117 index = 0
120 code = "" 118 code = ""
121 error = "" 119 error = ""
122 lines = traceback.format_exception_only(SyntaxError, detail) 120 lines = traceback.format_exception_only(SyntaxError, detail)
137 index = len(seLine.rstrip()) - 4 135 index = len(seLine.rstrip()) - 4
138 else: 136 else:
139 fn = detail.filename 137 fn = detail.filename
140 line = detail.lineno or 1 138 line = detail.lineno or 1
141 error = detail.msg 139 error = detail.msg
142 return (True, fn, int(line), index, code, error, []) 140 return [{'error': (fn, int(line), index, code.strip(), error)}]
143 except ValueError as detail: 141 except ValueError as detail:
144 try: 142 try:
145 fn = detail.filename 143 fn = detail.filename
146 line = detail.lineno 144 line = detail.lineno
147 error = detail.msg 145 error = detail.msg
148 except AttributeError: 146 except AttributeError:
149 fn = filename 147 fn = filename
150 line = 1 148 line = 1
151 error = str(detail) 149 error = str(detail)
152 return (True, fn, line, 0, "", error, []) 150 return [{'error': (fn, line, 0, "", error)}]
153 except Exception as detail: 151 except Exception as detail:
154 try: 152 try:
155 fn = detail.filename 153 fn = detail.filename
156 line = detail.lineno 154 line = detail.lineno
157 error = detail.msg 155 error = detail.msg
158 return (True, fn, line, 0, "", error, []) 156 return [{'error': (fn, line, 0, "", error)}]
159 except: # this catchall is intentional 157 except: # this catchall is intentional
160 pass 158 pass
161 159
162 # pyflakes 160 # pyflakes
163 if not checkFlakes: 161 if not checkFlakes:
164 return (False, "", -1, -1, "", "", []) 162 return [{}]
165 163
166 strings = [] 164 results = []
167 lines = codestring.splitlines() 165 lines = codestring.splitlines()
168 try: 166 try:
169 warnings = Checker(module, filename) 167 warnings = Checker(module, filename)
170 warnings.messages.sort(key=lambda a: a.lineno) 168 warnings.messages.sort(key=lambda a: a.lineno)
171 for warning in warnings.messages: 169 for warning in warnings.messages:
174 continue 172 continue
175 173
176 _fn, lineno, col, message, msg_args = warning.getMessageData() 174 _fn, lineno, col, message, msg_args = warning.getMessageData()
177 if "__IGNORE_WARNING__" not in extractLineFlags( 175 if "__IGNORE_WARNING__" not in extractLineFlags(
178 lines[lineno - 1].strip()): 176 lines[lineno - 1].strip()):
179 strings.append([ 177 results.append((_fn, lineno, col, "", message, msg_args))
180 "FLAKES_WARNING", _fn, lineno, col, message, msg_args])
181 except SyntaxError as err: 178 except SyntaxError as err:
182 if err.text.strip(): 179 if err.text.strip():
183 msg = err.text.strip() 180 msg = err.text.strip()
184 else: 181 else:
185 msg = err.msg 182 msg = err.msg
186 strings.append(["FLAKES_ERROR", filename, err.lineno, 0, msg, ()]) 183 results.append((filename, err.lineno, 0, "FLAKES_ERROR", msg, []))
187 184
188 return (False, "", -1, -1, "", "", strings) 185 return [{'warnings': results}]

eric ide

mercurial