122 "__name__", |
120 "__name__", |
123 "__doc__", |
121 "__doc__", |
124 "credits", |
122 "credits", |
125 ] |
123 ] |
126 |
124 |
127 def __init__(self, source, filename, select, ignore, expected, repeat, |
125 def __init__(self, source, filename, tree, select, ignore, expected, |
128 args): |
126 repeat, args): |
129 """ |
127 """ |
130 Constructor |
128 Constructor |
131 |
129 |
132 @param source source code to be checked |
130 @param source source code to be checked |
133 @type list of str |
131 @type list of str |
134 @param filename name of the source file |
132 @param filename name of the source file |
135 @type str |
133 @type str |
|
134 @param tree AST tree of the source code |
|
135 @type ast.Module |
136 @param select list of selected codes |
136 @param select list of selected codes |
137 @type list of str |
137 @type list of str |
138 @param ignore list of codes to be ignored |
138 @param ignore list of codes to be ignored |
139 @type list of str |
139 @type list of str |
140 @param expected list of expected codes |
140 @param expected list of expected codes |
148 self.__ignore = ('',) if select else tuple(ignore) |
148 self.__ignore = ('',) if select else tuple(ignore) |
149 self.__expected = expected[:] |
149 self.__expected = expected[:] |
150 self.__repeat = repeat |
150 self.__repeat = repeat |
151 self.__filename = filename |
151 self.__filename = filename |
152 self.__source = source[:] |
152 self.__source = source[:] |
|
153 self.__tree = copy.deepcopy(tree) |
153 self.__args = args |
154 self.__args = args |
154 |
155 |
155 self.__pep3101FormatRegex = re.compile( |
156 self.__pep3101FormatRegex = re.compile( |
156 r'^(?:[^\'"]*[\'"][^\'"]*[\'"])*\s*%|^\s*%') |
157 r'^(?:[^\'"]*[\'"][^\'"]*[\'"])*\s*%|^\s*%') |
157 |
158 |
265 "code": code, |
266 "code": code, |
266 "args": args, |
267 "args": args, |
267 } |
268 } |
268 ) |
269 ) |
269 |
270 |
270 def __reportInvalidSyntax(self): |
|
271 """ |
|
272 Private method to report a syntax error. |
|
273 """ |
|
274 exc_type, exc = sys.exc_info()[:2] |
|
275 if len(exc.args) > 1: |
|
276 offset = exc.args[1] |
|
277 if len(offset) > 2: |
|
278 offset = offset[1:3] |
|
279 else: |
|
280 offset = (1, 0) |
|
281 self.__error(offset[0] - 1, offset[1] or 0, |
|
282 'M901', exc_type.__name__, exc.args[0]) |
|
283 |
|
284 def __generateTree(self): |
|
285 """ |
|
286 Private method to generate an AST for our source. |
|
287 |
|
288 @return generated AST |
|
289 @rtype ast.AST |
|
290 """ |
|
291 return ast.parse("".join(self.__source), self.__filename) |
|
292 |
|
293 def run(self): |
271 def run(self): |
294 """ |
272 """ |
295 Public method to check the given source against miscellaneous |
273 Public method to check the given source against miscellaneous |
296 conditions. |
274 conditions. |
297 """ |
275 """ |
299 # don't do anything, if essential data is missing |
277 # don't do anything, if essential data is missing |
300 return |
278 return |
301 |
279 |
302 if not self.__checkers: |
280 if not self.__checkers: |
303 # don't do anything, if no codes were selected |
281 # don't do anything, if no codes were selected |
304 return |
|
305 |
|
306 try: |
|
307 self.__tree = self.__generateTree() |
|
308 except (SyntaxError, TypeError): |
|
309 self.__reportInvalidSyntax() |
|
310 return |
282 return |
311 |
283 |
312 for check in self.__checkers: |
284 for check in self.__checkers: |
313 check() |
285 check() |
314 |
286 |
941 """ |
913 """ |
942 Private method to check use of naive datetime functions. |
914 Private method to check use of naive datetime functions. |
943 """ |
915 """ |
944 # step 1: generate an augmented node tree containing parent info |
916 # step 1: generate an augmented node tree containing parent info |
945 # for each child node |
917 # for each child node |
946 tree = self.__generateTree() |
918 tree = copy.deepcopy(self.__tree) |
947 for node in ast.walk(tree): |
919 for node in ast.walk(tree): |
948 for childNode in ast.iter_child_nodes(node): |
920 for childNode in ast.iter_child_nodes(node): |
949 childNode._dtCheckerParent = node |
921 childNode._dtCheckerParent = node |
950 |
922 |
951 # step 2: perform checks and report issues |
923 # step 2: perform checks and report issues |