Plugins/CheckerPlugins/Pep8/Pep257Checker.py

changeset 2949
e8f41288a688
parent 2948
ea04689ee599
child 2952
94fc661a54a2
diff -r ea04689ee599 -r e8f41288a688 Plugins/CheckerPlugins/Pep8/Pep257Checker.py
--- a/Plugins/CheckerPlugins/Pep8/Pep257Checker.py	Sat Sep 28 16:46:46 2013 +0200
+++ b/Plugins/CheckerPlugins/Pep8/Pep257Checker.py	Sat Sep 28 17:24:00 2013 +0200
@@ -115,6 +115,7 @@
         "D221", "D222",
         "D231", "D234", "D235", "D236", "D237", "D238", "D239",
         "D242", "D243", "D244", "D245", "D246", "D247",
+        "D250", "D251",
     ]
     
     Messages = {
@@ -182,10 +183,12 @@
             "Pep257Checker", "docstring summary does not end with a period"),
         "D234": QT_TRANSLATE_NOOP(
             "Pep257Checker",
-            "docstring does not contain a @return line but returns something"),
+            "docstring does not contain a @return line but function/method"
+            " returns something"),
         "D235": QT_TRANSLATE_NOOP(
             "Pep257Checker",
-            "docstring contains a @return line but doesn't return anything"),
+            "docstring contains a @return line but function/method doesn't"
+            " return anything"),
         "D236": QT_TRANSLATE_NOOP(
             "Pep257Checker",
             "docstring does not contain enough @param/@keyparam lines"),
@@ -214,6 +217,14 @@
         "D247": QT_TRANSLATE_NOOP(
             "Pep257Checker",
             "last paragraph of docstring is followed by a blank line"),
+        "D250": QT_TRANSLATE_NOOP(
+            "Pep257Checker",
+            "docstring does not contain a @exception line but function/method"
+            " raises an exception"),
+        "D251": QT_TRANSLATE_NOOP(
+            "Pep257Checker",
+            "docstring contains a @exception line but function/method doesn't"
+            " raise an exception"),
     }
     
     def __init__(self, source, filename, select, ignore, expected, repeat,
@@ -316,6 +327,7 @@
                      ("D236", "D237", "D238", "D239")),
                     (self.__checkEricNoBlankBeforeAndAfterClassOrFunction,
                      ("D244", "D245")),
+                    (self.__checkEricException, ("D250", "D251")),
                 ],
                 "docstring": [
                     (self.__checkTripleDoubleQuotes, ("D111",)),
@@ -373,8 +385,8 @@
             if code in Pep257Checker.Codes:
                 text = self.getMessage(code, *args)
             else:
-                text = code + " " + QCoreApplication.translate("Pep257Checker",
-                    "no message for this code defined")
+                text = code + " " + QCoreApplication.translate(
+                    "Pep257Checker", "no message for this code defined")
             # record the issue with one based line number
             self.errors.append((self.__filename, lineNumber + 1, offset, text))
     
@@ -462,13 +474,13 @@
         lines = docstringContext.source()
         
         line0 = (lines[0]
-                .replace('r"""', "", 1)
-                .replace('u"""', "", 1)
-                .replace('"""', "")
-                .replace("r'''", "", 1)
-                .replace("u'''", "", 1)
-                .replace("'''", "")
-                .strip())
+                 .replace('r"""', "", 1)
+                 .replace('u"""', "", 1)
+                 .replace('"""', "")
+                 .replace("r'''", "", 1)
+                 .replace("u'''", "", 1)
+                 .replace("'''", "")
+                 .strip())
         if len(lines) > 1:
             line1 = lines[1].strip().replace('"""', "").replace("'''", "")
         else:
@@ -570,6 +582,7 @@
         Private method to extract a docstring given `def` or `class` source.
         
         @param context context data to get the docstring from (Pep257Context)
+        @param what string denoting what is being parsed (string)
         @return context of extracted docstring (Pep257Context)
         """
         moduleDocstring = self.__parseModuleDocstring(context.source())
@@ -1107,7 +1120,7 @@
     
     def __checkEricReturn(self, docstringContext, context):
         """
-        Private method to check, that docstrings contain an @return line
+        Private method to check, that docstrings contain an @return line
         if they return anything and don't otherwise.
         
         @param docstringContext docstring context (Pep257Context)
@@ -1133,8 +1146,8 @@
     
     def __checkEricFunctionArguments(self, docstringContext, context):
         """
-        Private method to check, that docstrings contain an @param line
-        for each argument.
+        Private method to check, that docstrings contain an @param and/or
+        @keyparam line for each argument.
         
         @param docstringContext docstring context (Pep257Context)
         @param context context of the docstring (Pep257Context)
@@ -1156,10 +1169,10 @@
                 argNames.remove("cls")
             
             docstring = docstringContext.ssource()
-            if (docstring.count("@param") + docstring.count("@keyparam") < 
+            if (docstring.count("@param") + docstring.count("@keyparam") <
                     len(argNames + kwNames)):
                 self.__error(docstringContext.end(), 0, "D236")
-            elif (docstring.count("@param") + docstring.count("@keyparam") > 
+            elif (docstring.count("@param") + docstring.count("@keyparam") >
                     len(argNames + kwNames)):
                 self.__error(docstringContext.end(), 0, "D237")
             else:
@@ -1181,6 +1194,34 @@
                 if argNames + kwNames != args:
                     self.__error(docstringContext.end(), 0, "D239")
     
+    def __checkEricException(self, docstringContext, context):
+        """
+        Private method to check, that docstrings contain an &#64;exception line
+        if they raise an exception and don't otherwise.
+        
+        @param docstringContext docstring context (Pep257Context)
+        @param context context of the docstring (Pep257Context)
+        """
+        if docstringContext is None or self.__isScript:
+            return
+        
+        tokens = list(
+            tokenize.generate_tokens(StringIO(context.ssource()).readline))
+        exception = [tokens[i + 1][0] for i,  token in enumerate(tokens)
+                     if token[1] == "raise"]
+        if "@exception" not in docstringContext.ssource() and \
+                "@throws" not in docstringContext.ssource() and \
+                "@raise" not in docstringContext.ssource():
+            if (set(exception) -
+                    set([tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE]) !=
+                    set([])):
+                self.__error(docstringContext.end(), 0, "D250")
+        else:
+            if (set(exception) -
+                    set([tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE]) ==
+                    set([])):
+                self.__error(docstringContext.end(), 0, "D251")
+    
     def __checkEricBlankAfterSummary(self, docstringContext, context):
         """
         Private method to check, that docstring summaries are followed

eric ide

mercurial