UtilitiesPython2/Pep257CheckerPy2.py

changeset 2946
987b6368dbae
parent 2934
82811ddafea2
child 2948
ea04689ee599
equal deleted inserted replaced
2945:0005e6314aea 2946:987b6368dbae
109 "D131", "D132", "D133", "D134", 109 "D131", "D132", "D133", "D134",
110 "D141", "D142", "D143", "D144", "D145", 110 "D141", "D142", "D143", "D144", "D145",
111 111
112 "D203", "D205", 112 "D203", "D205",
113 "D221", 113 "D221",
114 "D231", "D234", "D235", "D236", "D237", "D238", 114 "D231", "D234", "D235", "D236", "D237", "D238", "D239",
115 "D242", "D243", "D244", "D245", "D246", "D247", 115 "D242", "D243", "D244", "D245", "D246", "D247",
116 ] 116 ]
117 117
118 def __init__(self, source, filename, select, ignore, expected, repeat, 118 def __init__(self, source, filename, select, ignore, expected, repeat,
119 maxLineLength=79, docType="pep257"): 119 maxLineLength=79, docType="pep257"):
208 ], 208 ],
209 "defDocstring": [ 209 "defDocstring": [
210 (self.__checkFunctionDocstring, ("D102", "D203")), 210 (self.__checkFunctionDocstring, ("D102", "D203")),
211 (self.__checkImperativeMood, ("D132",)), 211 (self.__checkImperativeMood, ("D132",)),
212 (self.__checkNoSignature, ("D133",)), 212 (self.__checkNoSignature, ("D133",)),
213 (self.__checkEricReturn, ("D234",)), 213 (self.__checkEricReturn, ("D234", "D235")),
214 (self.__checkEricFunctionArguments, 214 (self.__checkEricFunctionArguments,
215 ("D235", "D236", "D237", "D238")), 215 ("D236", "D237", "D238", "D239")),
216 (self.__checkEricNoBlankBeforeAndAfterClassOrFunction, 216 (self.__checkEricNoBlankBeforeAndAfterClassOrFunction,
217 ("D244", "D245")), 217 ("D244", "D245")),
218 ], 218 ],
219 "docstring": [ 219 "docstring": [
220 (self.__checkTripleDoubleQuotes, ("D111",)), 220 (self.__checkTripleDoubleQuotes, ("D111",)),
221 (self.__checkBackslashes, ("D112",)), 221 (self.__checkBackslashes, ("D112",)),
222 (self.__checkUnicode, ("D113",)), 222 (self.__checkUnicode, ("D113",)),
223 (self.__checkEricOneLiner, ("D221",)),
224 (self.__checkIndent, ("D122",)), 223 (self.__checkIndent, ("D122",)),
225 (self.__checkEricEndsWithPeriod, ("D231",)), 224 (self.__checkEricEndsWithPeriod, ("D231",)),
226 (self.__checkEricBlankAfterSummary, ("D246",)), 225 (self.__checkEricBlankAfterSummary, ("D246",)),
227 (self.__checkEricNBlankAfterLastParagraph, ("D247",)), 226 (self.__checkEricNBlankAfterLastParagraph, ("D247",)),
227 (self.__checkEricQuotesOnSeparateLines, ("D222", "D223"))
228 ], 228 ],
229 } 229 }
230 230
231 self.__checkers = {} 231 self.__checkers = {}
232 for key, checkers in checkersWithCodes.items(): 232 for key, checkers in checkersWithCodes.items():
890 890
891 while cti < len(contextLines) and \ 891 while cti < len(contextLines) and \
892 not contextLines[cti].strip().endswith(('"""', "'''")): 892 not contextLines[cti].strip().endswith(('"""', "'''")):
893 cti += 1 893 cti += 1
894 end = cti 894 end = cti
895 if cti == len(contextLines): 895 if cti >= len(contextLines) - 1:
896 return 896 return
897 897
898 if contextLines[start - 1].strip(): 898 if contextLines[start - 1].strip():
899 self.__error(docstringContext.start(), 0, "D142") 899 self.__error(docstringContext.start(), 0, "D142")
900 if contextLines[end + 1].strip(): 900 if contextLines[end + 1].strip():
942 942
943 ################################################################## 943 ##################################################################
944 ## Checking functionality below (eric specific ones) 944 ## Checking functionality below (eric specific ones)
945 ################################################################## 945 ##################################################################
946 946
947 def __checkEricOneLiner(self, docstringContext, context): 947 def __checkEricQuotesOnSeparateLines(self, docstringContext, context):
948 """ 948 """
949 Private method to check, that one-liner docstrings are on 949 Private method to check, that leading and trailing quotes are on
950 three lines (quotes, docstring, quotes). 950 a line by themselves.
951 951
952 @param docstringContext docstring context (Pep257Context) 952 @param docstringContext docstring context (Pep257Context)
953 @param context context of the docstring (Pep257Context) 953 @param context context of the docstring (Pep257Context)
954 """ 954 """
955 if docstringContext is None: 955 if docstringContext is None:
956 return 956 return
957 957
958 lines = docstringContext.source() 958 lines = docstringContext.source()
959 if len(lines) != 3: 959 if lines[0].strip().strip('ru"'):
960 nonEmptyLines = [l for l in lines if l.strip().strip('\'"')] 960 self.__error(docstringContext.start(), 0, "D221")
961 if len(nonEmptyLines) == 1: 961 if lines[-1].strip().strip('"'):
962 self.__error(docstringContext.start(), 0, "D221") 962 self.__error(docstringContext.end(), 0, "D222")
963 963
964 def __checkEricEndsWithPeriod(self, docstringContext, context): 964 def __checkEricEndsWithPeriod(self, docstringContext, context):
965 """ 965 """
966 Private method to check, that docstring summaries end with a period. 966 Private method to check, that docstring summaries end with a period.
967 967
970 """ 970 """
971 if docstringContext is None: 971 if docstringContext is None:
972 return 972 return
973 973
974 summaryLines, lineNumber = self.__getSummaryLines(docstringContext) 974 summaryLines, lineNumber = self.__getSummaryLines(docstringContext)
975 if summaryLines[-1].lstrip().startswith("@"):
976 summaryLines.pop(-1)
975 summary = " ".join([s.strip() for s in summaryLines if s]) 977 summary = " ".join([s.strip() for s in summaryLines if s])
976 if not summary.endswith(".") and \ 978 if not summary.endswith(".") and \
977 not summary.split(None, 1)[0].lower() == "constructor": 979 not summary.split(None, 1)[0].lower() == "constructor":
978 self.__error( 980 self.__error(
979 docstringContext.start() + lineNumber + len(summaryLines) - 1, 981 docstringContext.start() + lineNumber + len(summaryLines) - 1,
980 0, "D231") 982 0, "D231")
981 983
982 def __checkEricReturn(self, docstringContext, context): 984 def __checkEricReturn(self, docstringContext, context):
983 """ 985 """
984 Private method to check, that docstrings contain an @return line. 986 Private method to check, that docstrings contain an @return line
987 if they return anything and don't otherwise.
985 988
986 @param docstringContext docstring context (Pep257Context) 989 @param docstringContext docstring context (Pep257Context)
987 @param context context of the docstring (Pep257Context) 990 @param context context of the docstring (Pep257Context)
988 """ 991 """
989 if docstringContext is None or self.__isScript: 992 if docstringContext is None or self.__isScript:
990 return 993 return
991 994
995 tokens = list(
996 tokenize.generate_tokens(StringIO(context.ssource()).readline))
997 return_ = [tokens[i + 1][0] for i, token in enumerate(tokens)
998 if token[1] == "return"]
992 if "@return" not in docstringContext.ssource(): 999 if "@return" not in docstringContext.ssource():
993 tokens = list(
994 tokenize.generate_tokens(StringIO(context.ssource()).readline))
995 return_ = [tokens[i + 1][0] for i, token in enumerate(tokens)
996 if token[1] == "return"]
997 if (set(return_) - 1000 if (set(return_) -
998 set([tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE]) != 1001 set([tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE]) !=
999 set([])): 1002 set([])):
1000 self.__error(docstringContext.end(), 0, "D234") 1003 self.__error(docstringContext.end(), 0, "D234")
1004 else:
1005 if (set(return_) -
1006 set([tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE]) ==
1007 set([])):
1008 self.__error(docstringContext.end(), 0, "D235")
1001 1009
1002 def __checkEricFunctionArguments(self, docstringContext, context): 1010 def __checkEricFunctionArguments(self, docstringContext, context):
1003 """ 1011 """
1004 Private method to check, that docstrings contain an @param line 1012 Private method to check, that docstrings contain an @param line
1005 for each argument. 1013 for each argument.
1024 argNames.remove("cls") 1032 argNames.remove("cls")
1025 1033
1026 docstring = docstringContext.ssource() 1034 docstring = docstringContext.ssource()
1027 if (docstring.count("@param") + docstring.count("@keyparam") < 1035 if (docstring.count("@param") + docstring.count("@keyparam") <
1028 len(argNames + kwNames)): 1036 len(argNames + kwNames)):
1029 self.__error(docstringContext.end(), 0, "D235") 1037 self.__error(docstringContext.end(), 0, "D236")
1030 elif (docstring.count("@param") + docstring.count("@keyparam") > 1038 elif (docstring.count("@param") + docstring.count("@keyparam") >
1031 len(argNames + kwNames)): 1039 len(argNames + kwNames)):
1032 self.__error(docstringContext.end(), 0, "D236") 1040 self.__error(docstringContext.end(), 0, "D237")
1033 else: 1041 else:
1034 # extract @param and @keyparam from docstring 1042 # extract @param and @keyparam from docstring
1035 args = [] 1043 args = []
1036 kwargs = [] 1044 kwargs = []
1037 for line in docstringContext.source(): 1045 for line in docstringContext.source():
1038 if line.strip().startswith(("@param", "@keyparam")): 1046 if line.strip().startswith(("@param", "@keyparam")):
1039 at, name, _ = line.strip().split(None, 2) 1047 at, name = line.strip().split(None, 2)[:2]
1040 if at == "@keyparam": 1048 if at == "@keyparam":
1041 kwargs.append(name) 1049 kwargs.append(name)
1042 args.append(name) 1050 args.append(name)
1043 1051
1044 # do the checks 1052 # do the checks
1045 for name in kwNames: 1053 for name in kwNames:
1046 if name not in kwargs: 1054 if name not in kwargs:
1047 self.__error(docstringContext.end(), 0, "D237") 1055 self.__error(docstringContext.end(), 0, "D238")
1048 return 1056 return
1049 if argNames + kwNames != args: 1057 if argNames + kwNames != args:
1050 self.__error(docstringContext.end(), 0, "D238") 1058 self.__error(docstringContext.end(), 0, "D239")
1051 1059
1052 def __checkEricBlankAfterSummary(self, docstringContext, context): 1060 def __checkEricBlankAfterSummary(self, docstringContext, context):
1053 """ 1061 """
1054 Private method to check, that docstring summaries are followed 1062 Private method to check, that docstring summaries are followed
1055 by a blank line. 1063 by a blank line.
1064 if len(docstrings) <= 3: 1072 if len(docstrings) <= 3:
1065 # correct/invalid one-liner 1073 # correct/invalid one-liner
1066 return 1074 return
1067 1075
1068 summaryLines, lineNumber = self.__getSummaryLines(docstringContext) 1076 summaryLines, lineNumber = self.__getSummaryLines(docstringContext)
1069 if len(docstrings) > lineNumber + len(summaryLines) - 1: 1077 if len(docstrings) - 2 > lineNumber + len(summaryLines) - 1:
1070 if docstrings[lineNumber + len(summaryLines)].strip(): 1078 if docstrings[lineNumber + len(summaryLines)].strip():
1071 self.__error(docstringContext.start() + lineNumber, 0, "D246") 1079 self.__error(docstringContext.start() + lineNumber, 0, "D246")
1072 1080
1073 def __checkEricNoBlankBeforeAndAfterClassOrFunction( 1081 def __checkEricNoBlankBeforeAndAfterClassOrFunction(
1074 self, docstringContext, context): 1082 self, docstringContext, context):
1100 1108
1101 while cti < len(contextLines) and \ 1109 while cti < len(contextLines) and \
1102 not contextLines[cti].strip().endswith(('"""', "'''")): 1110 not contextLines[cti].strip().endswith(('"""', "'''")):
1103 cti += 1 1111 cti += 1
1104 end = cti 1112 end = cti
1105 if cti == len(contextLines): 1113 if cti >= len(contextLines) - 1:
1106 return 1114 return
1107 1115
1108 if isClassContext: 1116 if isClassContext:
1109 if not contextLines[start - 1].strip(): 1117 if not contextLines[start - 1].strip():
1110 self.__error(docstringContext.start(), 0, "D242") 1118 self.__error(docstringContext.start(), 0, "D242")

eric ide

mercurial