Repository: sphinx-doc/sphinx

Issue:
WARNING: error while formatting arguments for xxx.XXX: 'ForwardRef' object has no attribute '__origin__' on python 3.7
Subject: WARNING: error while formatting arguments for xxx.XXX: 'ForwardRef' object has no attribute `'__origin__'` on python 3.7

### Problem
- This warning is raised on python3.7 with autodoc of the below code and type hints does not made in output.

```python
from typing import Optional

class Node(object):
    """Node class."""

    def __init__(self, parent_node: Optional['Node']) -> None:
        self._parent = parent_node
```

#### Procedure to reproduce the problem
```
git clone https://github.com/miyakogi/sphinx_py37
cd sphinx_py37
(make new venv and install sphinx if needed)
cd docs
make html
```

#### Error logs / results

Output:

```
WARNING: error while formatting arguments for sphinx_py37.Node: 'ForwardRef' object has no attribute '__origin__'
```

And type hints are not exist in the output HTML.

#### Expected results

No warning and type hints in the result.

### Reproducible project / your project
- https://github.com/miyakogi/sphinx_py37

### Environment info
- OS: Linux (Arch Linux) and Windows 10 home
- Python version: 3.7.0
- Sphinx version: 1.7.6 and 1.8.0.dev20180813


Discussion:

Patch:
diff --git a/CHANGES b/CHANGES
index 2cdb52a6c..7472232da 100644
--- a/CHANGES
+++ b/CHANGES
@@ -28,6 +28,8 @@ Bugs fixed
   font with XeLaTeX/LuaLateX (refs: #5251)
 * #5280: autodoc: Fix wrong type annotations for complex typing
 * autodoc: Optional types are wrongly rendered
+* #5291: autodoc crashed by ForwardRef types
+
 
 Testing
 --------
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index c3fe0178d..64e93f267 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -477,6 +477,8 @@ def format_annotation_new(self, annotation):
                 qualname = annotation._name
             elif getattr(annotation, '__qualname__', None):
                 qualname = annotation.__qualname__
+            elif getattr(annotation, '__forward_arg__', None):
+                qualname = annotation.__forward_arg__
             else:
                 qualname = self.format_annotation(annotation.__origin__)  # ex. Union
         elif hasattr(annotation, '__qualname__'):
@@ -510,6 +512,8 @@ def format_annotation_old(self, annotation):
                 qualname = annotation._name
             elif getattr(annotation, '__qualname__', None):
                 qualname = annotation.__qualname__
+            elif getattr(annotation, '__forward_arg__', None):
+                qualname = annotation.__forward_arg__
             else:
                 qualname = self.format_annotation(annotation.__origin__)  # ex. Union
         elif hasattr(annotation, '__qualname__'):


Test patch:
diff --git a/tests/test_util_inspect.py b/tests/test_util_inspect.py
index 51c2d06e1..a48aedcf0 100644
--- a/tests/test_util_inspect.py
+++ b/tests/test_util_inspect.py
@@ -297,6 +297,9 @@ def test_Signature_annotations():
     sig = inspect.Signature(Node.children).format_args()
     assert sig == '(self) -> List[typing_test_data.Node]'
 
+    sig = inspect.Signature(Node.__init__).format_args()
+    assert sig == '(self, parent: Optional[Node]) -> None'
+
 
 def test_safe_getattr_with_default():
     class Foo(object):
diff --git a/tests/typing_test_data.py b/tests/typing_test_data.py
index 35064b042..5b161eac4 100644
--- a/tests/typing_test_data.py
+++ b/tests/typing_test_data.py
@@ -73,5 +73,8 @@ def f13() -> Optional[str]:
 
 
 class Node:
+    def __init__(self, parent: Optional['Node']) -> None:
+        pass
+
     def children(self) -> List['Node']:
         pass