Repository: sphinx-doc/sphinx

Issue:
Autodoc issue
Subject: Autodoc issue

### Problem
- Currently I have this: https://gyazo.com/3782bbce5d406ef9cb636b458cbcc509, how do I remove https://gyazo.com/0019a029a377e99bbab493fa9c894b4e

#### Procedure to reproduce the problem
```py
class BotDescription:
	"""Represents a DBL Bot Description

	Attributes
	----------
	short: str
		The bot's short description.
	long: str
		The bot's long description.
	"""
	def __init__(self, *, data={}):
		self.long = None
		self.short = None
		self.update(data=data)

	def update(self, *, data):
		longdesc = data.get("longdesc",None)
		shortdesc = data.get("shortdesc",None)
		if shortdesc:
			self.short = shortdesc
		if longdesc:
			self.long = longdesc
```

#### Error logs / results
```
Nothing
```
- Nothing

#### Expected results
Not display (*, data={})

### Reproducible project / your project
- https://github.com/JustMaffie/PyDBL

### Environment info
- OS: Windows
- Python version: 3.6.1
- Sphinx version: 1.6.2


Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599?src=pr&el=h1) Report
> Merging [#4599](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599?src=pr&el=desc) into [1.7](https://codecov.io/gh/sphinx-doc/sphinx/commit/419021e82f543c40e921b784445aeb5f97303caa?src=pr&el=desc) will **decrease** coverage by `0.79%`.
> The diff coverage is `50%`.

[![Impacted file tree graph](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599/graphs/tree.svg?width=650&token=VFlFSELbkw&height=150&src=pr)](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599?src=pr&el=tree)

```diff
@@           Coverage Diff            @@
##              1.7   #4599     +/-   ##
========================================
- Coverage   81.79%     81%   -0.8%     
========================================
  Files         277     274      -3     
  Lines       37024   36649    -375     
  Branches     5792    5548    -244     
========================================
- Hits        30283   29686    -597     
- Misses       5441    5631    +190     
- Partials     1300    1332     +32
```


| [Impacted Files](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [sphinx/util/inspect.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599/diff?src=pr&el=tree#diff-c3BoaW54L3V0aWwvaW5zcGVjdC5weQ==) | `49.76% <ø> (-22.99%)` | :arrow_down: |
| [tests/conftest.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599/diff?src=pr&el=tree#diff-dGVzdHMvY29uZnRlc3QucHk=) | `85.18% <50%> (-6.82%)` | :arrow_down: |
| [sphinx/util/pycompat.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599/diff?src=pr&el=tree#diff-c3BoaW54L3V0aWwvcHljb21wYXQucHk=) | `47.14% <0%> (-42.86%)` | :arrow_down: |
| [tests/test\_util\_inspect.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF91dGlsX2luc3BlY3QucHk=) | `60.28% <0%> (-29.91%)` | :arrow_down: |
| [sphinx/pycode/\_\_init\_\_.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599/diff?src=pr&el=tree#diff-c3BoaW54L3B5Y29kZS9fX2luaXRfXy5weQ==) | `81.33% <0%> (-9.34%)` | :arrow_down: |
| [tests/test\_smartquotes.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF9zbWFydHF1b3Rlcy5weQ==) | `92.5% <0%> (-7.5%)` | :arrow_down: |
| [tests/test\_pycode.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF9weWNvZGUucHk=) | `92.59% <0%> (-7.41%)` | :arrow_down: |
| [sphinx/ext/napoleon/\_\_init\_\_.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599/diff?src=pr&el=tree#diff-c3BoaW54L2V4dC9uYXBvbGVvbi9fX2luaXRfXy5weQ==) | `69.04% <0%> (-7.15%)` | :arrow_down: |
| [tests/test\_build\_texinfo.py](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599/diff?src=pr&el=tree#diff-dGVzdHMvdGVzdF9idWlsZF90ZXhpbmZvLnB5) | `77.14% <0%> (-5.72%)` | :arrow_down: |
| ... and [34 more](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599?src=pr&el=footer). Last update [419021e...18fd4ef](https://codecov.io/gh/sphinx-doc/sphinx/pull/4599?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/CHANGES b/CHANGES
index c8fa73ce5..df83d9b24 100644
--- a/CHANGES
+++ b/CHANGES
@@ -17,6 +17,8 @@ Bugs fixed
 ----------
 
 * #4608: epub: Invalid meta tag is generated
+* #4260: autodoc: keyword only argument separator is not disappeared if it is
+  appeared at top of the argument list
 
 Testing
 --------
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index 6fd5c789c..318758623 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -390,7 +390,8 @@ def format_args(self):
             # insert '*' between POSITIONAL args and KEYWORD_ONLY args::
             #     func(a, b, *, c, d):
             if param.kind == param.KEYWORD_ONLY and last_kind in (param.POSITIONAL_OR_KEYWORD,
-                                                                  param.POSITIONAL_ONLY):
+                                                                  param.POSITIONAL_ONLY,
+                                                                  None):
                 args.append('*')
 
             if param.kind in (param.POSITIONAL_ONLY,


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
index 9fb06edab..67560d009 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -21,6 +21,9 @@
 collect_ignore = ['roots']
 
 # Disable Python version-specific
+if sys.version_info < (3,):
+    collect_ignore += ['py3']
+
 if sys.version_info < (3, 5):
     collect_ignore += ['py35']
 
diff --git a/tests/py3/test_util_inspect_py3.py b/tests/py3/test_util_inspect_py3.py
new file mode 100644
index 000000000..6d02025f9
--- /dev/null
+++ b/tests/py3/test_util_inspect_py3.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+"""
+    py3/test_util_inspect
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    Tests util.inspect functions.
+
+    :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from sphinx.util import inspect
+
+
+def test_Signature_keyword_only_arguments():
+    def func1(arg1, arg2, *, arg3=None, arg4=None):
+        pass
+
+    def func2(*, arg3, arg4):
+        pass
+
+    sig = inspect.Signature(func1).format_args()
+    assert sig == '(arg1, arg2, *, arg3=None, arg4=None)'
+
+    sig = inspect.Signature(func2).format_args()
+    assert sig == '(*, arg3, arg4)'