120 |
120 |
121 "D203", "D205", |
121 "D203", "D205", |
122 "D221", "D222", |
122 "D221", "D222", |
123 "D231", "D232", "D234", "D235", "D236", "D237", "D238", "D239", |
123 "D231", "D232", "D234", "D235", "D236", "D237", "D238", "D239", |
124 "D242", "D243", "D244", "D245", "D246", "D247", |
124 "D242", "D243", "D244", "D245", "D246", "D247", |
125 "D250", "D251", |
125 "D250", "D251", "D252", "D253", |
|
126 "D260", "D261", "D262", "D263", |
126 |
127 |
127 "D901", |
128 "D901", |
128 ] |
129 ] |
129 |
130 |
130 def __init__(self, source, filename, select, ignore, expected, repeat, |
131 def __init__(self, source, filename, select, ignore, expected, repeat, |
226 (self.__checkEricReturn, ("D234", "D235")), |
228 (self.__checkEricReturn, ("D234", "D235")), |
227 (self.__checkEricFunctionArguments, |
229 (self.__checkEricFunctionArguments, |
228 ("D236", "D237", "D238", "D239")), |
230 ("D236", "D237", "D238", "D239")), |
229 (self.__checkEricNoBlankBeforeAndAfterClassOrFunction, |
231 (self.__checkEricNoBlankBeforeAndAfterClassOrFunction, |
230 ("D244", "D245")), |
232 ("D244", "D245")), |
231 (self.__checkEricException, ("D250", "D251")), |
233 (self.__checkEricException, |
|
234 ("D250", "D251", "D252", "D253")), |
232 ], |
235 ], |
233 "docstring": [ |
236 "docstring": [ |
234 (self.__checkTripleDoubleQuotes, ("D111",)), |
237 (self.__checkTripleDoubleQuotes, ("D111",)), |
235 (self.__checkBackslashes, ("D112",)), |
238 (self.__checkBackslashes, ("D112",)), |
236 (self.__checkUnicode, ("D113",)), |
239 (self.__checkUnicode, ("D113",)), |
1125 def __checkEricException(self, docstringContext, context): |
1128 def __checkEricException(self, docstringContext, context): |
1126 """ |
1129 """ |
1127 Private method to check, that docstrings contain an @exception line |
1130 Private method to check, that docstrings contain an @exception line |
1128 if they raise an exception and don't otherwise. |
1131 if they raise an exception and don't otherwise. |
1129 |
1132 |
|
1133 Note: This method also checks the raised and documented exceptions for |
|
1134 completeness (i.e. raised exceptions that are not documented or |
|
1135 documented exceptions that are not raised) |
|
1136 |
1130 @param docstringContext docstring context (DocStyleContext) |
1137 @param docstringContext docstring context (DocStyleContext) |
1131 @param context context of the docstring (DocStyleContext) |
1138 @param context context of the docstring (DocStyleContext) |
1132 """ |
1139 """ |
1133 if docstringContext is None: |
1140 if docstringContext is None: |
1134 return |
1141 return |
1135 |
1142 |
1136 tokens = list( |
1143 tokens = list( |
1137 tokenize.generate_tokens(StringIO(context.ssource()).readline)) |
1144 tokenize.generate_tokens(StringIO(context.ssource()).readline)) |
1138 exception = [tokens[i + 1][0] for i, token in enumerate(tokens) |
1145 exceptions = set() |
1139 if token[1] == "raise"] |
1146 raisedExceptions = set() |
|
1147 tokensLen = len(tokens) |
|
1148 for i, token in enumerate(tokens): |
|
1149 if token[1] == "raise": |
|
1150 exceptions.add(tokens[i + 1][0]) |
|
1151 if tokens[i + 1][0] == tokenize.NAME: |
|
1152 if tokensLen > (i + 2) and \ |
|
1153 tokens[i + 2][1] == ".": |
|
1154 raisedExceptions.add("{0}.{1}".format( |
|
1155 tokens[i + 1][1], tokens[i + 3][1])) |
|
1156 else: |
|
1157 raisedExceptions.add(tokens[i + 1][1]) |
|
1158 |
1140 if "@exception" not in docstringContext.ssource() and \ |
1159 if "@exception" not in docstringContext.ssource() and \ |
1141 "@throws" not in docstringContext.ssource() and \ |
1160 "@throws" not in docstringContext.ssource() and \ |
1142 "@raise" not in docstringContext.ssource(): |
1161 "@raise" not in docstringContext.ssource(): |
1143 if (set(exception) - |
1162 if (exceptions - |
1144 {tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE} != |
1163 {tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE} != |
1145 set()): |
1164 set()): |
1146 self.__error(docstringContext.end(), 0, "D250") |
1165 self.__error(docstringContext.end(), 0, "D250") |
1147 else: |
1166 else: |
1148 if (set(exception) - |
1167 if (exceptions - |
1149 {tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE} == |
1168 {tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE} == |
1150 set()): |
1169 set()): |
1151 self.__error(docstringContext.end(), 0, "D251") |
1170 self.__error(docstringContext.end(), 0, "D251") |
|
1171 else: |
|
1172 # step 1: extract documented exceptions |
|
1173 documentedExceptions = set() |
|
1174 for line in docstringContext.source(): |
|
1175 line = line.strip() |
|
1176 if line.startswith(("@exception", "@throws", "@raise")): |
|
1177 exceptionTokens = line.split(None, 2) |
|
1178 if len(exceptionTokens) >= 2: |
|
1179 documentedExceptions.add(exceptionTokens[1]) |
|
1180 |
|
1181 # step 2: report undocumented exceptions |
|
1182 for exception in raisedExceptions: |
|
1183 if exception not in documentedExceptions: |
|
1184 self.__error(docstringContext.end(), 0, "D252", |
|
1185 exception) |
|
1186 |
|
1187 # step 3: report undefined signals |
|
1188 for exception in documentedExceptions: |
|
1189 if exception not in raisedExceptions: |
|
1190 self.__error(docstringContext.end(), 0, "D253", |
|
1191 exception) |
|
1192 |
|
1193 def __checkEricSignal(self, docstringContext, context): |
|
1194 """ |
|
1195 Private method to check, that docstrings contain an @signal line |
|
1196 if they define signals and don't otherwise. |
|
1197 |
|
1198 Note: This method also checks the defined and documented signals for |
|
1199 completeness (i.e. defined signals that are not documented or |
|
1200 documented signals that are not defined) |
|
1201 |
|
1202 @param docstringContext docstring context (DocStyleContext) |
|
1203 @param context context of the docstring (DocStyleContext) |
|
1204 """ |
|
1205 if docstringContext is None: |
|
1206 return |
|
1207 |
|
1208 tokens = list( |
|
1209 tokenize.generate_tokens(StringIO(context.ssource()).readline)) |
|
1210 definedSignals = set() |
|
1211 for i, token in enumerate(tokens): |
|
1212 if token[1] in ("pyqtSignal", "Signal"): |
|
1213 if tokens[i - 1][1] == "." and tokens[i - 2][1] == "QtCore": |
|
1214 definedSignals.add(tokens[i - 4][1]) |
|
1215 elif tokens[i - 1][1] == "=": |
|
1216 definedSignals.add(tokens[i - 2][1]) |
|
1217 |
|
1218 if "@signal" not in docstringContext.ssource() and definedSignals: |
|
1219 self.__error(docstringContext.end(), 0, "D260") |
|
1220 elif "@signal" in docstringContext.ssource(): |
|
1221 if not definedSignals: |
|
1222 self.__error(docstringContext.end(), 0, "D261") |
|
1223 else: |
|
1224 # step 1: extract documented signals |
|
1225 documentedSignals = set() |
|
1226 for line in docstringContext.source(): |
|
1227 line = line.strip() |
|
1228 if line.startswith("@signal"): |
|
1229 signalTokens = line.split(None, 2) |
|
1230 if len(signalTokens) >= 2: |
|
1231 signal = signalTokens[1] |
|
1232 if "(" in signal: |
|
1233 signal = signal.split("(", 1)[0] |
|
1234 documentedSignals.add(signal) |
|
1235 |
|
1236 # step 2: report undocumented signals |
|
1237 for signal in definedSignals: |
|
1238 if signal not in documentedSignals: |
|
1239 self.__error(docstringContext.end(), 0, "D262", signal) |
|
1240 |
|
1241 # step 3: report undefined signals |
|
1242 for signal in documentedSignals: |
|
1243 if signal not in definedSignals: |
|
1244 self.__error(docstringContext.end(), 0, "D263", signal) |
1152 |
1245 |
1153 def __checkEricBlankAfterSummary(self, docstringContext, context): |
1246 def __checkEricBlankAfterSummary(self, docstringContext, context): |
1154 """ |
1247 """ |
1155 Private method to check, that docstring summaries are followed |
1248 Private method to check, that docstring summaries are followed |
1156 by a blank line. |
1249 by a blank line. |