Repository: sphinx-doc/sphinx

Issue:
Autodoc: Wrong formatting of signature in presence of return annotations
While the `py_sig_re` regular expression successfully extracts the return annotations from signatures of the form

```
foo (a, b) -> c
```

when such a return annotation is present in the signature string, the generated description of the signature incorrectly adds parentheses when listing the functions of a module with their one-line summary with autodoc.

<img width="685" alt="screen shot 2016-03-08 at 6 31 49 pm" src="https://cloud.githubusercontent.com/assets/2397974/13620270/6a9fd646-e55c-11e5-9f73-64402309c29e.png">

However, the signature representation is correct in the long form.

<img width="680" alt="screen shot 2016-03-08 at 6 32 02 pm" src="https://cloud.githubusercontent.com/assets/2397974/13620259/63737d46-e55c-11e5-974b-424f9c6a4a80.png">


Discussion:

Patch:
diff --git a/CHANGES b/CHANGES
index 306db083b..4ebc9c2da 100644
--- a/CHANGES
+++ b/CHANGES
@@ -29,6 +29,7 @@ Bugs fixed
 * #4525: autosectionlabel does not support parallel build
 * #3953: Do not raise warning when there is a working intersphinx inventory
 * #4487: math: ValueError is raised on parallel build. Thanks to jschueller.
+* #2372: autosummary: invalid signatures are shown for type annotated functions
 
 Testing
 --------
diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py
index 08776badc..769ae4a63 100644
--- a/sphinx/ext/autosummary/__init__.py
+++ b/sphinx/ext/autosummary/__init__.py
@@ -397,10 +397,20 @@ def append_row(*column_texts):
         return [table_spec, table]
 
 
+def strip_arg_typehint(s):
+    # type: (unicode) -> unicode
+    """Strip a type hint from argument definition."""
+    return s.split(':')[0].strip()
+
+
 def mangle_signature(sig, max_chars=30):
     # type: (unicode, int) -> unicode
     """Reformat a function signature to a more compact form."""
-    s = re.sub(r"^\((.*)\)$", r"\1", sig).strip()
+    # Strip return type annotation
+    s = re.sub(r"\)\s*->\s.*$", ")", sig)
+
+    # Remove parenthesis
+    s = re.sub(r"^\((.*)\)$", r"\1", s).strip()
 
     # Strip strings (which can contain things that confuse the code below)
     s = re.sub(r"\\\\", "", s)
@@ -422,6 +432,13 @@ def mangle_signature(sig, max_chars=30):
         opts.insert(0, m.group(2))
         s = m.group(1)[:-2]
 
+    # Strip typehints
+    for i, arg in enumerate(args):
+        args[i] = strip_arg_typehint(arg)
+
+    for i, opt in enumerate(opts):
+        opts[i] = strip_arg_typehint(opt)
+
     # Produce a more compact signature
     sig = limited_join(", ", args, max_chars=max_chars - 2)
     if opts:


Test patch:
diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py
index a4cd9e03b..ad3f53982 100644
--- a/tests/test_ext_autosummary.py
+++ b/tests/test_ext_autosummary.py
@@ -47,6 +47,7 @@ def test_mangle_signature():
     (a, b={'c=d, ': 3, '\\\\': 3}) :: (a[, b])
     (a=1, b=2, c=3) :: ([a, b, c])
     (a=1, b=<SomeClass: a, b, c>, c=3) :: ([a, b, c])
+    (a: int, b: int) -> str :: (a, b)
     """
 
     TEST = [[y.strip() for y in x.split("::")] for x in TEST.split("\n")