Repository: sphinx-doc/sphinx

Issue:
linkcheck builder crashes for a hyperlink containing multibyte character
### Problem
- linkcheck builder crashes for a hyperlink containing multibyte character

#### Procedure to reproduce the problem

Add a hyperlink which contains multibyte character like this:
```
`hello <https://example.com/ああああああああ>`_
```

And then, call linkcheck builder:

#### Error logs / results
```
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/Users/tkomiya/work/sphinx/sphinx/builders/linkcheck.py", line 132, in check_uri
    req_url.encode('ascii')
UnicodeEncodeError: 'ascii' codec can't encode characters in position 20-27: ordinal not in range(128)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/tkomiya/.pyenv/versions/3.6.5/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/Users/tkomiya/.pyenv/versions/3.6.5/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/tkomiya/work/sphinx/sphinx/builders/linkcheck.py", line 217, in check_thread
    status, info, code = check()
  File "/Users/tkomiya/work/sphinx/sphinx/builders/linkcheck.py", line 200, in check
    status, info, code = check_uri()
  File "/Users/tkomiya/work/sphinx/sphinx/builders/linkcheck.py", line 134, in check_uri
    req_url = encode_uri(req_url)
  File "/Users/tkomiya/work/sphinx/sphinx/util/__init__.py", line 604, in encode_uri
    split[2] = quote_plus(split[2].encode('utf-8'), '/').decode('ascii')
AttributeError: 'str' object has no attribute 'decode'
```

#### Expected results
Works fine.

### Reproducible project / your project
No.

### Environment info
- OS: Mac
- Python version: 3.7.1
- Sphinx version: 1.8.2



Discussion:

Patch:
diff --git a/CHANGES b/CHANGES
index 6d3daa3e2..70b549943 100644
--- a/CHANGES
+++ b/CHANGES
@@ -20,6 +20,7 @@ Bugs fixed
 * #5520: LaTeX, caption package incompatibility since Sphinx 1.6
 * #5614: autodoc: incremental build is broken when builtin modules are imported
 * #5627: qthelp: index.html missing in QtHelp
+* #5659: linkcheck: crashes for a hyperlink containing multibyte character
 
 Testing
 --------
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index 9bc88c82f..019de997d 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -598,12 +598,11 @@ def import_object(objname, source=None):
 
 def encode_uri(uri):
     # type: (unicode) -> unicode
-    split = list(urlsplit(uri))  # type: Any
+    split = list(urlsplit(uri))  # type: List[unicode]
     split[1] = split[1].encode('idna').decode('ascii')
-    split[2] = quote_plus(split[2].encode('utf-8'), '/').decode('ascii')
-    query = list((q, quote_plus(v.encode('utf-8')))
-                 for (q, v) in parse_qsl(split[3]))
-    split[3] = urlencode(query).decode('ascii')
+    split[2] = quote_plus(split[2].encode('utf-8'), '/')
+    query = list((q, v.encode('utf-8')) for (q, v) in parse_qsl(split[3]))
+    split[3] = urlencode(query)
     return urlunsplit(split)
 
 


Test patch:
diff --git a/tests/test_util.py b/tests/test_util.py
index a3745e7a1..c6645220e 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -30,13 +30,13 @@ def test_encode_uri():
                 u'%D0%B1%D0%B0%D0%B7%D0%B0%D0%BC%D0%B8_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85')
     uri = (u'https://ru.wikipedia.org/wiki'
            u'/Система_управления_базами_данных')
-    assert expected, encode_uri(uri)
+    assert expected == encode_uri(uri)
 
     expected = (u'https://github.com/search?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+is%3A'
                 u'sprint-friendly+user%3Ajupyter&type=Issues&ref=searchresults')
     uri = (u'https://github.com/search?utf8=✓&q=is%3Aissue+is%3Aopen+is%3A'
            u'sprint-friendly+user%3Ajupyter&type=Issues&ref=searchresults')
-    assert expected, encode_uri(uri)
+    assert expected == encode_uri(uri)
 
 
 def test_display_chunk():