43 "N822", |
45 "N822", |
44 "N823", |
46 "N823", |
45 "N831", |
47 "N831", |
46 ] |
48 ] |
47 |
49 |
48 def __init__(self, tree, filename, options): |
50 def __init__(self, source, filename, tree, select, ignore, expected, repeat, args): |
49 """ |
51 """ |
50 Constructor (according to 'extended' pycodestyle.py API) |
52 Constructor |
51 |
53 |
52 @param tree AST tree of the source file |
54 @param source source code to be checked |
53 @type ast.AST |
55 @type list of str |
54 @param filename name of the source file |
56 @param filename name of the source file |
55 @type str |
57 @type str |
56 @param options options as parsed by pycodestyle.StyleGuide |
58 @param tree AST tree of the source code |
57 @type optparse.Option |
59 @type ast.Module |
58 """ |
60 @param select list of selected codes |
|
61 @type list of str |
|
62 @param ignore list of codes to be ignored |
|
63 @type list of str |
|
64 @param expected list of expected codes |
|
65 @type list of str |
|
66 @param repeat flag indicating to report each occurrence of a code |
|
67 @type bool |
|
68 @param args dictionary of arguments for the various checks |
|
69 @type dict |
|
70 """ |
|
71 self.__select = tuple(select) |
|
72 self.__ignore = tuple(ignore) |
|
73 self.__expected = expected[:] |
|
74 self.__repeat = repeat |
|
75 self.__filename = filename |
|
76 self.__source = source[:] |
|
77 self.__tree = copy.deepcopy(tree) |
|
78 self.__args = args |
|
79 |
59 self.__parents = collections.deque() |
80 self.__parents = collections.deque() |
60 self.__tree = tree |
81 |
61 self.__filename = filename |
82 # statistics counters |
|
83 self.counters = {} |
|
84 |
|
85 # collection of detected errors |
|
86 self.errors = [] |
62 |
87 |
63 self.__checkersWithCodes = { |
88 self.__checkersWithCodes = { |
64 "classdef": [ |
89 "classdef": [ |
65 (self.__checkClassName, ("N801", "N818")), |
90 (self.__checkClassName, ("N801", "N818")), |
66 (self.__checkNameToBeAvoided, ("N831",)), |
91 (self.__checkNameToBeAvoided, ("N831",)), |
97 for name in ("import", "importfrom"): |
122 for name in ("import", "importfrom"): |
98 self.__checkersWithCodes[name] = [ |
123 self.__checkersWithCodes[name] = [ |
99 (self.__checkImportAs, ("N811", "N812", "N813", "N814", "N815")), |
124 (self.__checkImportAs, ("N811", "N812", "N813", "N814", "N815")), |
100 ] |
125 ] |
101 |
126 |
102 self.__checkers = {} |
127 self.__checkers = collections.defaultdict(list) |
103 for key, checkers in self.__checkersWithCodes.items(): |
128 for key, checkers in self.__checkersWithCodes.items(): |
104 for checker, codes in checkers: |
129 for checker, codes in checkers: |
105 if any(not (code and options.ignore_code(code)) for code in codes): |
130 if any(not (code and self.__ignoreCode(code)) for code in codes): |
106 if key not in self.__checkers: |
|
107 self.__checkers[key] = [] |
|
108 self.__checkers[key].append(checker) |
131 self.__checkers[key].append(checker) |
|
132 |
|
133 def __ignoreCode(self, code): |
|
134 """ |
|
135 Private method to check if the message code should be ignored. |
|
136 |
|
137 @param code message code to check for |
|
138 @type str |
|
139 @return flag indicating to ignore the given code |
|
140 @rtype bool |
|
141 """ |
|
142 return ( |
|
143 code in self.__ignore |
|
144 or (code.startswith(self.__ignore) and not code.startswith(self.__select)) |
|
145 ) |
|
146 |
|
147 def __error(self, node, code): |
|
148 """ |
|
149 Private method to build the error information. |
|
150 |
|
151 @param node AST node to report an error for |
|
152 @type ast.AST |
|
153 @param code error code to report |
|
154 @type str |
|
155 """ |
|
156 if self.__ignoreCode(code): |
|
157 return |
|
158 |
|
159 if isinstance(node, ast.Module): |
|
160 lineno = 0 |
|
161 offset = 0 |
|
162 else: |
|
163 lineno = node.lineno |
|
164 offset = node.col_offset |
|
165 if isinstance(node, ast.ClassDef): |
|
166 lineno += len(node.decorator_list) |
|
167 offset += 6 |
|
168 elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): |
|
169 lineno += len(node.decorator_list) |
|
170 offset += 4 |
|
171 |
|
172 # record the issue with one based line number |
|
173 errorInfo = { |
|
174 "file": self.__filename, |
|
175 "line": lineno, |
|
176 "offset": offset, |
|
177 "code": code, |
|
178 "args": [], |
|
179 } |
|
180 |
|
181 if errorInfo not in self.errors: |
|
182 # this issue was not seen before |
|
183 if code in self.counters: |
|
184 self.counters[code] += 1 |
|
185 else: |
|
186 self.counters[code] = 1 |
|
187 |
|
188 # Don't care about expected codes |
|
189 if code in self.__expected: |
|
190 return |
|
191 |
|
192 if code and (self.counters[code] == 1 or self.__repeat): |
|
193 self.errors.append(errorInfo) |
109 |
194 |
110 def run(self): |
195 def run(self): |
111 """ |
196 """ |
112 Public method run by the pycodestyle.py checker. |
197 Public method run by the pycodestyle.py checker. |
113 |
198 |
124 """ |
209 """ |
125 Private method to scan the given AST tree. |
210 Private method to scan the given AST tree. |
126 |
211 |
127 @param node AST tree node to scan |
212 @param node AST tree node to scan |
128 @type ast.AST |
213 @type ast.AST |
129 @yield tuple giving line number, offset within line and error code |
214 """ |
130 @ytype tuple of (int, int, str) |
215 self.__visitNode(node) |
131 """ |
|
132 yield from self.__visitNode(node) |
|
133 self.__parents.append(node) |
216 self.__parents.append(node) |
134 for child in ast.iter_child_nodes(node): |
217 for child in ast.iter_child_nodes(node): |
135 yield from self.__visitTree(child) |
218 self.__visitTree(child) |
136 self.__parents.pop() |
219 self.__parents.pop() |
137 |
220 |
138 def __visitNode(self, node): |
221 def __visitNode(self, node): |
139 """ |
222 """ |
140 Private method to inspect the given AST node. |
223 Private method to inspect the given AST node. |
141 |
224 |
142 @param node AST tree node to inspect |
225 @param node AST tree node to inspect |
143 @type ast.AST |
226 @type ast.AST |
144 @yield tuple giving line number, offset within line and error code |
|
145 @ytype tuple of (int, int, str) |
|
146 """ |
227 """ |
147 if isinstance(node, ast.ClassDef): |
228 if isinstance(node, ast.ClassDef): |
148 self.__tagClassFunctions(node) |
229 self.__tagClassFunctions(node) |
149 elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): |
230 elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): |
150 self.__findGlobalDefs(node) |
231 self.__findGlobalDefs(node) |
151 |
232 |
152 checkerName = node.__class__.__name__.lower() |
233 checkerName = node.__class__.__name__.lower() |
153 if checkerName in self.__checkers: |
234 if checkerName in self.__checkers: |
154 for checker in self.__checkers[checkerName]: |
235 for checker in self.__checkers[checkerName]: |
155 for error in checker(node, self.__parents): |
236 checker(node, self.__parents) |
156 yield error + (self.__checkers[checkerName],) |
|
157 |
237 |
158 def __tagClassFunctions(self, classNode): |
238 def __tagClassFunctions(self, classNode): |
159 """ |
239 """ |
160 Private method to tag functions if they are methods, class methods or |
240 Private method to tag functions if they are methods, class methods or |
161 static methods. |
241 static methods. |
231 """ |
311 """ |
232 posArgs = [arg.arg for arg in node.args.args] |
312 posArgs = [arg.arg for arg in node.args.args] |
233 kwOnly = [arg.arg for arg in node.args.kwonlyargs] |
313 kwOnly = [arg.arg for arg in node.args.kwonlyargs] |
234 return posArgs + kwOnly |
314 return posArgs + kwOnly |
235 |
315 |
236 def __error(self, node, code): |
|
237 """ |
|
238 Private method to build the error information. |
|
239 |
|
240 @param node AST node to report an error for |
|
241 @type ast.AST |
|
242 @param code error code to report |
|
243 @type str |
|
244 @return tuple giving line number, offset within line and error code |
|
245 @rtype tuple of (int, int, str) |
|
246 """ |
|
247 if isinstance(node, ast.Module): |
|
248 lineno = 0 |
|
249 offset = 0 |
|
250 else: |
|
251 lineno = node.lineno |
|
252 offset = node.col_offset |
|
253 if isinstance(node, ast.ClassDef): |
|
254 lineno += len(node.decorator_list) |
|
255 offset += 6 |
|
256 elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): |
|
257 lineno += len(node.decorator_list) |
|
258 offset += 4 |
|
259 return (lineno, offset, code) |
|
260 |
|
261 def __isNameToBeAvoided(self, name): |
316 def __isNameToBeAvoided(self, name): |
262 """ |
317 """ |
263 Private method to check, if the given name should be avoided. |
318 Private method to check, if the given name should be avoided. |
264 |
319 |
265 @param name name to be checked |
320 @param name name to be checked |
275 |
330 |
276 @param node AST note to check |
331 @param node AST note to check |
277 @type ast.Ast |
332 @type ast.Ast |
278 @param _parents list of parent nodes (unused) |
333 @param _parents list of parent nodes (unused) |
279 @type list of ast.AST |
334 @type list of ast.AST |
280 @yield tuple giving line number, offset within line and error code |
|
281 @ytype tuple of (int, int, str) |
|
282 """ |
335 """ |
283 if isinstance(node, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)): |
336 if isinstance(node, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)): |
284 name = node.name |
337 name = node.name |
285 if self.__isNameToBeAvoided(name): |
338 if self.__isNameToBeAvoided(name): |
286 yield self.__error(node, "N831") |
339 self.__error(node, "N831") |
287 |
340 |
288 elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): |
341 elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): |
289 argNames = self.__getArgNames(node) |
342 argNames = self.__getArgNames(node) |
290 for arg in argNames: |
343 for arg in argNames: |
291 if self.__isNameToBeAvoided(arg): |
344 if self.__isNameToBeAvoided(arg): |
292 yield self.__error(node, "N831") |
345 self.__error(node, "N831") |
293 |
346 |
294 elif isinstance(node, (ast.Assign, ast.NamedExpr, ast.AnnAssign)): |
347 elif isinstance(node, (ast.Assign, ast.NamedExpr, ast.AnnAssign)): |
295 if isinstance(node, ast.Assign): |
348 if isinstance(node, ast.Assign): |
296 targets = node.targets |
349 targets = node.targets |
297 else: |
350 else: |
298 targets = [node.target] |
351 targets = [node.target] |
299 for target in targets: |
352 for target in targets: |
300 if isinstance(target, ast.Name): |
353 if isinstance(target, ast.Name): |
301 name = target.id |
354 name = target.id |
302 if bool(name) and self.__isNameToBeAvoided(name): |
355 if bool(name) and self.__isNameToBeAvoided(name): |
303 yield self.__error(node, "N831") |
356 self.__error(node, "N831") |
304 |
357 |
305 elif isinstance(target, (ast.Tuple, ast.List)): |
358 elif isinstance(target, (ast.Tuple, ast.List)): |
306 for element in target.elts: |
359 for element in target.elts: |
307 if isinstance(element, ast.Name): |
360 if isinstance(element, ast.Name): |
308 name = element.id |
361 name = element.id |
309 if bool(name) and self.__isNameToBeAvoided(name): |
362 if bool(name) and self.__isNameToBeAvoided(name): |
310 yield self.__error(node, "N831") |
363 self.__error(node, "N831") |
311 |
364 |
312 def __getClassdef(self, name, parents): |
365 def __getClassdef(self, name, parents): |
313 """ |
366 """ |
314 Private method to extract the class definition. |
367 Private method to extract the class definition. |
315 |
368 |
364 |
417 |
365 @param node AST note to check |
418 @param node AST note to check |
366 @type ast.ClassDef |
419 @type ast.ClassDef |
367 @param parents list of parent nodes |
420 @param parents list of parent nodes |
368 @type list of ast.AST |
421 @type list of ast.AST |
369 @yield tuple giving line number, offset within line and error code |
|
370 @ytype tuple of (int, int, str) |
|
371 """ |
422 """ |
372 name = node.name |
423 name = node.name |
373 strippedName = name.strip("_") |
424 strippedName = name.strip("_") |
374 if not strippedName[:1].isupper() or "_" in strippedName: |
425 if not strippedName[:1].isupper() or "_" in strippedName: |
375 yield self.__error(node, "N801") |
426 self.__error(node, "N801") |
376 |
427 |
377 superClasses = self.__superClassNames(name, parents) |
428 superClasses = self.__superClassNames(name, parents) |
378 if "Exception" in superClasses and not name.endswith("Error"): |
429 if "Exception" in superClasses and not name.endswith("Error"): |
379 yield self.__error(node, "N818") |
430 self.__error(node, "N818") |
380 |
431 |
381 def __checkFunctionName(self, node, _parents): |
432 def __checkFunctionName(self, node, _parents): |
382 """ |
433 """ |
383 Private class to check the given node for function name |
434 Private class to check the given node for function name |
384 conventions (N802, N809). |
435 conventions (N802, N809). |
391 |
442 |
392 @param node AST note to check |
443 @param node AST note to check |
393 @type ast.FunctionDef or ast.AsynFunctionDef |
444 @type ast.FunctionDef or ast.AsynFunctionDef |
394 @param _parents list of parent nodes (unused) |
445 @param _parents list of parent nodes (unused) |
395 @type list of ast.AST |
446 @type list of ast.AST |
396 @yield tuple giving line number, offset within line and error code |
|
397 @ytype tuple of (int, int, str) |
|
398 """ |
447 """ |
399 functionType = getattr(node, "function_type", "function") |
448 functionType = getattr(node, "function_type", "function") |
400 name = node.name |
449 name = node.name |
401 |
450 |
402 if name in ("__dir__", "__getattr__"): |
451 if name in ("__dir__", "__getattr__"): |
403 return |
452 return |
404 |
453 |
405 if name.lower() != name: |
454 if name.lower() != name: |
406 yield self.__error(node, "N802") |
455 self.__error(node, "N802") |
407 if functionType == "function" and name[:2] == "__" and name[-2:] == "__": |
456 if functionType == "function" and name[:2] == "__" and name[-2:] == "__": |
408 yield self.__error(node, "N809") |
457 self.__error(node, "N809") |
409 |
458 |
410 def __checkFunctionArgumentNames(self, node, _parents): |
459 def __checkFunctionArgumentNames(self, node, _parents): |
411 """ |
460 """ |
412 Private class to check the argument names of functions |
461 Private class to check the argument names of functions |
413 (N803, N804, N805, N806). |
462 (N803, N804, N805, N806). |
418 |
467 |
419 @param node AST note to check |
468 @param node AST note to check |
420 @type ast.FunctionDef or ast.AsynFunctionDef |
469 @type ast.FunctionDef or ast.AsynFunctionDef |
421 @param _parents list of parent nodes (unused) |
470 @param _parents list of parent nodes (unused) |
422 @type list of ast.AST |
471 @type list of ast.AST |
423 @yield tuple giving line number, offset within line and error code |
|
424 @ytype tuple of (int, int, str) |
|
425 """ |
472 """ |
426 if node.args.kwarg is not None: |
473 if node.args.kwarg is not None: |
427 kwarg = node.args.kwarg.arg |
474 kwarg = node.args.kwarg.arg |
428 if kwarg.lower() != kwarg: |
475 if kwarg.lower() != kwarg: |
429 yield self.__error(node, "N803") |
476 self.__error(node, "N803") |
430 |
477 |
431 elif node.args.vararg is not None: |
478 elif node.args.vararg is not None: |
432 vararg = node.args.vararg.arg |
479 vararg = node.args.vararg.arg |
433 if vararg.lower() != vararg: |
480 if vararg.lower() != vararg: |
434 yield self.__error(node, "N803") |
481 self.__error(node, "N803") |
435 |
482 |
436 else: |
483 else: |
437 argNames = self.__getArgNames(node) |
484 argNames = self.__getArgNames(node) |
438 functionType = getattr(node, "function_type", "function") |
485 functionType = getattr(node, "function_type", "function") |
439 |
486 |
440 if not argNames: |
487 if not argNames: |
441 if functionType == "method": |
488 if functionType == "method": |
442 yield self.__error(node, "N805") |
489 self.__error(node, "N805") |
443 elif functionType == "classmethod": |
490 elif functionType == "classmethod": |
444 yield self.__error(node, "N804") |
491 self.__error(node, "N804") |
445 |
492 |
446 elif functionType == "method" and argNames[0] != "self": |
493 elif functionType == "method" and argNames[0] != "self": |
447 yield self.__error(node, "N805") |
494 self.__error(node, "N805") |
448 elif functionType == "classmethod" and argNames[0] != "cls": |
495 elif functionType == "classmethod" and argNames[0] != "cls": |
449 yield self.__error(node, "N804") |
496 self.__error(node, "N804") |
450 elif functionType == "staticmethod" and argNames[0] in ("cls", "self"): |
497 elif functionType == "staticmethod" and argNames[0] in ("cls", "self"): |
451 yield self.__error(node, "N806") |
498 self.__error(node, "N806") |
452 for arg in argNames: |
499 for arg in argNames: |
453 if arg.lower() != arg: |
500 if arg.lower() != arg: |
454 yield self.__error(node, "N803") |
501 self.__error(node, "N803") |
455 break |
502 break |
456 |
503 |
457 def __checkVariableNames(self, node, parents): |
504 def __checkVariableNames(self, node, parents): |
458 """ |
505 """ |
459 Private method to check variable names in function, class and global scope |
506 Private method to check variable names in function, class and global scope |
463 |
510 |
464 @param node AST note to check |
511 @param node AST note to check |
465 @type ast.AST |
512 @type ast.AST |
466 @param parents list of parent nodes |
513 @param parents list of parent nodes |
467 @type list of ast.AST |
514 @type list of ast.AST |
468 @yield tuple giving line number, offset within line and error code |
|
469 @ytype tuple of (int, int, str) |
|
470 """ |
515 """ |
471 nodeType = type(node) |
516 nodeType = type(node) |
472 if nodeType is ast.Assign: |
517 if nodeType is ast.Assign: |
473 if self.__isNamedTupel(node.value): |
518 if self.__isNamedTupel(node.value): |
474 return |
519 return |
475 for target in node.targets: |
520 for target in node.targets: |
476 yield from self.__findVariableNameErrors(target, parents) |
521 self.__findVariableNameErrors(target, parents) |
477 |
522 |
478 elif nodeType in (ast.NamedExpr, ast.AnnAssign): |
523 elif nodeType in (ast.NamedExpr, ast.AnnAssign): |
479 if self.__isNamedTupel(node.value): |
524 if self.__isNamedTupel(node.value): |
480 return |
525 return |
481 yield from self.__findVariableNameErrors(node.target, parents) |
526 self.__findVariableNameErrors(node.target, parents) |
482 |
527 |
483 elif nodeType in (ast.With, ast.AsyncWith): |
528 elif nodeType in (ast.With, ast.AsyncWith): |
484 for item in node.items: |
529 for item in node.items: |
485 yield from self.__findVariableNameErrors(item.optional_vars, parents) |
530 self.__findVariableNameErrors(item.optional_vars, parents) |
486 |
531 |
487 elif nodeType in (ast.For, ast.AsyncFor): |
532 elif nodeType in (ast.For, ast.AsyncFor): |
488 yield from self.__findVariableNameErrors(node.target, parents) |
533 self.__findVariableNameErrors(node.target, parents) |
489 |
534 |
490 elif nodeType is ast.ExceptHandler: |
535 elif nodeType is ast.ExceptHandler: |
491 if node.name: |
536 if node.name: |
492 yield from self.__findVariableNameErrors(node, parents) |
537 self.__findVariableNameErrors(node, parents) |
493 |
538 |
494 elif nodeType in (ast.GeneratorExp, ast.ListComp, ast.DictComp, ast.SetComp): |
539 elif nodeType in (ast.GeneratorExp, ast.ListComp, ast.DictComp, ast.SetComp): |
495 for gen in node.generators: |
540 for gen in node.generators: |
496 yield from self.__findVariableNameErrors(gen.target, parents) |
541 self.__findVariableNameErrors(gen.target, parents) |
497 |
542 |
498 def __findVariableNameErrors(self, assignmentTarget, parents): |
543 def __findVariableNameErrors(self, assignmentTarget, parents): |
499 """ |
544 """ |
500 Private method to check, if there is a variable name error. |
545 Private method to check, if there is a variable name error. |
501 |
546 |
502 @param assignmentTarget target node of the assignment |
547 @param assignmentTarget target node of the assignment |
503 @type ast.Name, ast.Tuple, ast.List or ast.ExceptHandler |
548 @type ast.Name, ast.Tuple, ast.List or ast.ExceptHandler |
504 @param parents list of parent nodes |
549 @param parents list of parent nodes |
505 @type ast.AST |
550 @type ast.AST |
506 @yield tuple giving line number, offset within line and error code |
|
507 @ytype tuple of (int, int, str) |
|
508 """ |
551 """ |
509 for parentFunc in reversed(parents): |
552 for parentFunc in reversed(parents): |
510 if isinstance(parentFunc, ast.ClassDef): |
553 if isinstance(parentFunc, ast.ClassDef): |
511 checker = self.__classVariableCheck |
554 checker = self.__classVariableCheck |
512 break |
555 break |
627 |
670 |
628 @param node AST node to check |
671 @param node AST node to check |
629 @type ast.AST |
672 @type ast.AST |
630 @param _parents list of parent nodes (unused) |
673 @param _parents list of parent nodes (unused) |
631 @type list of ast.AST |
674 @type list of ast.AST |
632 @yield tuple giving line number, offset within line and error code |
|
633 @ytype tuple of (int, int, str) |
|
634 """ |
675 """ |
635 if self.__filename: |
676 if self.__filename: |
636 moduleName = os.path.splitext(os.path.basename(self.__filename))[0] |
677 moduleName = os.path.splitext(os.path.basename(self.__filename))[0] |
637 if moduleName.lower() != moduleName: |
678 if moduleName.lower() != moduleName: |
638 yield self.__error(node, "N807") |
679 self.__error(node, "N807") |
639 |
680 |
640 if moduleName == "__init__": |
681 if moduleName == "__init__": |
641 # we got a package |
682 # we got a package |
642 packageName = os.path.split(os.path.dirname(self.__filename))[1] |
683 packageName = os.path.split(os.path.dirname(self.__filename))[1] |
643 if packageName.lower() != packageName: |
684 if packageName.lower() != packageName: |
644 yield self.__error(node, "N808") |
685 self.__error(node, "N808") |
645 |
686 |
646 def __checkImportAs(self, node, _parents): |
687 def __checkImportAs(self, node, _parents): |
647 """ |
688 """ |
648 Private method to check that imports don't change the |
689 Private method to check that imports don't change the |
649 naming convention (N811, N812, N813, N814, N815). |
690 naming convention (N811, N812, N813, N814, N815). |
650 |
691 |
651 @param node AST node to check |
692 @param node AST node to check |
652 @type ast.Import |
693 @type ast.Import |
653 @param _parents list of parent nodes (unused) |
694 @param _parents list of parent nodes (unused) |
654 @type list of ast.AST |
695 @type list of ast.AST |
655 @yield tuple giving line number, offset within line and error code |
|
656 @ytype tuple of (int, int, str) |
|
657 """ |
696 """ |
658 for name in node.names: |
697 for name in node.names: |
659 asname = name.asname |
698 asname = name.asname |
660 if not asname: |
699 if not asname: |
661 continue |
700 continue |
662 |
701 |
663 originalName = name.name |
702 originalName = name.name |
664 if originalName.isupper(): |
703 if originalName.isupper(): |
665 if not asname.isupper(): |
704 if not asname.isupper(): |
666 yield self.__error(node, "N811") |
705 self.__error(node, "N811") |
667 elif originalName.islower(): |
706 elif originalName.islower(): |
668 if asname.lower() != asname: |
707 if asname.lower() != asname: |
669 yield self.__error(node, "N812") |
708 self.__error(node, "N812") |
670 elif asname.islower(): |
709 elif asname.islower(): |
671 yield self.__error(node, "N813") |
710 self.__error(node, "N813") |
672 elif asname.isupper(): |
711 elif asname.isupper(): |
673 if "".join(filter(str.isupper, originalName)) == asname: |
712 if "".join(filter(str.isupper, originalName)) == asname: |
674 yield self.__error(node, "N815") |
713 self.__error(node, "N815") |
675 else: |
714 else: |
676 yield self.__error(node, "N814") |
715 self.__error(node, "N814") |