Source code documentation generator, doc checker: added support for @yield and @ytype.

Sat, 16 Jan 2021 16:32:01 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 16 Jan 2021 16:32:01 +0100
changeset 7987
e8eb8370ea94
parent 7986
2971d5d19951
child 7988
c4c17121eff8

Source code documentation generator, doc checker: added support for @yield and @ytype.

docs/changelog file | annotate | diff | comparison | revisions
eric6/DocumentationTools/ModuleDocumentor.py file | annotate | diff | comparison | revisions
eric6/DocumentationTools/TemplatesListsStyle.py file | annotate | diff | comparison | revisions
eric6/DocumentationTools/TemplatesListsStyleCSS.py file | annotate | diff | comparison | revisions
eric6/Plugins/CheckerPlugins/CodeStyleChecker/DocStyle/DocStyleChecker.py file | annotate | diff | comparison | revisions
eric6/Plugins/CheckerPlugins/CodeStyleChecker/DocStyle/translations.py file | annotate | diff | comparison | revisions
--- a/docs/changelog	Fri Jan 15 19:49:36 2021 +0100
+++ b/docs/changelog	Sat Jan 16 16:32:01 2021 +0100
@@ -7,6 +7,7 @@
   -- added support for PySide6
 - Code Style Checker
   -- added a commented code whitelist patterns to the Miscellaneous Checker
+  -- added support for the '@yield' and '@ytype' tags
 - Debugger
   -- added support for debugging multiprocess scripts using these methods
      --- QProcess.start(), QProcess.startDetached()
@@ -20,6 +21,8 @@
   -- added support for the "Continue Until" action execution code until the
      current cursor line (if it is greater than the current line) or until
      returning from the current frame
+- Documentation Generator
+  -- added support for the '@yield' and '@ytype' tags to document generators
 - Editor
   -- added code to enclose the current selection by entering ", ' or a bracket
      ( (, ), [, ], {, }, <, > ) characters
--- a/eric6/DocumentationTools/ModuleDocumentor.py	Fri Jan 15 19:49:36 2021 +0100
+++ b/eric6/DocumentationTools/ModuleDocumentor.py	Sat Jan 16 16:32:01 2021 +0100
@@ -105,6 +105,9 @@
             self.returnsTemplate = TemplatesListsStyleCSS.returnsTemplate
             self.returnTypesTemplate = (
                 TemplatesListsStyleCSS.returnTypesTemplate)
+            self.yieldsTemplate = TemplatesListsStyleCSS.yieldsTemplate
+            self.yieldTypesTemplate = (
+                TemplatesListsStyleCSS.yieldTypesTemplate)
             self.exceptionsListTemplate = (
                 TemplatesListsStyleCSS.exceptionsListTemplate)
             self.exceptionsListEntryTemplate = (
@@ -170,6 +173,10 @@
                 TemplatesListsStyle.returnsTemplate.format(**colors))
             self.returnTypesTemplate = (
                 TemplatesListsStyle.returnTypesTemplate.format(**colors))
+            self.yieldsTemplate = (
+                TemplatesListsStyle.yieldsTemplate.format(**colors))
+            self.yieldTypesTemplate = (
+                TemplatesListsStyle.yieldTypesTemplate.format(**colors))
             self.exceptionsListTemplate = (
                 TemplatesListsStyle.exceptionsListTemplate.format(**colors))
             self.exceptionsListEntryTemplate = (
@@ -938,7 +945,7 @@
         @param descr The contents of the documentation string. (string)
         @exception TagError A tag doesn't have the correct number
             of arguments.
-        @return The formated contents of the documentation string. (string)
+        @return The formatted contents of the documentation string. (string)
         """
         if not descr:
             return ""
@@ -947,6 +954,8 @@
         paramList = []
         returns = []
         returnTypes = []
+        yields = []
+        yieldTypes = []
         exceptionDict = {}
         signalDict = {}
         eventDict = {}
@@ -1029,7 +1038,7 @@
                     parts = desc.split(None, 1)
                     if lastTag not in ["@return", "@ireturn"]:
                         raise TagError(
-                            "{0} line must be preceded by a return line\n"
+                            "{0} line must be preceded by a @return line\n"
                             .format(parts[0]))
                     inTagSection = True
                     lastTag = parts[0]
@@ -1038,6 +1047,28 @@
                             "Wrong format in {0} line.\n".format(parts[0]))
                     returnTypes = [parts[1]]
                     lastItem = returnTypes
+                elif desc.startswith("@yield"):
+                    inTagSection = True
+                    parts = desc.split(None, 1)
+                    lastTag = parts[0]
+                    if len(parts) < 2:
+                        raise TagError(
+                            "Wrong format in {0} line.\n".format(parts[0]))
+                    yields = [parts[1]]
+                    lastItem = yields
+                elif desc.startswith("@ytype"):
+                    parts = desc.split(None, 1)
+                    if lastTag != "@yield":
+                        raise TagError(
+                            "{0} line must be preceded by a @yield line\n"
+                            .format(parts[0]))
+                    inTagSection = True
+                    lastTag = parts[0]
+                    if len(parts) < 2:
+                        raise TagError(
+                            "Wrong format in {0} line.\n".format(parts[0]))
+                    yieldTypes = [parts[1]]
+                    lastItem = yieldTypes
                 elif desc.startswith(("@exception", "@throws", "@raise")):
                     inTagSection = True
                     parts = desc.split(None, 2)
@@ -1160,6 +1191,18 @@
         else:
             returnTypesSect = ""
         
+        if yields:
+            yieldSect = self.yieldsTemplate.format(
+                html_uencode('\n'.join(yields)))
+        else:
+            yieldSect = ""
+        
+        if yieldTypes:
+            yieldTypesSect = self.yieldTypesTemplate.format(
+                html_uencode('\n'.join(yieldTypes)))
+        else:
+            yieldTypesSect = ""
+        
         if exceptionDict:
             exceptionSect = self.exceptionsListTemplate.format(
                 **{'Exceptions': self.__genDescriptionListSection(
@@ -1206,11 +1249,11 @@
         else:
             seeSect = ''
         
-        return "{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}".format(
+        return "".join([
             deprecatedSect, description, parameterSect, returnSect,
-            returnTypesSect, exceptionSect, signalSect, eventSect,
-            authorInfoSect, seeSect, sinceInfoSect,
-        )
+            returnTypesSect, yieldSect, yieldTypesSect, exceptionSect,
+            signalSect, eventSect, authorInfoSect, seeSect, sinceInfoSect,
+        ])
     
     def getQtHelpKeywords(self):
         """
--- a/eric6/DocumentationTools/TemplatesListsStyle.py	Fri Jan 15 19:49:36 2021 +0100
+++ b/eric6/DocumentationTools/TemplatesListsStyle.py	Sat Jan 16 16:32:01 2021 +0100
@@ -182,7 +182,7 @@
 
 returnsTemplate = '''
 <dl>
-<dt>Returns:</dt>
+<dt>Return:</dt>
 <dd>
 {{0}}
 </dd>
@@ -196,6 +196,22 @@
 </dd>
 </dl>'''
 
+yieldsTemplate = '''
+<dl>
+<dt>Yield:</dt>
+<dd>
+{{0}}
+</dd>
+</dl>'''
+
+yieldTypesTemplate = '''
+<dl>
+<dt>Yield Type:</dt>
+<dd>
+{{0}}
+</dd>
+</dl>'''
+
 exceptionsListTemplate = '''
 <dl>
 {{Exceptions}}
--- a/eric6/DocumentationTools/TemplatesListsStyleCSS.py	Fri Jan 15 19:49:36 2021 +0100
+++ b/eric6/DocumentationTools/TemplatesListsStyleCSS.py	Sat Jan 16 16:32:01 2021 +0100
@@ -164,7 +164,7 @@
 
 returnsTemplate = '''
 <dl>
-<dt>Returns:</dt>
+<dt>Return:</dt>
 <dd>
 {0}
 </dd>
@@ -178,6 +178,22 @@
 </dd>
 </dl>'''
 
+yieldsTemplate = '''
+<dl>
+<dt>Yield:</dt>
+<dd>
+{0}
+</dd>
+</dl>'''
+
+yieldTypesTemplate = '''
+<dl>
+<dt>Yield Type:</dt>
+<dd>
+{0}
+</dd>
+</dl>'''
+
 exceptionsListTemplate = '''
 <dl>
 {Exceptions}
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/DocStyle/DocStyleChecker.py	Fri Jan 15 19:49:36 2021 +0100
+++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/DocStyle/DocStyleChecker.py	Sat Jan 16 16:32:01 2021 +0100
@@ -130,7 +130,8 @@
         
         "D203", "D205", "D206",
         "D221", "D222",
-        "D231", "D232", "D234", "D235", "D236", "D237", "D238", "D239",
+        "D231", "D232", "D234r", "D234y", "D235r", "D235y", "D236", "D237",
+        "D238", "D239",
         "D242", "D243", "D244", "D245", "D246", "D247",
         "D250", "D251", "D252", "D253",
         "D260", "D261", "D262", "D263",
@@ -232,7 +233,8 @@
                     (self.__checkFunctionDocstring, ("D102", "D203")),
                     (self.__checkImperativeMood, ("D132",)),
                     (self.__checkNoSignature, ("D133",)),
-                    (self.__checkEricReturn, ("D234", "D235")),
+                    (self.__checkEricReturn, ("D234r", "D235r")),
+                    (self.__checkEricYield, ("D234y", "D235y")),
                     (self.__checkEricFunctionArguments,
                      ("D236", "D237", "D238", "D239")),
                     (self.__checkEricNoBlankBeforeAndAfterClassOrFunction,
@@ -1069,17 +1071,43 @@
         tokens = list(
             tokenize.generate_tokens(StringIO(context.ssource()).readline))
         return_ = [tokens[i + 1][0] for i, token in enumerate(tokens)
-                   if token[1] in ("return", "yield")]
+                   if token[1] == "return"]
         if "@return" not in docstringContext.ssource():
             if (set(return_) -
                     {tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE} !=
                     set()):
-                self.__error(docstringContext.end(), 0, "D234")
+                self.__error(docstringContext.end(), 0, "D234r")
         else:
             if (set(return_) -
                     {tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE} ==
                     set()):
-                self.__error(docstringContext.end(), 0, "D235")
+                self.__error(docstringContext.end(), 0, "D235r")
+    
+    def __checkEricYield(self, docstringContext, context):
+        """
+        Private method to check, that docstrings contain an &#64;yield line
+        if they return anything and don't otherwise.
+        
+        @param docstringContext docstring context (DocStyleContext)
+        @param context context of the docstring (DocStyleContext)
+        """
+        if docstringContext is None:
+            return
+        
+        tokens = list(
+            tokenize.generate_tokens(StringIO(context.ssource()).readline))
+        yield_ = [tokens[i + 1][0] for i, token in enumerate(tokens)
+                  if token[1] == "yield"]
+        if "@yield" not in docstringContext.ssource():
+            if (set(yield_) -
+                    {tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE} !=
+                    set()):
+                self.__error(docstringContext.end(), 0, "D234y")
+        else:
+            if (set(yield_) -
+                    {tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE} ==
+                    set()):
+                self.__error(docstringContext.end(), 0, "D235y")
     
     def __checkEricFunctionArguments(self, docstringContext, context):
         """
--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/DocStyle/translations.py	Fri Jan 15 19:49:36 2021 +0100
+++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/DocStyle/translations.py	Sat Jan 16 16:32:01 2021 +0100
@@ -84,14 +84,22 @@
         "DocStyleChecker", "docstring summary does not end with a period"),
     "D232": QCoreApplication.translate(
         "DocStyleChecker", "docstring summary does not start with '{0}'"),
-    "D234": QCoreApplication.translate(
+    "D234r": QCoreApplication.translate(
         "DocStyleChecker",
         "docstring does not contain a @return line but function/method"
         " returns something"),
-    "D235": QCoreApplication.translate(
+    "D235r": QCoreApplication.translate(
         "DocStyleChecker",
         "docstring contains a @return line but function/method doesn't"
         " return anything"),
+    "D234y": QCoreApplication.translate(
+        "DocStyleChecker",
+        "docstring does not contain a @yield line but function/method"
+        " yields something"),
+    "D235y": QCoreApplication.translate(
+        "DocStyleChecker",
+        "docstring contains a @yield line but function/method doesn't"
+        " yield anything"),
     "D236": QCoreApplication.translate(
         "DocStyleChecker",
         "docstring does not contain enough @param/@keyparam lines"),

eric ide

mercurial