Removed support for Python < 3.9 in the LoggingVisitor class.
10367
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
1
|
# -*- coding: utf-8 -*- |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
2
|
|
11090
|
3
|
# Copyright (c) 2023 - 2025 Detlev Offenbach <detlev@die-offenbachs.de> |
10367
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
4
|
# |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
5
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
6
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
7
|
Module implementing a node visitor to check for logging issues. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
8
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
9
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
10
|
####################################################################### |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
11
|
## LoggingVisitor |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
12
|
## |
11132
|
13
|
## adapted from: flake8-logging v1.7.0 |
10367
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
14
|
## |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
15
|
## Original: Copyright (c) 2023 Adam Johnson |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
16
|
####################################################################### |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
17
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
18
|
import ast |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
19
|
import re |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
20
|
import sys |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
21
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
22
|
from functools import lru_cache |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
23
|
from typing import cast |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
24
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
25
|
_LoggerMethods = frozenset( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
26
|
( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
27
|
"debug", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
28
|
"info", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
29
|
"warn", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
30
|
"warning", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
31
|
"error", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
32
|
"critical", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
33
|
"log", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
34
|
"exception", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
35
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
36
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
37
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
38
|
_LogrecordAttributes = frozenset( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
39
|
( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
40
|
"asctime", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
41
|
"args", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
42
|
"created", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
43
|
"exc_info", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
44
|
"exc_text", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
45
|
"filename", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
46
|
"funcName", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
47
|
"levelname", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
48
|
"levelno", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
49
|
"lineno", |
10640
|
50
|
"message", |
10367
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
51
|
"module", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
52
|
"msecs", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
53
|
"msg", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
54
|
"name", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
55
|
"pathname", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
56
|
"process", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
57
|
"processName", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
58
|
"relativeCreated", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
59
|
"stack_info", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
60
|
"taskName", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
61
|
"thread", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
62
|
"threadName", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
63
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
64
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
65
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
66
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
67
|
@lru_cache(maxsize=None) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
68
|
def _modposPlaceholderRe(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
69
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
70
|
Function to generate a regular expression object for '%' formatting codes. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
71
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
72
|
@return regular expression object |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
73
|
@rtype re.Pattern |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
74
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
75
|
# https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
76
|
return re.compile( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
77
|
r""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
78
|
% # noqa: M601 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
79
|
(?P<spec> |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
80
|
% | # raw % character # noqa: M601 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
81
|
(?: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
82
|
([-#0 +]+)? # conversion flags |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
83
|
(?P<minwidth>\d+|\*)? # minimum field width |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
84
|
(?P<precision>\.\d+|\.\*)? # precision |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
85
|
[hlL]? # length modifier |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
86
|
[acdeEfFgGiorsuxX] # conversion type |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
87
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
88
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
89
|
""", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
90
|
re.VERBOSE, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
91
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
92
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
93
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
94
|
@lru_cache(maxsize=None) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
95
|
def _modnamedPlaceholderRe(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
96
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
97
|
Function to generate a regular expression object for '%' formatting codes using |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
98
|
names. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
99
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
100
|
@return regular expression object |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
101
|
@rtype re.Pattern |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
102
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
103
|
# https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
104
|
return re.compile( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
105
|
r""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
106
|
% # noqa: M601 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
107
|
\( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
108
|
(?P<name>.*?) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
109
|
\) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
110
|
([-#0 +]+)? # conversion flags |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
111
|
(\d+)? # minimum field width |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
112
|
(\.\d+)? # precision |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
113
|
[hlL]? # length modifier |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
114
|
[acdeEfFgGiorsuxX] # conversion type |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
115
|
""", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
116
|
re.VERBOSE, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
117
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
118
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
119
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
120
|
class LoggingVisitor(ast.NodeVisitor): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
121
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
122
|
Class implementing a node visitor to check for logging issues. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
123
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
124
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
125
|
GetLoggerNames = frozenset(("__cached__", "__file__")) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
126
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
127
|
def __init__(self, errorCallback): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
128
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
129
|
Constructor |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
130
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
131
|
@param errorCallback callback function to register an error |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
132
|
@type func |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
133
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
134
|
super().__init__() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
135
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
136
|
self.__error = errorCallback |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
137
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
138
|
self.__loggingName = None |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
139
|
self.__loggerName = None |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
140
|
self.__fromImports = {} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
141
|
self.__stack = [] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
142
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
143
|
def visit(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
144
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
145
|
Public method to handle ast nodes. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
146
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
147
|
@param node reference to the node to be processed |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
148
|
@type ast.AST |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
149
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
150
|
self.__stack.append(node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
151
|
super().visit(node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
152
|
self.__stack.pop() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
153
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
154
|
def visit_Import(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
155
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
156
|
Public method to handle Import nodes. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
157
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
158
|
@param node reference to the node to be processed |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
159
|
@type ast.Import |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
160
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
161
|
for alias in node.names: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
162
|
if alias.name == "logging": |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
163
|
self.__loggingName = alias.asname or alias.name |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
164
|
self.generic_visit(node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
165
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
166
|
def visit_ImportFrom(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
167
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
168
|
Public method to handle ImportFrom nodes. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
169
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
170
|
@param node reference to the node to be processed |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
171
|
@type ast.ImportFrom |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
172
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
173
|
if node.module == "logging": |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
174
|
for alias in node.names: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
175
|
if alias.name == "WARN": |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
176
|
if sys.version_info >= (3, 10): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
177
|
lineno = alias.lineno |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
178
|
colOffset = alias.col_offset |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
179
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
180
|
lineno = node.lineno |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
181
|
colOffset = node.col_offset |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
182
|
self.__error(lineno - 1, colOffset, "L109") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
183
|
if not alias.asname: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
184
|
self.__fromImports[alias.name] = node.module |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
185
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
186
|
self.generic_visit(node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
187
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
188
|
def visit_Attribute(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
189
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
190
|
Public method to handle Attribute nodes. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
191
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
192
|
@param node reference to the node to be processed |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
193
|
@type ast.Attribute |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
194
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
195
|
if ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
196
|
self.__loggingName |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
197
|
and isinstance(node.value, ast.Name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
198
|
and node.value.id == self.__loggingName |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
199
|
and node.attr == "WARN" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
200
|
): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
201
|
self.__error(node.lineno - 1, node.col_offset, "L109") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
202
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
203
|
self.generic_visit(node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
204
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
205
|
def visit_Call(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
206
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
207
|
Public method to handle Call nodes. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
208
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
209
|
@param node reference to the node to be processed |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
210
|
@type ast.Call |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
211
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
212
|
if ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
213
|
( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
214
|
self.__loggingName |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
215
|
and isinstance(node.func, ast.Attribute) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
216
|
and node.func.attr == "Logger" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
217
|
and isinstance(node.func.value, ast.Name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
218
|
and node.func.value.id == self.__loggingName |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
219
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
220
|
or ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
221
|
isinstance(node.func, ast.Name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
222
|
and node.func.id == "Logger" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
223
|
and self.__fromImports.get("Logger") == "logging" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
224
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
225
|
) and not self.__atModuleLevel(): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
226
|
self.__error(node.lineno - 1, node.col_offset, "L101") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
227
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
228
|
if ( |
10754
|
229
|
isinstance(node.func, ast.Attribute) |
|
230
|
and node.func.attr in _LoggerMethods |
|
231
|
and isinstance(node.func.value, ast.Name) |
|
232
|
and self.__loggingName |
|
233
|
and node.func.value.id == self.__loggingName |
|
234
|
) or ( |
|
235
|
isinstance(node.func, ast.Name) |
|
236
|
and node.func.id in _LoggerMethods |
|
237
|
and self.__fromImports.get(node.func.id) == "logging" |
|
238
|
): |
|
239
|
self.__error(node.lineno - 1, node.col_offset, "L115") |
|
240
|
|
|
241
|
if ( |
10367
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
242
|
self.__loggingName |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
243
|
and isinstance(node.func, ast.Attribute) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
244
|
and node.func.attr == "getLogger" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
245
|
and isinstance(node.func.value, ast.Name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
246
|
and node.func.value.id == self.__loggingName |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
247
|
) or ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
248
|
isinstance(node.func, ast.Name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
249
|
and node.func.id == "getLogger" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
250
|
and self.__fromImports.get("getLogger") == "logging" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
251
|
): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
252
|
if ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
253
|
len(self.__stack) >= 2 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
254
|
and isinstance(assign := self.__stack[-2], ast.Assign) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
255
|
and len(assign.targets) == 1 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
256
|
and isinstance(assign.targets[0], ast.Name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
257
|
and not self.__atModuleLevel() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
258
|
): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
259
|
self.__loggerName = assign.targets[0].id |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
260
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
261
|
if ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
262
|
node.args |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
263
|
and isinstance(node.args[0], ast.Name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
264
|
and node.args[0].id in self.GetLoggerNames |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
265
|
): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
266
|
self.__error(node.args[0].lineno - 1, node.args[0].col_offset, "L102") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
267
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
268
|
if ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
269
|
isinstance(node.func, ast.Attribute) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
270
|
and node.func.attr in _LoggerMethods |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
271
|
and isinstance(node.func.value, ast.Name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
272
|
) and ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
273
|
(self.__loggingName and node.func.value.id == self.__loggingName) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
274
|
or (self.__loggerName and node.func.value.id == self.__loggerName) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
275
|
): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
276
|
excHandler = self.__currentExceptHandler() |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
277
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
278
|
# L108 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
279
|
if node.func.attr == "warn": |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
280
|
self.__error(node.lineno - 1, node.col_offset, "L108") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
281
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
282
|
# L103 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
283
|
extraKeys = [] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
284
|
if any((extraNode := kw).arg == "extra" for kw in node.keywords): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
285
|
if isinstance(extraNode.value, ast.Dict): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
286
|
extraKeys = [ |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
287
|
(k.value, k) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
288
|
for k in extraNode.value.keys |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
289
|
if isinstance(k, ast.Constant) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
290
|
] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
291
|
elif ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
292
|
isinstance(extraNode.value, ast.Call) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
293
|
and isinstance(extraNode.value.func, ast.Name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
294
|
and extraNode.value.func.id == "dict" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
295
|
): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
296
|
extraKeys = [ |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
297
|
(k.arg, k) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
298
|
for k in extraNode.value.keywords |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
299
|
if k.arg is not None |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
300
|
] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
301
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
302
|
for key, keyNode in extraKeys: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
303
|
if key in _LogrecordAttributes: |
11133
d650c9527b87
Removed support for Python < 3.9 in the LoggingVisitor class.
Detlev Offenbach <detlev@die-offenbachs.de>
diff
changeset
|
304
|
self.__error( |
d650c9527b87
Removed support for Python < 3.9 in the LoggingVisitor class.
Detlev Offenbach <detlev@die-offenbachs.de>
diff
changeset
|
305
|
keyNode.lineno - 1, keyNode.col_offset, "L103", repr(key) |
d650c9527b87
Removed support for Python < 3.9 in the LoggingVisitor class.
Detlev Offenbach <detlev@die-offenbachs.de>
diff
changeset
|
306
|
) |
10367
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
307
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
308
|
if node.func.attr == "exception": |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
309
|
# L104 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
310
|
if not excHandler: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
311
|
self.__error(node.lineno - 1, node.col_offset, "L104") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
312
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
313
|
if any((excInfo := kw).arg == "exc_info" for kw in node.keywords): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
314
|
# L106 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
315
|
if ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
316
|
isinstance(excInfo.value, ast.Constant) and excInfo.value.value |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
317
|
) or ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
318
|
excHandler |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
319
|
and isinstance(excInfo.value, ast.Name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
320
|
and excInfo.value.id == excHandler.name |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
321
|
): |
11133
d650c9527b87
Removed support for Python < 3.9 in the LoggingVisitor class.
Detlev Offenbach <detlev@die-offenbachs.de>
diff
changeset
|
322
|
self.__error(excInfo.lineno - 1, excInfo.col_offset, "L106") |
10367
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
323
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
324
|
# L107 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
325
|
elif ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
326
|
isinstance(excInfo.value, ast.Constant) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
327
|
and not excInfo.value.value |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
328
|
): |
11133
d650c9527b87
Removed support for Python < 3.9 in the LoggingVisitor class.
Detlev Offenbach <detlev@die-offenbachs.de>
diff
changeset
|
329
|
self.__error(excInfo.lineno - 1, excInfo.col_offset, "L107") |
10367
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
330
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
331
|
# L105 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
332
|
elif node.func.attr == "error" and excHandler is not None: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
333
|
rewritable = False |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
334
|
if any((excInfo := kw).arg == "exc_info" for kw in node.keywords): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
335
|
if isinstance(excInfo.value, ast.Constant) and excInfo.value.value: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
336
|
rewritable = True |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
337
|
elif ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
338
|
isinstance(excInfo.value, ast.Name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
339
|
and excInfo.value.id == excHandler.name |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
340
|
): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
341
|
rewritable = True |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
342
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
343
|
rewritable = True |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
344
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
345
|
if rewritable: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
346
|
self.__error(node.lineno - 1, node.col_offset, "L105") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
347
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
348
|
# L114 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
349
|
elif ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
350
|
excHandler is None |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
351
|
and any((excInfo := kw).arg == "exc_info" for kw in node.keywords) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
352
|
and isinstance(excInfo.value, ast.Constant) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
353
|
and excInfo.value.value |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
354
|
): |
11133
d650c9527b87
Removed support for Python < 3.9 in the LoggingVisitor class.
Detlev Offenbach <detlev@die-offenbachs.de>
diff
changeset
|
355
|
self.__error(excInfo.lineno - 1, excInfo.col_offset, "L114") |
10367
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
356
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
357
|
# L110 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
358
|
if ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
359
|
node.func.attr == "exception" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
360
|
and len(node.args) >= 1 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
361
|
and isinstance(node.args[0], ast.Name) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
362
|
and excHandler is not None |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
363
|
and node.args[0].id == excHandler.name |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
364
|
): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
365
|
self.__error(node.args[0].lineno - 1, node.args[0].col_offset, "L110") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
366
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
367
|
msgArgKwarg = False |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
368
|
if node.func.attr == "log" and len(node.args) >= 2: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
369
|
msgArg = node.args[1] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
370
|
elif node.func.attr != "log" and len(node.args) >= 1: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
371
|
msgArg = node.args[0] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
372
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
373
|
try: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
374
|
msgArg = [k for k in node.keywords if k.arg == "msg"][0].value |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
375
|
msgArgKwarg = True |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
376
|
except IndexError: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
377
|
msgArg = None |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
378
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
379
|
# L111 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
380
|
if isinstance(msgArg, ast.JoinedStr): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
381
|
self.__error(msgArg.lineno - 1, msgArg.col_offset, "L111a") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
382
|
elif ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
383
|
isinstance(msgArg, ast.Call) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
384
|
and isinstance(msgArg.func, ast.Attribute) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
385
|
and isinstance(msgArg.func.value, ast.Constant) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
386
|
and isinstance(msgArg.func.value.value, str) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
387
|
and msgArg.func.attr == "format" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
388
|
): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
389
|
self.__error(msgArg.lineno - 1, msgArg.col_offset, "L111b") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
390
|
elif ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
391
|
isinstance(msgArg, ast.BinOp) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
392
|
and isinstance(msgArg.op, ast.Mod) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
393
|
and isinstance(msgArg.left, ast.Constant) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
394
|
and isinstance(msgArg.left.value, str) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
395
|
): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
396
|
self.__error(msgArg.lineno - 1, msgArg.col_offset, "L111c") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
397
|
elif isinstance(msgArg, ast.BinOp) and self.__isAddChainWithNonStr(msgArg): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
398
|
self.__error(msgArg.lineno - 1, msgArg.col_offset, "L111d") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
399
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
400
|
# L112 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
401
|
if ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
402
|
msgArg is not None |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
403
|
and not msgArgKwarg |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
404
|
and (msg := self.__flattenStrChain(msgArg)) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
405
|
and not any(isinstance(arg, ast.Starred) for arg in node.args) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
406
|
): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
407
|
self.__checkMsgAndArgs(node, msgArg, msg) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
408
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
409
|
self.generic_visit(node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
410
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
411
|
def __checkMsgAndArgs(self, node, msgArg, msg): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
412
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
413
|
Private method to check the message and arguments a given Call node. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
414
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
415
|
@param node reference to the Call node |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
416
|
@type ast.Call |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
417
|
@param msgArg message argument nodes |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
418
|
@type ast.AST |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
419
|
@param msg message |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
420
|
@type str |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
421
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
422
|
if not isinstance(node.func, ast.Attribute): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
423
|
return |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
424
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
425
|
if ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
426
|
( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
427
|
(node.func.attr != "log" and (dictIdx := 1)) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
428
|
or (node.func.attr == "log" and (dictIdx := 2)) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
429
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
430
|
and len(node.args) == dictIdx + 1 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
431
|
and (dictNode := node.args[dictIdx]) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
432
|
and isinstance(dictNode, ast.Dict) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
433
|
and all( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
434
|
isinstance(k, ast.Constant) and isinstance(k.value, str) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
435
|
for k in dictNode.keys |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
436
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
437
|
and ( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
438
|
modnames := {m["name"] for m in _modnamedPlaceholderRe().finditer(msg)} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
439
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
440
|
): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
441
|
# L113 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
442
|
given = {cast(ast.Constant, k).value for k in dictNode.keys} |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
443
|
if missing := modnames - given: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
444
|
self.__error( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
445
|
msgArg.lineno - 1, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
446
|
msgArg.col_offset, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
447
|
"L113a", # missing keys |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
448
|
", ".join([repr(k) for k in missing]), |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
449
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
450
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
451
|
if missing := given - modnames: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
452
|
self.__error( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
453
|
msgArg.lineno - 1, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
454
|
msgArg.col_offset, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
455
|
"L113b", # unreferenced keys |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
456
|
", ".join([repr(k) for k in missing]), |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
457
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
458
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
459
|
return |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
460
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
461
|
# L112 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
462
|
modposCount = sum( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
463
|
1 + (m["minwidth"] == "*") + (m["precision"] == ".*") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
464
|
for m in _modposPlaceholderRe().finditer(msg) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
465
|
if m["spec"] != "%" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
466
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
467
|
argCount = len(node.args) - 1 - (node.func.attr == "log") |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
468
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
469
|
if modposCount > 0 and modposCount != argCount: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
470
|
self.__error( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
471
|
msgArg.lineno - 1, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
472
|
msgArg.col_offset, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
473
|
"L112", |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
474
|
modposCount, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
475
|
"'%'", # noqa: M601 |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
476
|
argCount, |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
477
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
478
|
return |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
479
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
480
|
def __atModuleLevel(self): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
481
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
482
|
Private method to check, if we are on the module level. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
483
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
484
|
@return flag indicating the module level |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
485
|
@rtype bool |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
486
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
487
|
return any( |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
488
|
isinstance(parent, (ast.FunctionDef, ast.AsyncFunctionDef)) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
489
|
for parent in self.__stack |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
490
|
) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
491
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
492
|
def __currentExceptHandler(self): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
493
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
494
|
Private method to determine the current exception handler node. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
495
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
496
|
@return reference to the current exception handler node or None |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
497
|
@rtype ast.ExceptHandler |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
498
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
499
|
for node in reversed(self.__stack): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
500
|
if isinstance(node, ast.ExceptHandler): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
501
|
return node |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
502
|
elif isinstance(node, (ast.AsyncFunctionDef, ast.FunctionDef)): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
503
|
break |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
504
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
505
|
return None |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
506
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
507
|
def __isAddChainWithNonStr(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
508
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
509
|
Private method to check, if the node is an Add with a non string argument. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
510
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
511
|
@param node reference to the binary operator node |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
512
|
@type ast.BinOp |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
513
|
@return flag indicating an Add with a non string argument |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
514
|
@rtype bool |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
515
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
516
|
if not isinstance(node.op, ast.Add): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
517
|
return False |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
518
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
519
|
for side in (node.left, node.right): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
520
|
if isinstance(side, ast.BinOp): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
521
|
if self.__isAddChainWithNonStr(side): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
522
|
return True |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
523
|
elif not (isinstance(side, ast.Constant) and isinstance(side.value, str)): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
524
|
return True |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
525
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
526
|
return False |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
527
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
528
|
def __flattenStrChain(self, node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
529
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
530
|
Private method to flatten the given string chain. |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
531
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
532
|
@param node reference to the AST node |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
533
|
@type ast.AST |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
534
|
@return flattened string |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
535
|
@rtype str |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
536
|
""" |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
537
|
parts = [] |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
538
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
539
|
def visit(node): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
540
|
if isinstance(node, ast.Constant) and isinstance(node.value, str): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
541
|
parts.append(node.value) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
542
|
return True |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
543
|
elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.Add): |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
544
|
return visit(node.left) and visit(node.right) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
545
|
return False |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
546
|
|
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
547
|
result = visit(node) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
548
|
if result: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
549
|
return "".join(parts) |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
550
|
else: |
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
551
|
return None |