Tue, 10 Dec 2024 15:46:34 +0100
Updated copyright for 2025.
10362 | 1 | # -*- coding: utf-8 -*- |
2 | ||
11090
f5f5f5803935
Updated copyright for 2025.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10754
diff
changeset
|
3 | # Copyright (c) 2023 - 2025 Detlev Offenbach <detlev@die-offenbachs.de> |
10362 | 4 | # |
5 | ||
6 | """ | |
7 | Module implementing a checker for logging related issues. | |
8 | """ | |
9 | ||
10 | import copy | |
11 | ||
12 | ||
13 | class LoggingChecker: | |
14 | """ | |
15 | Class implementing a checker for logging related issues. | |
16 | """ | |
17 | ||
18 | Codes = [ | |
10367
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
19 | ## Logging |
10362 | 20 | "L101", |
21 | "L102", | |
22 | "L103", | |
23 | "L104", | |
10367
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
24 | "L105", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
25 | "L106", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
26 | "L107", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
27 | "L108", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
28 | "L109", |
10362 | 29 | "L110", |
10367
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
30 | "L111", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
31 | "L112", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
32 | "L113", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
33 | "L114", |
10754
6faecb62f3a4
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10439
diff
changeset
|
34 | "L115", |
10362 | 35 | ] |
36 | ||
37 | def __init__(self, source, filename, tree, select, ignore, expected, repeat, args): | |
38 | """ | |
39 | Constructor | |
40 | ||
41 | @param source source code to be checked | |
42 | @type list of str | |
43 | @param filename name of the source file | |
44 | @type str | |
45 | @param tree AST tree of the source code | |
46 | @type ast.Module | |
47 | @param select list of selected codes | |
48 | @type list of str | |
49 | @param ignore list of codes to be ignored | |
50 | @type list of str | |
51 | @param expected list of expected codes | |
52 | @type list of str | |
53 | @param repeat flag indicating to report each occurrence of a code | |
54 | @type bool | |
55 | @param args dictionary of arguments for the various checks | |
56 | @type dict | |
57 | """ | |
10367
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
58 | self.__select = tuple(select) # noqa: M188 |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
59 | self.__ignore = ("",) if select else tuple(ignore) # noqa: M188 |
10362 | 60 | self.__expected = expected[:] |
61 | self.__repeat = repeat | |
62 | self.__filename = filename | |
63 | self.__source = source[:] | |
64 | self.__tree = copy.deepcopy(tree) | |
65 | self.__args = args | |
66 | ||
67 | # statistics counters | |
68 | self.counters = {} | |
69 | ||
70 | # collection of detected errors | |
71 | self.errors = [] | |
72 | ||
73 | checkersWithCodes = [ | |
10367
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
74 | ( |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
75 | self.__checkLogging, |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
76 | ( |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
77 | "L101", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
78 | "L102", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
79 | "L103", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
80 | "L104", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
81 | "L105", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
82 | "L106", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
83 | "L107", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
84 | "L108", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
85 | "L109", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
86 | "L110", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
87 | "L111", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
88 | "L112", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
89 | "L113", |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
90 | "L114", |
10754
6faecb62f3a4
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10439
diff
changeset
|
91 | "L115", |
10367
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
92 | ), |
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
93 | ), |
10362 | 94 | ] |
95 | ||
96 | self.__checkers = [] | |
97 | for checker, codes in checkersWithCodes: | |
98 | if any(not (code and self.__ignoreCode(code)) for code in codes): | |
99 | self.__checkers.append(checker) | |
100 | ||
101 | def __ignoreCode(self, code): | |
102 | """ | |
103 | Private method to check if the message code should be ignored. | |
104 | ||
105 | @param code message code to check for | |
106 | @type str | |
107 | @return flag indicating to ignore the given code | |
108 | @rtype bool | |
109 | """ | |
110 | return code.startswith(self.__ignore) and not code.startswith(self.__select) | |
111 | ||
112 | def __error(self, lineNumber, offset, code, *args): | |
113 | """ | |
114 | Private method to record an issue. | |
115 | ||
116 | @param lineNumber line number of the issue | |
117 | @type int | |
118 | @param offset position within line of the issue | |
119 | @type int | |
120 | @param code message code | |
121 | @type str | |
122 | @param args arguments for the message | |
123 | @type list | |
124 | """ | |
125 | if self.__ignoreCode(code): | |
126 | return | |
127 | ||
128 | if code in self.counters: | |
129 | self.counters[code] += 1 | |
130 | else: | |
131 | self.counters[code] = 1 | |
132 | ||
133 | # Don't care about expected codes | |
134 | if code in self.__expected: | |
135 | return | |
136 | ||
137 | if code and (self.counters[code] == 1 or self.__repeat): | |
138 | # record the issue with one based line number | |
139 | self.errors.append( | |
140 | { | |
141 | "file": self.__filename, | |
142 | "line": lineNumber + 1, | |
143 | "offset": offset, | |
144 | "code": code, | |
145 | "args": args, | |
146 | } | |
147 | ) | |
148 | ||
149 | def run(self): | |
150 | """ | |
151 | Public method to check the given source against miscellaneous | |
152 | conditions. | |
153 | """ | |
154 | if not self.__filename: | |
155 | # don't do anything, if essential data is missing | |
156 | return | |
157 | ||
158 | if not self.__checkers: | |
159 | # don't do anything, if no codes were selected | |
160 | return | |
161 | ||
162 | for check in self.__checkers: | |
163 | check() | |
164 | ||
10367
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
165 | def __checkLogging(self): |
10362 | 166 | """ |
167 | Private method to check logging statements. | |
168 | """ | |
10367
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
169 | from .LoggingVisitor import LoggingVisitor |
10362 | 170 | |
10367
b189ca1f5d53
Code Style Checker
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10363
diff
changeset
|
171 | visitor = LoggingVisitor(errorCallback=self.__error) |
10362 | 172 | visitor.visit(self.__tree) |