Bump Sphinx version
diff --git a/requirements.txt b/requirements.txt
index 333a0fa..a9f5cb7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,9 +1,10 @@
-cibuildwheel == 2.*, >= 2.2.2
-colorama == 0.*, >= 0.4.3
-docutils == 0.16.*
-cython == 0.*, >= 0.29.14
-more_itertools == 8.*, >= 8.0.2
-sphinx == 2.*, >= 2.2.2
-sphinx_autodoc_typehints == 1.*, >= 1.10.3, < 1.11
-sphinx_rtd_theme == 0.*, >= 0.4.3
-wheel == 0.*, >= 0.33.6
+cibuildwheel == 2.*
+colorama == 0.4.*
+docutils == 0.17.*
+cython == 0.*
+more_itertools == 8.*
+sphinx == 4.*
+sphinx_autodoc_typehints == 1.*
+sphinx_rtd_theme == 1.*
+sphinxprettysearchresults == 0.3.*
+wheel
diff --git a/src/_encoder_options.pyx b/src/_encoder_options.pyx
index 16d5bee..bff172d 100644
--- a/src/_encoder_options.pyx
+++ b/src/_encoder_options.pyx
@@ -50,9 +50,9 @@
 @auto_pickle(False)
 cdef class Options:
     '''
-    Customizations for the ``encoder_*(...)`` function family.
+    Customizations for the :func:`encoder_*(...) <pyjson5.encoder>` function family.
 
-    Immutable. Use ``Options.update(**kw)`` to create a **new** Options instance.
+    Immutable. Use :meth:`Options.update(**kw) <pyjson5.Options.update>` to create a **new** Options instance.
 
     Parameters
     ----------
diff --git a/src/_exports.pyx b/src/_exports.pyx
index fc4b4b2..3d17ea8 100644
--- a/src/_exports.pyx
+++ b/src/_exports.pyx
@@ -13,7 +13,7 @@
 
 def decode(object data, object maxdepth=None, object some=False):
     '''
-    Decodes JSON5 serialized data from an ``str`` object.
+    Decodes JSON5 serialized data from an :class:`str` object.
 
     .. code:: python
 
@@ -21,7 +21,7 @@
 
     Parameters
     ----------
-    data : unicode
+    data : str
         JSON5 serialized data
     maxdepth : Optional[int]
         Maximum nesting level before are the parsing is aborted.
@@ -58,7 +58,7 @@
 
 def decode_latin1(object data, object maxdepth=None, object some=False):
     '''
-    Decodes JSON5 serialized data from a ``bytes`` object.
+    Decodes JSON5 serialized data from a :class:`bytes` object.
 
     .. code:: python
 
@@ -69,9 +69,9 @@
     data : bytes
         JSON5 serialized data, encoded as Latin-1 or ASCII.
     maxdepth : Optional[int]
-        see `decode(...) <pyjson5.decode_>`_
+        see :func:`decode(…) <pyjson5.decode>`
     some : bool
-        see `decode(...) <pyjson5.decode_>`_
+        see :func:`decode(…) <pyjson5.decode>`
 
     Raises
     ------
@@ -83,14 +83,14 @@
     Returns
     -------
     object
-        see `decode(...) <pyjson5.decode_>`_
+        see :func:`decode(…) <pyjson5.decode>`
     '''
     return decode_buffer(data, maxdepth, bool(some), 1)
 
 
 def decode_utf8(object data, object maxdepth=None, object some=False):
     '''
-    Decodes JSON5 serialized data from a ``bytes`` object.
+    Decodes JSON5 serialized data from a :class:`bytes` object.
 
     .. code:: python
 
@@ -101,9 +101,9 @@
     data : bytes
         JSON5 serialized data, encoded as UTF-8 or ASCII.
     maxdepth : Optional[int]
-        see `decode(...) <pyjson5.decode_>`_
+        see :func:`decode(…) <pyjson5.decode>`
     some : bool
-        see `decode(...) <pyjson5.decode_>`_
+        see :func:`decode(…) <pyjson5.decode>`
 
     Raises
     ------
@@ -115,7 +115,7 @@
     Returns
     -------
     object
-        see `decode(...) <pyjson5.decode_>`_
+        see :func:`decode(…) <pyjson5.decode>`
     '''
     return decode_buffer(data, maxdepth, bool(some), 0)
 
@@ -123,8 +123,8 @@
 def decode_buffer(object obj, object maxdepth=None, object some=False,
                   object wordlength=None):
     '''
-    Decodes JSON5 serialized data from an object that supports the buffer
-    protocol, e.g. bytearray.
+    Decodes JSON5 serialized data from an object that supports the buffer protocol,
+    e.g. :class:`bytearray`.
 
     .. code:: python
 
@@ -137,14 +137,14 @@
     data : object
         JSON5 serialized data.
         The argument must support Python's buffer protocol, i.e.
-        ``memoryview(...)`` must work. The buffer must be contigious.
+        :class:`memoryview(…) <memoryview>` must work. The buffer must be contigious.
     maxdepth : Optional[int]
-        see `decode(...) <pyjson5.decode_>`_
+        see :func:`decode(…) <pyjson5.decode>`
     some : bool
-        see `decode(...) <pyjson5.decode_>`_
+        see :func:`decode(…) <pyjson5.decode>`
     wordlength : Optional[int]
         Must be 0, 1, 2, 4 to denote UTF-8, UCS1, USC2 or USC4 data, resp.
-        Surrogates are not supported. Decode the data to an ``str`` if need be.
+        Surrogates are not supported. Decode the data to an :class:`str` if need be.
         If ``None`` is supplied, then the buffer's ``itemsize`` is used.
 
     Raises
@@ -159,7 +159,7 @@
     Returns
     -------
     object
-        see `decode(...) <pyjson5.decode_>`_
+        see :func:`decode(…) <pyjson5.decode>`
     '''
     cdef Py_buffer view
 
@@ -193,17 +193,17 @@
         The functions is called like ``cb(*args)``, and it returns:
 
         * **str, bytes, bytearray:** \
-            ``len(...) == 0`` denotes exhausted input. \
-            ``len(...) == 1`` is the next character.
+            ``len(…) == 0`` denotes exhausted input. \
+            ``len(…) == 1`` is the next character.
         * **int:** \
             ``< 0`` denotes exhausted input. \
            ``>= 0`` is the ordinal value of the next character.
         * **None:** \
             input exhausted
     maxdepth : Optional[int]
-        see `decode(...) <pyjson5.decode_>`_
+        see :func:`decode(…) <pyjson5.decode>`
     some : bool
-        see `decode(...) <pyjson5.decode_>`_
+        see :func:`decode(…) <pyjson5.decode>`
     args : Optional[Iterable[Any]]
         Arguments to call ``cb`` with.
 
@@ -217,7 +217,7 @@
     Returns
     -------
     object
-        see ``decode(...)``
+        see :func:`decode(…) <pyjson5.decode>`
     '''
     if not callable(cb):
         raise TypeError(f'type(cb)=={type(cb)!r} is not callable')
@@ -257,9 +257,9 @@
     fp : IOBase
         A file-like object to parse from.
     maxdepth : Optional[int] = None
-        see `decode(...) <pyjson5.decode_>`_
+        see :func:`decode(…) <pyjson5.decode>`
     some : bool
-        see `decode(...) <pyjson5.decode_>`_
+        see :func:`decode(…) <pyjson5.decode>`
 
     Raises
     ------
@@ -271,7 +271,7 @@
     Returns
     -------
     object
-        see ``decode(...)``
+        see :func:`decode(…) <pyjson5.decode>`
     '''
     if not isinstance(fp, IOBase):
         raise TypeError(f'type(fp)=={type(fp)!r} is not IOBase compatible')
@@ -288,7 +288,7 @@
 
 def encode(object data, *, options=None, **options_kw):
     '''
-    Serializes a Python object to a JSON5 compatible unicode string.
+    Serializes a Python object as a JSON5 compatible string.
 
     .. code:: python
 
@@ -385,11 +385,11 @@
     Parameters
     ----------
     data : object
-        see `encode(...) <pyjson5.encode_>`_
+        see :func:`encode(…) <pyjson5.encode>`
     options : Optional[Options]
-        see `encode(...) <pyjson5.encode_>`_
+        see :func:`encode(…) <pyjson5.encode>`
     options_kw
-        see `encode(...) <pyjson5.encode_>`_
+        see :func:`encode(…) <pyjson5.encode>`
 
     Raises
     ------
@@ -401,7 +401,7 @@
     Returns
     -------
     bytes
-        see `encode(...) <pyjson5.encode_>`_
+        see :func:`encode(…) <pyjson5.encode>`
     '''
     cdef void *temp
     cdef object result
@@ -472,18 +472,18 @@
     Parameters
     ----------
     data : object
-        see `encode(...) <pyjson5.encode_>`_
+        see :func:`encode(…) <pyjson5.encode>`
     cb : Callable[[Union[bytes|str]], None]
         A callback function.
-        Depending on the truthyness of ``supply_bytes`` either ``bytes`` or
-        ``str`` is supplied.
+        Depending on the truthyness of ``supply_bytes`` either :class:`bytes` or
+        :class:`str` is supplied.
     supply_bytes : bool
-        Call ``cb(...)`` with a ``bytes`` argument if true,
-        otherwise ``str``.
+        Call ``cb(…)`` with a :class:`bytes` argument if true,
+        otherwise :class:`str`.
     options : Optional[Options]
-        see `encode(...) <pyjson5.encode_>`_
+        see :func:`encode(…) <pyjson5.encode>`
     options_kw
-        see `encode(...) <pyjson5.encode_>`_
+        see :func:`encode(…) <pyjson5.encode>`
 
     Raises
     ------
@@ -515,22 +515,22 @@
     '''
     Serializes a Python object into a file-object.
 
-    The return value of ``fp.write(...)`` is not checked.
+    The return value of :meth:`fp.write(…) <io.BufferedWriter.write>` is not checked.
     If ``fp`` is unbuffered, then the result will be garbage!
 
     Parameters
     ----------
     data : object
-        see `encode(...) <pyjson5.encode_>`_
+        see :func:`encode(…) <pyjson5.encode>`
     fp : IOBase
         A file-like object to serialize into.
     supply_bytes : bool
-        Call ``fp.write(...)`` with a ``bytes`` argument if true,
-        otherwise ``str``.
+        Call :meth:`fp.write(…) <io.BufferedWriter.write>` with a :class:`bytes` argument if true,
+        otherwise :class:`str`.
     options : Optional[Options]
-        see `encode(...) <pyjson5.encode_>`_
+        see :func:`encode(…) <pyjson5.encode>`
     options_kw
-        see `encode(...) <pyjson5.encode_>`_
+        see :func:`encode(…) <pyjson5.encode>`
 
     Raises
     ------
@@ -579,11 +579,11 @@
     Parameters
     ----------
     data : object
-        see `encode(...) <pyjson5.encode_>`_
+        see :func:`encode(…) <pyjson5.encode>`
     options : Optional[Options]
-        see `encode(...) <pyjson5.encode_>`_
+        see :func:`encode(…) <pyjson5.encode>`
     options_kw
-        see `encode(...) <pyjson5.encode_>`_
+        see :func:`encode(…) <pyjson5.encode>`
 
     Returns
     -------
diff --git a/src/_legacy.pyx b/src/_legacy.pyx
index 337dc84..50a79d8 100644
--- a/src/_legacy.pyx
+++ b/src/_legacy.pyx
@@ -2,7 +2,7 @@
     '''
     Decodes JSON5 serialized data from a string.
 
-    Use `decode(...) <pyjson5.decode_>`_ instead!
+    Use :func:`decode(…) <pyjson5.decode>` instead!
 
     .. code:: python
 
@@ -21,7 +21,7 @@
     Returns
     -------
     object
-        see ``decode(...)``
+        see :func:`decode(…) <pyjson5.decode>`
     '''
     if not isinstance(s, unicode):
         s = PyUnicode_FromEncodedObject(s, encoding, 'strict')
@@ -32,7 +32,7 @@
     '''
     Decodes JSON5 serialized data from a file-like object.
 
-    Use `decode_io(...) <pyjson5.decode_io_>`_ instead!
+    Use :func:`decode_io(…) <pyjson5.decode_io>` instead!
 
     .. code:: python
 
@@ -47,17 +47,17 @@
 
     Returns
     -------
-    object
-        see ``decode(...)``
+    str
+        see :func:`decode_io(…) <pyjson5.decode_io>`
     '''
     return decode_io(fp, None, False)
 
 
 def dumps(obj, **kw):
     '''
-    Serializes a Python object to a JSON5 compatible unicode string.
+    Serializes a Python object to a JSON5 compatible string.
 
-    Use `encode(...) <pyjson5.encode_>`_ instead!
+    Use :func:`encode(…) <pyjson5.encode>` instead!
 
     .. code:: python
 
@@ -72,17 +72,17 @@
 
     Returns
     -------
-    unicode
-        see ``encode(data)``
+    str
+        see :func:`encode(…) <pyjson5.encode>`
     '''
     return encode(obj)
 
 
 def dump(object obj, object fp, **kw):
     '''
-    Serializes a Python object to a JSON5 compatible unicode string.
+    Serializes a Python object to a JSON5 compatible string.
 
-    Use `encode_io(...) <pyjson5.encode_io_>`_ instead!
+    Use :func:`encode_io(…) <pyjson5.encode_io>` instead!
 
     .. code:: python
 
diff --git a/src/pyjson5/__init__.pyi b/src/pyjson5/__init__.pyi
index 3ea3810..e041988 100644
--- a/src/pyjson5/__init__.pyi
+++ b/src/pyjson5/__init__.pyi
@@ -99,7 +99,7 @@
     tojson: Optional[str],
     mappingtypes: Optional[Tuple[type, ...]],
 ) -> str:
-    '''Serializes a Python object to a JSON5 compatible unicode string.'''
+    '''Serializes a Python object to a JSON5 compatible string.'''
     ...
 
 def encode_bytes(
@@ -179,11 +179,11 @@
     ...
 
 def dumps(obj: Any) -> str:
-    '''Serializes a Python object to a JSON5 compatible unicode string.'''
+    '''Serializes a Python object to a JSON5 compatible string.'''
     ...
 
 def dump(obj: Any, fp: _SupportsWrite[str]) -> None:
-    '''Serializes a Python object to a JSON5 compatible unicode string.'''
+    '''Serializes a Python object to a JSON5 compatible string.'''
     ...