Sat, 10 Apr 2021 15:11:43 +0200
Code Style Checker
- don't treat 'if __name__ == "__main__":' as an issue
- added a check for if-blocks which only check if a key is in a dictionary
- added a check for bare boolean function arguments
- added a check for bare numeric function arguments
8186 | 1 | # -*- coding: utf-8 -*- |
2 | ||
3 | # Copyright (c) 2021 Detlev Offenbach <detlev@die-offenbachs.de> | |
4 | # | |
5 | ||
6 | """ | |
7 | Module implementing the checker for simplifying Python code. | |
8 | """ | |
9 | ||
10 | import ast | |
8198
1c765dc90c21
Code Style Checker: changed code such, that the AST tree is built only once and passed to each checker module.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8195
diff
changeset
|
11 | import copy |
8186 | 12 | |
8189
17df5c8df8c1
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8186
diff
changeset
|
13 | from .SimplifyNodeVisitor import SimplifyNodeVisitor |
8186 | 14 | |
15 | ||
8207
d359172d11be
Applied some more code simplifications suggested by the new Simplify checker.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8202
diff
changeset
|
16 | class SimplifyChecker: |
8186 | 17 | """ |
18 | Class implementing a checker for to help simplifying Python code. | |
19 | """ | |
20 | Codes = [ | |
8189
17df5c8df8c1
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8186
diff
changeset
|
21 | # Python-specifics |
17df5c8df8c1
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8186
diff
changeset
|
22 | "Y101", "Y102", "Y103", "Y104", "Y105", "Y106", "Y107", "Y108", |
8191
9125da0c227e
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8189
diff
changeset
|
23 | "Y109", "Y110", "Y111", "Y112", "Y113", "Y114", "Y115", "Y116", |
8211
8322a6f219ff
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8210
diff
changeset
|
24 | "Y117", "Y118", "Y119", "Y120", "Y121", "Y122", |
8209
14470a65a52e
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8207
diff
changeset
|
25 | |
14470a65a52e
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8207
diff
changeset
|
26 | # Python-specifics not part of flake8-simplify |
14470a65a52e
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8207
diff
changeset
|
27 | "Y181", "Y182", |
8189
17df5c8df8c1
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8186
diff
changeset
|
28 | |
17df5c8df8c1
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8186
diff
changeset
|
29 | # Comparations |
8195
db7f2badd374
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8194
diff
changeset
|
30 | "Y201", "Y202", "Y203", "Y204", "Y205", "Y206", "Y207", "Y208", |
db7f2badd374
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8194
diff
changeset
|
31 | "Y211", "Y212", "Y213", |
db7f2badd374
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8194
diff
changeset
|
32 | "Y221", "Y222", "Y223", "Y224", |
db7f2badd374
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8194
diff
changeset
|
33 | |
db7f2badd374
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8194
diff
changeset
|
34 | # Opinionated |
db7f2badd374
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8194
diff
changeset
|
35 | "Y301", |
8211
8322a6f219ff
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8210
diff
changeset
|
36 | |
8322a6f219ff
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8210
diff
changeset
|
37 | # General Code Style |
8322a6f219ff
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8210
diff
changeset
|
38 | "Y401", "Y402", |
8186 | 39 | ] |
40 | ||
8198
1c765dc90c21
Code Style Checker: changed code such, that the AST tree is built only once and passed to each checker module.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8195
diff
changeset
|
41 | def __init__(self, source, filename, tree, selected, ignored, expected, |
1c765dc90c21
Code Style Checker: changed code such, that the AST tree is built only once and passed to each checker module.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8195
diff
changeset
|
42 | repeat): |
8186 | 43 | """ |
44 | Constructor | |
45 | ||
46 | @param source source code to be checked | |
47 | @type list of str | |
48 | @param filename name of the source file | |
49 | @type str | |
8198
1c765dc90c21
Code Style Checker: changed code such, that the AST tree is built only once and passed to each checker module.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8195
diff
changeset
|
50 | @param tree AST tree of the source code |
1c765dc90c21
Code Style Checker: changed code such, that the AST tree is built only once and passed to each checker module.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8195
diff
changeset
|
51 | @type ast.Module |
8186 | 52 | @param selected list of selected codes |
53 | @type list of str | |
54 | @param ignored list of codes to be ignored | |
55 | @type list of str | |
56 | @param expected list of expected codes | |
57 | @type list of str | |
58 | @param repeat flag indicating to report each occurrence of a code | |
59 | @type bool | |
60 | """ | |
61 | self.__select = tuple(selected) | |
62 | self.__ignore = ('',) if selected else tuple(ignored) | |
63 | self.__expected = expected[:] | |
64 | self.__repeat = repeat | |
65 | self.__filename = filename | |
66 | self.__source = source[:] | |
8198
1c765dc90c21
Code Style Checker: changed code such, that the AST tree is built only once and passed to each checker module.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8195
diff
changeset
|
67 | self.__tree = copy.deepcopy(tree) |
8186 | 68 | |
69 | # statistics counters | |
70 | self.counters = {} | |
71 | ||
72 | # collection of detected errors | |
73 | self.errors = [] | |
74 | ||
75 | self.__checkCodes = (code for code in self.Codes | |
76 | if not self.__ignoreCode(code)) | |
77 | ||
78 | def __ignoreCode(self, code): | |
79 | """ | |
80 | Private method to check if the message code should be ignored. | |
81 | ||
82 | @param code message code to check for | |
83 | @type str | |
84 | @return flag indicating to ignore the given code | |
85 | @rtype bool | |
86 | """ | |
87 | return (code.startswith(self.__ignore) and | |
88 | not code.startswith(self.__select)) | |
89 | ||
90 | def __error(self, lineNumber, offset, code, *args): | |
91 | """ | |
92 | Private method to record an issue. | |
93 | ||
94 | @param lineNumber line number of the issue | |
95 | @type int | |
96 | @param offset position within line of the issue | |
97 | @type int | |
98 | @param code message code | |
99 | @type str | |
100 | @param args arguments for the message | |
101 | @type list | |
102 | """ | |
103 | if self.__ignoreCode(code): | |
104 | return | |
105 | ||
106 | if code in self.counters: | |
107 | self.counters[code] += 1 | |
108 | else: | |
109 | self.counters[code] = 1 | |
110 | ||
111 | # Don't care about expected codes | |
112 | if code in self.__expected: | |
113 | return | |
114 | ||
115 | if code and (self.counters[code] == 1 or self.__repeat): | |
116 | # record the issue with one based line number | |
117 | self.errors.append( | |
118 | { | |
119 | "file": self.__filename, | |
120 | "line": lineNumber + 1, | |
121 | "offset": offset, | |
122 | "code": code, | |
123 | "args": args, | |
124 | } | |
125 | ) | |
126 | ||
127 | def run(self): | |
128 | """ | |
129 | Public method to check the given source against functions | |
130 | to be replaced by 'pathlib' equivalents. | |
131 | """ | |
132 | if not self.__filename: | |
133 | # don't do anything, if essential data is missing | |
134 | return | |
135 | ||
136 | if not self.__checkCodes: | |
137 | # don't do anything, if no codes were selected | |
138 | return | |
139 | ||
8191
9125da0c227e
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8189
diff
changeset
|
140 | # Add parent information |
9125da0c227e
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8189
diff
changeset
|
141 | for node in ast.walk(self.__tree): |
9125da0c227e
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8189
diff
changeset
|
142 | for child in ast.iter_child_nodes(node): |
9125da0c227e
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8189
diff
changeset
|
143 | child.parent = node # type: ignore |
9125da0c227e
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8189
diff
changeset
|
144 | |
8189
17df5c8df8c1
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8186
diff
changeset
|
145 | visitor = SimplifyNodeVisitor(self.__error) |
8186 | 146 | visitor.visit(self.__tree) |