177 lineno = alias.lineno |
177 lineno = alias.lineno |
178 colOffset = alias.col_offset |
178 colOffset = alias.col_offset |
179 else: |
179 else: |
180 lineno = node.lineno |
180 lineno = node.lineno |
181 colOffset = node.col_offset |
181 colOffset = node.col_offset |
182 self.__error(lineno - 1, colOffset, "L109") |
182 self.__error(lineno - 1, colOffset, "L-109") |
183 if not alias.asname: |
183 if not alias.asname: |
184 self.__fromImports[alias.name] = node.module |
184 self.__fromImports[alias.name] = node.module |
185 |
185 |
186 self.generic_visit(node) |
186 self.generic_visit(node) |
187 |
187 |
196 self.__loggingName |
196 self.__loggingName |
197 and isinstance(node.value, ast.Name) |
197 and isinstance(node.value, ast.Name) |
198 and node.value.id == self.__loggingName |
198 and node.value.id == self.__loggingName |
199 and node.attr == "WARN" |
199 and node.attr == "WARN" |
200 ): |
200 ): |
201 self.__error(node.lineno - 1, node.col_offset, "L109") |
201 self.__error(node.lineno - 1, node.col_offset, "L-109") |
202 |
202 |
203 self.generic_visit(node) |
203 self.generic_visit(node) |
204 |
204 |
205 def visit_Call(self, node): |
205 def visit_Call(self, node): |
206 """ |
206 """ |
221 isinstance(node.func, ast.Name) |
221 isinstance(node.func, ast.Name) |
222 and node.func.id == "Logger" |
222 and node.func.id == "Logger" |
223 and self.__fromImports.get("Logger") == "logging" |
223 and self.__fromImports.get("Logger") == "logging" |
224 ) |
224 ) |
225 ) and not self.__atModuleLevel(): |
225 ) and not self.__atModuleLevel(): |
226 self.__error(node.lineno - 1, node.col_offset, "L101") |
226 self.__error(node.lineno - 1, node.col_offset, "L-101") |
227 |
227 |
228 if ( |
228 if ( |
229 isinstance(node.func, ast.Attribute) |
229 isinstance(node.func, ast.Attribute) |
230 and node.func.attr in _LoggerMethods |
230 and node.func.attr in _LoggerMethods |
231 and isinstance(node.func.value, ast.Name) |
231 and isinstance(node.func.value, ast.Name) |
234 ) or ( |
234 ) or ( |
235 isinstance(node.func, ast.Name) |
235 isinstance(node.func, ast.Name) |
236 and node.func.id in _LoggerMethods |
236 and node.func.id in _LoggerMethods |
237 and self.__fromImports.get(node.func.id) == "logging" |
237 and self.__fromImports.get(node.func.id) == "logging" |
238 ): |
238 ): |
239 self.__error(node.lineno - 1, node.col_offset, "L115") |
239 self.__error(node.lineno - 1, node.col_offset, "L-115") |
240 |
240 |
241 if ( |
241 if ( |
242 self.__loggingName |
242 self.__loggingName |
243 and isinstance(node.func, ast.Attribute) |
243 and isinstance(node.func, ast.Attribute) |
244 and node.func.attr == "getLogger" |
244 and node.func.attr == "getLogger" |
261 if ( |
261 if ( |
262 node.args |
262 node.args |
263 and isinstance(node.args[0], ast.Name) |
263 and isinstance(node.args[0], ast.Name) |
264 and node.args[0].id in self.GetLoggerNames |
264 and node.args[0].id in self.GetLoggerNames |
265 ): |
265 ): |
266 self.__error(node.args[0].lineno - 1, node.args[0].col_offset, "L102") |
266 self.__error(node.args[0].lineno - 1, node.args[0].col_offset, "L-102") |
267 |
267 |
268 if ( |
268 if ( |
269 isinstance(node.func, ast.Attribute) |
269 isinstance(node.func, ast.Attribute) |
270 and node.func.attr in _LoggerMethods |
270 and node.func.attr in _LoggerMethods |
271 and isinstance(node.func.value, ast.Name) |
271 and isinstance(node.func.value, ast.Name) |
275 ): |
275 ): |
276 excHandler = self.__currentExceptHandler() |
276 excHandler = self.__currentExceptHandler() |
277 |
277 |
278 # L108 |
278 # L108 |
279 if node.func.attr == "warn": |
279 if node.func.attr == "warn": |
280 self.__error(node.lineno - 1, node.col_offset, "L108") |
280 self.__error(node.lineno - 1, node.col_offset, "L-108") |
281 |
281 |
282 # L103 |
282 # L103 |
283 extraKeys = [] |
283 extraKeys = [] |
284 if any((extraNode := kw).arg == "extra" for kw in node.keywords): |
284 if any((extraNode := kw).arg == "extra" for kw in node.keywords): |
285 if isinstance(extraNode.value, ast.Dict): |
285 if isinstance(extraNode.value, ast.Dict): |
300 ] |
300 ] |
301 |
301 |
302 for key, keyNode in extraKeys: |
302 for key, keyNode in extraKeys: |
303 if key in _LogrecordAttributes: |
303 if key in _LogrecordAttributes: |
304 self.__error( |
304 self.__error( |
305 keyNode.lineno - 1, keyNode.col_offset, "L103", repr(key) |
305 keyNode.lineno - 1, keyNode.col_offset, "L-103", repr(key) |
306 ) |
306 ) |
307 |
307 |
308 if node.func.attr == "exception": |
308 if node.func.attr == "exception": |
309 # L104 |
309 # L104 |
310 if not excHandler: |
310 if not excHandler: |
311 self.__error(node.lineno - 1, node.col_offset, "L104") |
311 self.__error(node.lineno - 1, node.col_offset, "L-104") |
312 |
312 |
313 if any((excInfo := kw).arg == "exc_info" for kw in node.keywords): |
313 if any((excInfo := kw).arg == "exc_info" for kw in node.keywords): |
314 # L106 |
314 # L106 |
315 if ( |
315 if ( |
316 isinstance(excInfo.value, ast.Constant) and excInfo.value.value |
316 isinstance(excInfo.value, ast.Constant) and excInfo.value.value |
317 ) or ( |
317 ) or ( |
318 excHandler |
318 excHandler |
319 and isinstance(excInfo.value, ast.Name) |
319 and isinstance(excInfo.value, ast.Name) |
320 and excInfo.value.id == excHandler.name |
320 and excInfo.value.id == excHandler.name |
321 ): |
321 ): |
322 self.__error(excInfo.lineno - 1, excInfo.col_offset, "L106") |
322 self.__error(excInfo.lineno - 1, excInfo.col_offset, "L-106") |
323 |
323 |
324 # L107 |
324 # L107 |
325 elif ( |
325 elif ( |
326 isinstance(excInfo.value, ast.Constant) |
326 isinstance(excInfo.value, ast.Constant) |
327 and not excInfo.value.value |
327 and not excInfo.value.value |
328 ): |
328 ): |
329 self.__error(excInfo.lineno - 1, excInfo.col_offset, "L107") |
329 self.__error(excInfo.lineno - 1, excInfo.col_offset, "L-107") |
330 |
330 |
331 # L105 |
331 # L105 |
332 elif node.func.attr == "error" and excHandler is not None: |
332 elif node.func.attr == "error" and excHandler is not None: |
333 rewritable = False |
333 rewritable = False |
334 if any((excInfo := kw).arg == "exc_info" for kw in node.keywords): |
334 if any((excInfo := kw).arg == "exc_info" for kw in node.keywords): |
341 rewritable = True |
341 rewritable = True |
342 else: |
342 else: |
343 rewritable = True |
343 rewritable = True |
344 |
344 |
345 if rewritable: |
345 if rewritable: |
346 self.__error(node.lineno - 1, node.col_offset, "L105") |
346 self.__error(node.lineno - 1, node.col_offset, "L-105") |
347 |
347 |
348 # L114 |
348 # L114 |
349 elif ( |
349 elif ( |
350 excHandler is None |
350 excHandler is None |
351 and any((excInfo := kw).arg == "exc_info" for kw in node.keywords) |
351 and any((excInfo := kw).arg == "exc_info" for kw in node.keywords) |
352 and isinstance(excInfo.value, ast.Constant) |
352 and isinstance(excInfo.value, ast.Constant) |
353 and excInfo.value.value |
353 and excInfo.value.value |
354 ): |
354 ): |
355 self.__error(excInfo.lineno - 1, excInfo.col_offset, "L114") |
355 self.__error(excInfo.lineno - 1, excInfo.col_offset, "L-114") |
356 |
356 |
357 # L110 |
357 # L110 |
358 if ( |
358 if ( |
359 node.func.attr == "exception" |
359 node.func.attr == "exception" |
360 and len(node.args) >= 1 |
360 and len(node.args) >= 1 |
361 and isinstance(node.args[0], ast.Name) |
361 and isinstance(node.args[0], ast.Name) |
362 and excHandler is not None |
362 and excHandler is not None |
363 and node.args[0].id == excHandler.name |
363 and node.args[0].id == excHandler.name |
364 ): |
364 ): |
365 self.__error(node.args[0].lineno - 1, node.args[0].col_offset, "L110") |
365 self.__error(node.args[0].lineno - 1, node.args[0].col_offset, "L-110") |
366 |
366 |
367 msgArgKwarg = False |
367 msgArgKwarg = False |
368 if node.func.attr == "log" and len(node.args) >= 2: |
368 if node.func.attr == "log" and len(node.args) >= 2: |
369 msgArg = node.args[1] |
369 msgArg = node.args[1] |
370 elif node.func.attr != "log" and len(node.args) >= 1: |
370 elif node.func.attr != "log" and len(node.args) >= 1: |
376 except IndexError: |
376 except IndexError: |
377 msgArg = None |
377 msgArg = None |
378 |
378 |
379 # L111 |
379 # L111 |
380 if isinstance(msgArg, ast.JoinedStr): |
380 if isinstance(msgArg, ast.JoinedStr): |
381 self.__error(msgArg.lineno - 1, msgArg.col_offset, "L111a") |
381 self.__error(msgArg.lineno - 1, msgArg.col_offset, "L-111a") |
382 elif ( |
382 elif ( |
383 isinstance(msgArg, ast.Call) |
383 isinstance(msgArg, ast.Call) |
384 and isinstance(msgArg.func, ast.Attribute) |
384 and isinstance(msgArg.func, ast.Attribute) |
385 and isinstance(msgArg.func.value, ast.Constant) |
385 and isinstance(msgArg.func.value, ast.Constant) |
386 and isinstance(msgArg.func.value.value, str) |
386 and isinstance(msgArg.func.value.value, str) |
387 and msgArg.func.attr == "format" |
387 and msgArg.func.attr == "format" |
388 ): |
388 ): |
389 self.__error(msgArg.lineno - 1, msgArg.col_offset, "L111b") |
389 self.__error(msgArg.lineno - 1, msgArg.col_offset, "L-111b") |
390 elif ( |
390 elif ( |
391 isinstance(msgArg, ast.BinOp) |
391 isinstance(msgArg, ast.BinOp) |
392 and isinstance(msgArg.op, ast.Mod) |
392 and isinstance(msgArg.op, ast.Mod) |
393 and isinstance(msgArg.left, ast.Constant) |
393 and isinstance(msgArg.left, ast.Constant) |
394 and isinstance(msgArg.left.value, str) |
394 and isinstance(msgArg.left.value, str) |
395 ): |
395 ): |
396 self.__error(msgArg.lineno - 1, msgArg.col_offset, "L111c") |
396 self.__error(msgArg.lineno - 1, msgArg.col_offset, "L-111c") |
397 elif isinstance(msgArg, ast.BinOp) and self.__isAddChainWithNonStr(msgArg): |
397 elif isinstance(msgArg, ast.BinOp) and self.__isAddChainWithNonStr(msgArg): |
398 self.__error(msgArg.lineno - 1, msgArg.col_offset, "L111d") |
398 self.__error(msgArg.lineno - 1, msgArg.col_offset, "L-111d") |
399 |
399 |
400 # L112 |
400 # L112 |
401 if ( |
401 if ( |
402 msgArg is not None |
402 msgArg is not None |
403 and not msgArgKwarg |
403 and not msgArgKwarg |
442 given = {cast(ast.Constant, k).value for k in dictNode.keys} |
442 given = {cast(ast.Constant, k).value for k in dictNode.keys} |
443 if missing := modnames - given: |
443 if missing := modnames - given: |
444 self.__error( |
444 self.__error( |
445 msgArg.lineno - 1, |
445 msgArg.lineno - 1, |
446 msgArg.col_offset, |
446 msgArg.col_offset, |
447 "L113a", # missing keys |
447 "L-113a", # missing keys |
448 ", ".join([repr(k) for k in missing]), |
448 ", ".join([repr(k) for k in missing]), |
449 ) |
449 ) |
450 |
450 |
451 if missing := given - modnames: |
451 if missing := given - modnames: |
452 self.__error( |
452 self.__error( |
453 msgArg.lineno - 1, |
453 msgArg.lineno - 1, |
454 msgArg.col_offset, |
454 msgArg.col_offset, |
455 "L113b", # unreferenced keys |
455 "L-113b", # unreferenced keys |
456 ", ".join([repr(k) for k in missing]), |
456 ", ".join([repr(k) for k in missing]), |
457 ) |
457 ) |
458 |
458 |
459 return |
459 return |
460 |
460 |