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): |