18 Class implementing a checker for code complexity. |
18 Class implementing a checker for code complexity. |
19 """ |
19 """ |
20 Codes = [ |
20 Codes = [ |
21 "C101", |
21 "C101", |
22 "C111", "C112", |
22 "C111", "C112", |
23 |
|
24 "C901", |
|
25 ] |
23 ] |
26 |
24 |
27 def __init__(self, source, filename, select, ignore, args): |
25 def __init__(self, source, filename, tree, select, ignore, args): |
28 """ |
26 """ |
29 Constructor |
27 Constructor |
30 |
28 |
31 @param source source code to be checked |
29 @param source source code to be checked |
32 @type list of str |
30 @type list of str |
33 @param filename name of the source file |
31 @param filename name of the source file |
34 @type str |
32 @type str |
|
33 @param tree AST tree of the source code |
|
34 @type ast.Module |
35 @param select list of selected codes |
35 @param select list of selected codes |
36 @type list of str |
36 @type list of str |
37 @param ignore list of codes to be ignored |
37 @param ignore list of codes to be ignored |
38 @type list of str |
38 @type list of str |
39 @param args dictionary of arguments for the miscellaneous checks |
39 @param args dictionary of arguments for the miscellaneous checks |
40 @type dict |
40 @type dict |
41 """ |
41 """ |
42 self.__filename = filename |
42 self.__filename = filename |
43 self.__source = source[:] |
43 self.__source = source[:] |
|
44 self.__tree = copy.deepcopy(tree) |
44 self.__select = tuple(select) |
45 self.__select = tuple(select) |
45 self.__ignore = ('',) if select else tuple(ignore) |
46 self.__ignore = ('',) if select else tuple(ignore) |
46 self.__args = args |
47 self.__args = args |
47 |
48 |
48 self.__defaultArgs = { |
49 self.__defaultArgs = { |
111 "code": code, |
112 "code": code, |
112 "args": args, |
113 "args": args, |
113 } |
114 } |
114 ) |
115 ) |
115 |
116 |
116 def __reportInvalidSyntax(self): |
|
117 """ |
|
118 Private method to report a syntax error. |
|
119 """ |
|
120 exc_type, exc = sys.exc_info()[:2] |
|
121 if len(exc.args) > 1: |
|
122 offset = exc.args[1] |
|
123 if len(offset) > 2: |
|
124 offset = offset[1:3] |
|
125 else: |
|
126 offset = (1, 0) |
|
127 self.__error(offset[0] - 1, offset[1] or 0, |
|
128 'C901', exc_type.__name__, exc.args[0]) |
|
129 |
|
130 def run(self): |
117 def run(self): |
131 """ |
118 """ |
132 Public method to check the given source for code complexity. |
119 Public method to check the given source for code complexity. |
133 """ |
120 """ |
134 if not self.__filename or not self.__source: |
121 if not self.__filename or not self.__source: |
135 # don't do anything, if essential data is missing |
122 # don't do anything, if essential data is missing |
136 return |
123 return |
137 |
124 |
138 if not self.__checkers: |
125 if not self.__checkers: |
139 # don't do anything, if no codes were selected |
126 # don't do anything, if no codes were selected |
140 return |
|
141 |
|
142 try: |
|
143 self.__tree = ast.parse("".join(self.__source), self.__filename) |
|
144 except (SyntaxError, TypeError): |
|
145 self.__reportInvalidSyntax() |
|
146 return |
127 return |
147 |
128 |
148 for check in self.__checkers: |
129 for check in self.__checkers: |
149 check() |
130 check() |
150 |
131 |