Repository: spyder-ide/spyder

Issue:
Add sphinx/reStructuredText docstrings
Is there a reason why Sphinx/reStructuredText annotation is not added to Spyder auto-doc?
It's a little more simplistic than numpy/google.


Discussion:
I don't understand what you mean. Please be more explicit. 
under settings->editor->advanced you can set a docstring format that is automatically introduced. Here it would be useful to have the option of reStructuredText, e.g.

```Python
def func(p):
    """
    function description
    
    :param p: this does x
    :returns: 'hello'
    """
    return 'hello'
```

This format is a bit older, but also a bit more space saving and simpler
That feature was added by a volunteer contributor, and he decided to add support for Numpy and Google style docstrings only.

So it's up to you or the community to fill this gap if they want to see Sphinx/reStructuredText kind of auto-generated docstrings support.
@skjerns @ccordoba12 May I try to solve this issue?
of course!
> May I try to solve this issue?

Sure, please go ahead.
Thank you :smile:!

@skjerns There's something I want to check.
>This format is a bit older, but also a bit more space saving and simpler

The sphinx format of autodocsting of vscode is also long.
![Screenshot from 2020-02-02 05-50-24](https://user-images.githubusercontent.com/22970578/73598893-e6e32e00-4580-11ea-912b-d74cde71b5f6.png)

Is this the format you want?

Resolving patch:
diff --git a/spyder/plugins/editor/confpage.py b/spyder/plugins/editor/confpage.py
--- a/spyder/plugins/editor/confpage.py
+++ b/spyder/plugins/editor/confpage.py
@@ -243,7 +243,8 @@ def enable_tabwidth_spin(index):
         docstring_label.setWordWrap(True)
 
         docstring_combo_choices = ((_("Numpy"), 'Numpydoc'),
-                                   (_("Google"), 'Googledoc'),)
+                                   (_("Google"), 'Googledoc'),
+                                   (_("Sphinx"), 'Sphinxdoc'),)
         docstring_combo = self.create_combobox(
             "Type:",
             docstring_combo_choices,
diff --git a/spyder/plugins/editor/extensions/docstring.py b/spyder/plugins/editor/extensions/docstring.py
--- a/spyder/plugins/editor/extensions/docstring.py
+++ b/spyder/plugins/editor/extensions/docstring.py
@@ -262,6 +262,8 @@ def _generate_docstring(self, doc_type, quote):
                     docstring = self._generate_numpy_doc(func_info)
                 elif doc_type == 'Googledoc':
                     docstring = self._generate_google_doc(func_info)
+                elif doc_type == "Sphinxdoc":
+                    docstring = self._generate_sphinx_doc(func_info)
 
         return docstring
 
@@ -430,6 +432,71 @@ def _generate_google_doc(self, func_info):
 
         return google_doc
 
+    def _generate_sphinx_doc(self, func_info):
+        """Generate a docstring of sphinx type."""
+        sphinx_doc = ''
+
+        arg_names = func_info.arg_name_list
+        arg_types = func_info.arg_type_list
+        arg_values = func_info.arg_value_list
+
+        if len(arg_names) > 0 and arg_names[0] == 'self':
+            del arg_names[0]
+            del arg_types[0]
+            del arg_values[0]
+
+        indent1 = func_info.func_indent + self.code_editor.indent_chars
+
+        sphinx_doc += '\n{}\n'.format(indent1)
+
+        arg_text = ''
+        for arg_name, arg_type, arg_value in zip(arg_names, arg_types,
+                                                 arg_values):
+            arg_text += '{}:param {}: DESCRIPTION'.format(indent1, arg_name)
+
+            if arg_value:
+                arg_value = arg_value.replace(self.quote3, self.quote3_other)
+                arg_text += ', defaults to {}\n'.format(arg_value)
+            else:
+                arg_text += '\n'
+
+            arg_text += '{}:type {}: '.format(indent1, arg_name)
+
+            if arg_type:
+                arg_text += '{}'.format(arg_type)
+            else:
+                arg_text += 'TYPE'
+
+            if arg_value:
+                arg_text += ', optional'
+            arg_text += '\n'
+
+        sphinx_doc += arg_text
+
+        if func_info.raise_list:
+            for raise_type in func_info.raise_list:
+                sphinx_doc += '{}:raises {}: DESCRIPTION\n'.format(indent1,
+                                                                   raise_type)
+
+        if func_info.has_yield:
+            header = '{}:yield:'.format(indent1)
+        else:
+            header = '{}:return:'.format(indent1)
+
+        return_type_annotated = func_info.return_type_annotated
+        if return_type_annotated:
+            return_section = '{} DESCRIPTION\n'.format(header)
+            return_section += '{}:rtype: {}'.format(indent1,
+                                                    return_type_annotated)
+        else:
+            return_section = '{} DESCRIPTION\n'.format(header)
+            return_section += '{}:rtype: TYPE'.format(indent1)
+
+        sphinx_doc += return_section
+        sphinx_doc += '\n\n{}{}'.format(indent1, self.quote3)
+
+        return sphinx_doc
+
     @staticmethod
     def find_top_level_bracket_locations(string_toparse):
         """Get the locations of top-level brackets in a string."""


Test patch:
diff --git a/spyder/plugins/editor/extensions/tests/test_docstring.py b/spyder/plugins/editor/extensions/tests/test_docstring.py
--- a/spyder/plugins/editor/extensions/tests/test_docstring.py
+++ b/spyder/plugins/editor/extensions/tests/test_docstring.py
@@ -236,6 +236,63 @@ def test_get_function_body(editor_auto_docstring, text, indent, expected):
 
     """
     '''),
+        ('Sphinxdoc',
+         '''async def foo():
+    raise
+    raise ValueError
+    raise TypeError("test")
+    yield value
+    ''',
+         '''async def foo():
+    """\n    \n    :raises ValueError: DESCRIPTION
+    :raises TypeError: DESCRIPTION
+    :yield: DESCRIPTION
+    :rtype: TYPE
+
+    """
+    raise
+    raise ValueError
+    raise TypeError("test")
+    yield value
+    '''
+         ),
+        ('Sphinxdoc',
+         '''  def foo():
+      ''',
+         '''  def foo():
+      """\n      \n      :return: DESCRIPTION
+      :rtype: TYPE
+
+      """
+      ''',
+         ),
+        ('Sphinxdoc',
+         '''def foo(arg, arg0, arg1: int, arg2: List[Tuple[str, float]],
+    arg3='-> (float, int):', arg4=':float, int[', arg5: str='""') -> \
+  (List[Tuple[str, float]], str, float):
+    ''',
+         '''def foo(arg, arg0, arg1: int, arg2: List[Tuple[str, float]],
+    arg3='-> (float, int):', arg4=':float, int[', arg5: str='""') -> \
+  (List[Tuple[str, float]], str, float):
+    """\n    \n    :param arg: DESCRIPTION
+    :type arg: TYPE
+    :param arg0: DESCRIPTION
+    :type arg0: TYPE
+    :param arg1: DESCRIPTION
+    :type arg1: int
+    :param arg2: DESCRIPTION
+    :type arg2: List[Tuple[str, float]]
+    :param arg3: DESCRIPTION, defaults to '-> (float, int):'
+    :type arg3: TYPE, optional
+    :param arg4: DESCRIPTION, defaults to ':float, int['
+    :type arg4: TYPE, optional
+    :param arg5: DESCRIPTION, defaults to '""'
+    :type arg5: str, optional
+    :return: DESCRIPTION
+    :rtype: (List[Tuple[str, float]], str, float)
+
+    """
+    ''')
     ])
 def test_editor_docstring_by_shortcut(editor_auto_docstring, doc_type,
                                       text, expected, use_shortcut):