Repository: sphinx-doc/sphinx

Issue:
2.1.0 regression [autodoc]: Unknown target name: "type"
Our CI jobs started failing with Sphinx 2.1.0.
Example here:
https://travis-ci.org/apache/arrow/jobs/540490192#L5631

The error is:
```
Warning, treated as error:
docstring of pyarrow.SerializationContext.register_type:0:Unknown target name: "type".
```

Here is said docstring:
```python
        """EXPERIMENTAL: Add type to the list of types we can serialize.

        Parameters
        ----------
        type_ : TypeType
            The type that we can serialize.
        type_id : string
            A string used to identify the type.
        pickle : bool
            True if the serialization should be done with pickle.
            False if it should be done efficiently with Arrow.
        custom_serializer : callable
            This argument is optional, but can be provided to
            serialize objects of the class in a particular way.
        custom_deserializer : callable
            This argument is optional, but can be provided to
            deserialize objects of the class in a particular way.
        """
```

You can find out `conf.py` here:
https://github.com/apache/arrow/blob/master/docs/source/conf.py


Discussion:

Patch:
diff --git a/CHANGES b/CHANGES
index 6341ecaad..12ebc4975 100644
--- a/CHANGES
+++ b/CHANGES
@@ -21,6 +21,8 @@ Bugs fixed
 * #6448: autodoc: crashed when autodocumenting classes with ``__slots__ = None``
 * #6452: autosummary: crashed when generating document of properties
 * #6455: napoleon: docstrings for properties are not processed
+* #6436: napoleon: "Unknown target name" error if variable name ends with
+  underscore
 
 Testing
 --------
diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py
index 5ba65d351..7ff184961 100644
--- a/sphinx/ext/napoleon/docstring.py
+++ b/sphinx/ext/napoleon/docstring.py
@@ -328,6 +328,9 @@ def _dedent(self, lines, full=False):
 
     def _escape_args_and_kwargs(self, name):
         # type: (str) -> str
+        if name.endswith('_'):
+            name = name[:-1] + r'\_'
+
         if name[:2] == '**':
             return r'\*\*' + name[2:]
         elif name[:1] == '*':


Test patch:
diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py
index a333dc47b..f1714bd62 100644
--- a/tests/test_ext_napoleon_docstring.py
+++ b/tests/test_ext_napoleon_docstring.py
@@ -1351,8 +1351,8 @@ def test_underscore_in_attribute(self):
 """
 
         expected = """
-:ivar arg_: some description
-:vartype arg_: type
+:ivar arg\\_: some description
+:vartype arg\\_: type
 """
 
         config = Config(napoleon_use_ivar=True)