src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Naming/NamingStyleChecker.py

branch
eric7
changeset 11147
dee6e106b4d3
parent 11145
d328a7b74fd8
child 11148
15e30f0c76a8
equal deleted inserted replaced
11146:59e04f7003e9 11147:dee6e106b4d3
24 """ 24 """
25 Class implementing a checker for naming conventions. 25 Class implementing a checker for naming conventions.
26 """ 26 """
27 27
28 Codes = [ 28 Codes = [
29 "N801", 29 "N-801",
30 "N802", 30 "N-802",
31 "N803", 31 "N-803",
32 "N804", 32 "N-804",
33 "N805", 33 "N-805",
34 "N806", 34 "N-806",
35 "N807", 35 "N-807",
36 "N808", 36 "N-808",
37 "N809", 37 "N-809",
38 "N811", 38 "N-811",
39 "N812", 39 "N-812",
40 "N813", 40 "N-813",
41 "N814", 41 "N-814",
42 "N815", 42 "N-815",
43 "N818", 43 "N-818",
44 "N821", 44 "N-821",
45 "N822", 45 "N-822",
46 "N823", 46 "N-823",
47 "N831", 47 "N-831",
48 ] 48 ]
49 49
50 def __init__(self, source, filename, tree, select, ignore, expected, repeat, args): 50 def __init__(self, source, filename, tree, select, ignore, expected, repeat, args):
51 """ 51 """
52 Constructor 52 Constructor
85 # collection of detected errors 85 # collection of detected errors
86 self.errors = [] 86 self.errors = []
87 87
88 self.__checkersWithCodes = { 88 self.__checkersWithCodes = {
89 "classdef": [ 89 "classdef": [
90 (self.__checkClassName, ("N801", "N818")), 90 (self.__checkClassName, ("N-801", "N-818")),
91 (self.__checkNameToBeAvoided, ("N831",)), 91 (self.__checkNameToBeAvoided, ("N-831",)),
92 ], 92 ],
93 "module": [ 93 "module": [
94 (self.__checkModule, ("N807", "N808")), 94 (self.__checkModule, ("N-807", "N-808")),
95 ], 95 ],
96 } 96 }
97 for name in ("functiondef", "asyncfunctiondef"): 97 for name in ("functiondef", "asyncfunctiondef"):
98 self.__checkersWithCodes[name] = [ 98 self.__checkersWithCodes[name] = [
99 (self.__checkFunctionName, ("N802", "N809")), 99 (self.__checkFunctionName, ("N-802", "N-809")),
100 (self.__checkFunctionArgumentNames, ("N803", "N804", "N805", "N806")), 100 (self.__checkFunctionArgumentNames, ("N-803", "N-804", "N-805", "N-806")),
101 (self.__checkNameToBeAvoided, ("N831",)), 101 (self.__checkNameToBeAvoided, ("N-831",)),
102 ] 102 ]
103 for name in ("assign", "namedexpr", "annassign"): 103 for name in ("assign", "namedexpr", "annassign"):
104 self.__checkersWithCodes[name] = [ 104 self.__checkersWithCodes[name] = [
105 (self.__checkVariableNames, ("N821",)), 105 (self.__checkVariableNames, ("N-821",)),
106 (self.__checkNameToBeAvoided, ("N831",)), 106 (self.__checkNameToBeAvoided, ("N-831",)),
107 ] 107 ]
108 for name in ( 108 for name in (
109 "with", 109 "with",
110 "asyncwith", 110 "asyncwith",
111 "for", 111 "for",
115 "listcomp", 115 "listcomp",
116 "dictcomp", 116 "dictcomp",
117 "setcomp", 117 "setcomp",
118 ): 118 ):
119 self.__checkersWithCodes[name] = [ 119 self.__checkersWithCodes[name] = [
120 (self.__checkVariableNames, ("N821",)), 120 (self.__checkVariableNames, ("N-821",)),
121 ] 121 ]
122 for name in ("import", "importfrom"): 122 for name in ("import", "importfrom"):
123 self.__checkersWithCodes[name] = [ 123 self.__checkersWithCodes[name] = [
124 (self.__checkImportAs, ("N811", "N812", "N813", "N814", "N815")), 124 (self.__checkImportAs, ("N-811", "N-812", "N-813", "N-814", "N-815")),
125 ] 125 ]
126 126
127 self.__checkers = collections.defaultdict(list) 127 self.__checkers = collections.defaultdict(list)
128 for key, checkers in self.__checkersWithCodes.items(): 128 for key, checkers in self.__checkersWithCodes.items():
129 for checker, codes in checkers: 129 for checker, codes in checkers:
333 @type list of ast.AST 333 @type list of ast.AST
334 """ 334 """
335 if isinstance(node, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)): 335 if isinstance(node, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):
336 name = node.name 336 name = node.name
337 if self.__isNameToBeAvoided(name): 337 if self.__isNameToBeAvoided(name):
338 self.__error(node, "N831") 338 self.__error(node, "N-831")
339 339
340 elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): 340 elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
341 argNames = self.__getArgNames(node) 341 argNames = self.__getArgNames(node)
342 for arg in argNames: 342 for arg in argNames:
343 if self.__isNameToBeAvoided(arg): 343 if self.__isNameToBeAvoided(arg):
344 self.__error(node, "N831") 344 self.__error(node, "N-831")
345 345
346 elif isinstance(node, (ast.Assign, ast.NamedExpr, ast.AnnAssign)): 346 elif isinstance(node, (ast.Assign, ast.NamedExpr, ast.AnnAssign)):
347 if isinstance(node, ast.Assign): 347 if isinstance(node, ast.Assign):
348 targets = node.targets 348 targets = node.targets
349 else: 349 else:
350 targets = [node.target] 350 targets = [node.target]
351 for target in targets: 351 for target in targets:
352 if isinstance(target, ast.Name): 352 if isinstance(target, ast.Name):
353 name = target.id 353 name = target.id
354 if bool(name) and self.__isNameToBeAvoided(name): 354 if bool(name) and self.__isNameToBeAvoided(name):
355 self.__error(node, "N831") 355 self.__error(node, "N-831")
356 356
357 elif isinstance(target, (ast.Tuple, ast.List)): 357 elif isinstance(target, (ast.Tuple, ast.List)):
358 for element in target.elts: 358 for element in target.elts:
359 if isinstance(element, ast.Name): 359 if isinstance(element, ast.Name):
360 name = element.id 360 name = element.id
361 if bool(name) and self.__isNameToBeAvoided(name): 361 if bool(name) and self.__isNameToBeAvoided(name):
362 self.__error(node, "N831") 362 self.__error(node, "N-831")
363 363
364 def __getClassdef(self, name, parents): 364 def __getClassdef(self, name, parents):
365 """ 365 """
366 Private method to extract the class definition. 366 Private method to extract the class definition.
367 367
420 @type list of ast.AST 420 @type list of ast.AST
421 """ 421 """
422 name = node.name 422 name = node.name
423 strippedName = name.strip("_") 423 strippedName = name.strip("_")
424 if not strippedName[:1].isupper() or "_" in strippedName: 424 if not strippedName[:1].isupper() or "_" in strippedName:
425 self.__error(node, "N801") 425 self.__error(node, "N-801")
426 426
427 superClasses = self.__superClassNames(name, parents) 427 superClasses = self.__superClassNames(name, parents)
428 if "Exception" in superClasses and not name.endswith("Error"): 428 if "Exception" in superClasses and not name.endswith("Error"):
429 self.__error(node, "N818") 429 self.__error(node, "N-818")
430 430
431 def __checkFunctionName(self, node, _parents): 431 def __checkFunctionName(self, node, _parents):
432 """ 432 """
433 Private class to check the given node for function name 433 Private class to check the given node for function name
434 conventions (N802, N809). 434 conventions (N802, N809).
449 449
450 if name in ("__dir__", "__getattr__"): 450 if name in ("__dir__", "__getattr__"):
451 return 451 return
452 452
453 if name.lower() != name: 453 if name.lower() != name:
454 self.__error(node, "N802") 454 self.__error(node, "N-802")
455 if functionType == "function" and name[:2] == "__" and name[-2:] == "__": 455 if functionType == "function" and name[:2] == "__" and name[-2:] == "__":
456 self.__error(node, "N809") 456 self.__error(node, "N-809")
457 457
458 def __checkFunctionArgumentNames(self, node, _parents): 458 def __checkFunctionArgumentNames(self, node, _parents):
459 """ 459 """
460 Private class to check the argument names of functions 460 Private class to check the argument names of functions
461 (N803, N804, N805, N806). 461 (N803, N804, N805, N806).
470 @type list of ast.AST 470 @type list of ast.AST
471 """ 471 """
472 if node.args.kwarg is not None: 472 if node.args.kwarg is not None:
473 kwarg = node.args.kwarg.arg 473 kwarg = node.args.kwarg.arg
474 if kwarg.lower() != kwarg: 474 if kwarg.lower() != kwarg:
475 self.__error(node, "N803") 475 self.__error(node, "N-803")
476 476
477 elif node.args.vararg is not None: 477 elif node.args.vararg is not None:
478 vararg = node.args.vararg.arg 478 vararg = node.args.vararg.arg
479 if vararg.lower() != vararg: 479 if vararg.lower() != vararg:
480 self.__error(node, "N803") 480 self.__error(node, "N-803")
481 481
482 else: 482 else:
483 argNames = self.__getArgNames(node) 483 argNames = self.__getArgNames(node)
484 functionType = getattr(node, "function_type", "function") 484 functionType = getattr(node, "function_type", "function")
485 485
486 if not argNames: 486 if not argNames:
487 if functionType == "method": 487 if functionType == "method":
488 self.__error(node, "N805") 488 self.__error(node, "N-805")
489 elif functionType == "classmethod": 489 elif functionType == "classmethod":
490 self.__error(node, "N804") 490 self.__error(node, "N-804")
491 491
492 elif functionType == "method" and argNames[0] != "self": 492 elif functionType == "method" and argNames[0] != "self":
493 self.__error(node, "N805") 493 self.__error(node, "N-805")
494 elif functionType == "classmethod" and argNames[0] != "cls": 494 elif functionType == "classmethod" and argNames[0] != "cls":
495 self.__error(node, "N804") 495 self.__error(node, "N-804")
496 elif functionType == "staticmethod" and argNames[0] in ("cls", "self"): 496 elif functionType == "staticmethod" and argNames[0] in ("cls", "self"):
497 self.__error(node, "N806") 497 self.__error(node, "N-806")
498 for arg in argNames: 498 for arg in argNames:
499 if arg.lower() != arg: 499 if arg.lower() != arg:
500 self.__error(node, "N803") 500 self.__error(node, "N-803")
501 break 501 break
502 502
503 def __checkVariableNames(self, node, parents): 503 def __checkVariableNames(self, node, parents):
504 """ 504 """
505 Private method to check variable names in function, class and global scope 505 Private method to check variable names in function, class and global scope
605 @type str 605 @type str
606 @return error code or None 606 @return error code or None
607 @rtype str or None 607 @rtype str or None
608 """ 608 """
609 if self.__isMixedCase(name): 609 if self.__isMixedCase(name):
610 return "N823" 610 return "N-823"
611 611
612 return None 612 return None
613 613
614 def __classVariableCheck(self, name): 614 def __classVariableCheck(self, name):
615 """ 615 """
619 @type str 619 @type str
620 @return error code or None 620 @return error code or None
621 @rtype str or None 621 @rtype str or None
622 """ 622 """
623 if self.__isMixedCase(name): 623 if self.__isMixedCase(name):
624 return "N822" 624 return "N-822"
625 625
626 return None 626 return None
627 627
628 def __functionVariableCheck(self, func, varName): 628 def __functionVariableCheck(self, func, varName):
629 """ 629 """
635 @type str 635 @type str
636 @return error code or None 636 @return error code or None
637 @rtype str or None 637 @rtype str or None
638 """ 638 """
639 if varName not in func.global_names and varName.lower() != varName: 639 if varName not in func.global_names and varName.lower() != varName:
640 return "N821" 640 return "N-821"
641 641
642 return None 642 return None
643 643
644 def __isNamedTupel(self, nodeValue): 644 def __isNamedTupel(self, nodeValue):
645 """ 645 """
673 @type list of ast.AST 673 @type list of ast.AST
674 """ 674 """
675 if self.__filename: 675 if self.__filename:
676 moduleName = os.path.splitext(os.path.basename(self.__filename))[0] 676 moduleName = os.path.splitext(os.path.basename(self.__filename))[0]
677 if moduleName.lower() != moduleName: 677 if moduleName.lower() != moduleName:
678 self.__error(node, "N807") 678 self.__error(node, "N-807")
679 679
680 if moduleName == "__init__": 680 if moduleName == "__init__":
681 # we got a package 681 # we got a package
682 packageName = os.path.split(os.path.dirname(self.__filename))[1] 682 packageName = os.path.split(os.path.dirname(self.__filename))[1]
683 if packageName.lower() != packageName: 683 if packageName.lower() != packageName:
684 self.__error(node, "N808") 684 self.__error(node, "N-808")
685 685
686 def __checkImportAs(self, node, _parents): 686 def __checkImportAs(self, node, _parents):
687 """ 687 """
688 Private method to check that imports don't change the 688 Private method to check that imports don't change the
689 naming convention (N811, N812, N813, N814, N815). 689 naming convention (N811, N812, N813, N814, N815).
699 continue 699 continue
700 700
701 originalName = name.name 701 originalName = name.name
702 if originalName.isupper(): 702 if originalName.isupper():
703 if not asname.isupper(): 703 if not asname.isupper():
704 self.__error(node, "N811") 704 self.__error(node, "N-811")
705 elif originalName.islower(): 705 elif originalName.islower():
706 if asname.lower() != asname: 706 if asname.lower() != asname:
707 self.__error(node, "N812") 707 self.__error(node, "N-812")
708 elif asname.islower(): 708 elif asname.islower():
709 self.__error(node, "N813") 709 self.__error(node, "N-813")
710 elif asname.isupper(): 710 elif asname.isupper():
711 if "".join(filter(str.isupper, originalName)) == asname: 711 if "".join(filter(str.isupper, originalName)) == asname:
712 self.__error(node, "N815") 712 self.__error(node, "N-815")
713 else: 713 else:
714 self.__error(node, "N814") 714 self.__error(node, "N-814")

eric ide

mercurial