# Buggy code
def annotate_to_first_argument(self, func: Callable, typ: Type) -> None:
    """Annotate type hint to the first argument of function if needed."""
    try:
        sig = inspect.signature(func, type_aliases=self.config.autodoc_type_aliases)
    except TypeError as exc:
        logger.warning(
            __("Failed to get a function signature for %s: %s"), self.fullname, exc
        )
        return
    except ValueError:
        return

    if len(sig.parameters) == 0:
        return

    params = list(sig.parameters.values())
    if params[0].annotation is Parameter.empty:
        params[0] = params[0].replace(annotation=typ)
        try:
            func.__signature__ = sig.replace(parameters=params)  # type: ignore
        except TypeError:
            # failed to update signature (ex. built-in or extension types)
            return


# Traceback (AttributeError)
root@155a990f7394:/renderdoc/docs# cat /tmp/sphinx-err-eubtp5yu.log
# Sphinx version: 3.5.0
# Python version: 3.6.9 (CPython)
# Docutils version: 0.16 release
# Jinja2 version: 2.11.3
# Last messages:
#   reading sources... [ 52%] python_api/examples/renderdoc/save_texture
#
#   reading sources... [ 53%] python_api/examples/renderdoc_intro
#
#   reading sources... [ 54%] python_api/index
#
#   reading sources... [ 55%] python_api/qrenderdoc/config
#
#   The name of the builder is: html
#
# Loaded extensions:
#   sphinx.ext.mathjax (3.5.0) from /usr/local/lib/python3.6/dist-packages/sphinx/ext/mathjax.py
#   sphinxcontrib.applehelp (1.0.2) from /usr/local/lib/python3.6/dist-packages/sphinxcontrib/applehelp/__init__.py
#   sphinxcontrib.devhelp (1.0.2) from /usr/local/lib/python3.6/dist-packages/sphinxcontrib/devhelp/__init__.py
#   sphinxcontrib.htmlhelp (1.0.3) from /usr/local/lib/python3.6/dist-packages/sphinxcontrib/htmlhelp/__init__.py
#   sphinxcontrib.serializinghtml (1.1.4) from /usr/local/lib/python3.6/dist-packages/sphinxcontrib/serializinghtml/__init__.py
#   sphinxcontrib.qthelp (1.0.3) from /usr/local/lib/python3.6/dist-packages/sphinxcontrib/qthelp/__init__.py
#   alabaster (0.7.12) from /usr/local/lib/python3.6/dist-packages/alabaster/__init__.py
#   sphinx.ext.autodoc.type_comment (3.5.0) from /usr/local/lib/python3.6/dist-packages/sphinx/ext/autodoc/type_comment.py
#   sphinx.ext.autodoc (3.5.0) from /usr/local/lib/python3.6/dist-packages/sphinx/ext/autodoc/__init__.py
#   sphinx_paramlinks (unknown version) from /renderdoc/docs/sphinx_exts/sphinx_paramlinks/__init__.py
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/sphinx/cmd/build.py", line 280, in build_main
app.build(args.force_all, filenames)
File "/usr/local/lib/python3.6/dist-packages/sphinx/application.py", line 352, in build
self.builder.build_update()
File "/usr/local/lib/python3.6/dist-packages/sphinx/builders/__init__.py", line 298, in build_update
len(to_build))
File "/usr/local/lib/python3.6/dist-packages/sphinx/builders/__init__.py", line 310, in build
updated_docnames = set(self.read())
File "/usr/local/lib/python3.6/dist-packages/sphinx/builders/__init__.py", line 417, in read
self._read_serial(docnames)
File "/usr/local/lib/python3.6/dist-packages/sphinx/builders/__init__.py", line 438, in _read_serial
self.read_doc(docname)
File "/usr/local/lib/python3.6/dist-packages/sphinx/builders/__init__.py", line 478, in read_doc
doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
File "/usr/local/lib/python3.6/dist-packages/sphinx/io.py", line 221, in read_doc
pub.publish()
File "/usr/local/lib/python3.6/dist-packages/docutils/core.py", line 218, in publish
self.settings)
File "/usr/local/lib/python3.6/dist-packages/sphinx/io.py", line 126, in read
self.parse()
File "/usr/local/lib/python3.6/dist-packages/docutils/readers/__init__.py", line 77, in parse
self.parser.parse(self.input, document)
File "/usr/local/lib/python3.6/dist-packages/sphinx/parsers.py", line 104, in parse
self.statemachine.run(inputlines, document, inliner=self.inliner)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 171, in run
input_source=document['source'])
File "/usr/local/lib/python3.6/dist-packages/docutils/statemachine.py", line 242, in run
context, state, transitions)
File "/usr/local/lib/python3.6/dist-packages/docutils/statemachine.py", line 459, in check_line
return method(match, context, next_state)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 2769, in underline
self.section(title, source, style, lineno - 1, messages)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 395, in new_subsection
node=section_node, match_titles=True)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
node=node, match_titles=match_titles)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/usr/local/lib/python3.6/dist-packages/docutils/statemachine.py", line 242, in run
context, state, transitions)
File "/usr/local/lib/python3.6/dist-packages/docutils/statemachine.py", line 459, in check_line
return method(match, context, next_state)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 2769, in underline
self.section(title, source, style, lineno - 1, messages)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 395, in new_subsection
node=section_node, match_titles=True)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
node=node, match_titles=match_titles)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/usr/local/lib/python3.6/dist-packages/docutils/statemachine.py", line 242, in run
context, state, transitions)
File "/usr/local/lib/python3.6/dist-packages/docutils/statemachine.py", line 459, in check_line
return method(match, context, next_state)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 2342, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
return method(self, expmatch)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 2097, in directive
directive_class, match, type_name, option_presets)
File "/usr/local/lib/python3.6/dist-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
result = directive_instance.run()
File "/usr/local/lib/python3.6/dist-packages/sphinx/ext/autodoc/directive.py", line 167, in run
documenter.generate(more_content=self.content)
File "/usr/local/lib/python3.6/dist-packages/sphinx/ext/autodoc/__init__.py", line 1728, in generate
all_members=all_members)
File "/usr/local/lib/python3.6/dist-packages/sphinx/ext/autodoc/__init__.py", line 970, in generate
self.document_members(all_members)
File "/usr/local/lib/python3.6/dist-packages/sphinx/ext/autodoc/__init__.py", line 1717, in document_members
super().document_members(all_members)
File "/usr/local/lib/python3.6/dist-packages/sphinx/ext/autodoc/__init__.py", line 853, in document_members
check_module=members_check_module and not isattr)
File "/usr/local/lib/python3.6/dist-packages/sphinx/ext/autodoc/__init__.py", line 904, in generate
if not self.import_object():
File "/usr/local/lib/python3.6/dist-packages/sphinx/ext/autodoc/__init__.py", line 2455, in import_object
self.update_annotations(self.parent)
File "/usr/local/lib/python3.6/dist-packages/sphinx/ext/autodoc/__init__.py", line 2432, in update_annotations
parent.__annotations__ = annotations
AttributeError: type 'qrenderdoc.PersistantConfig' has no attribute '__annotations__'

# Fixed code
def annotate_to_first_argument(self, func: Callable, typ: Type) -> None:
    """Annotate type hint to the first argument of function if needed."""
    try:
        sig = inspect.signature(func, type_aliases=self.config.autodoc_type_aliases)
    except TypeError as exc:
        logger.warning(
            __("Failed to get a function signature for %s: %s"), self.fullname, exc
        )
        return
    except ValueError:
        return

    if len(sig.parameters) == 0:
        return

    params = list(sig.parameters.values())
    if params[0].annotation is Parameter.empty:
        params[0] = params[0].replace(annotation=typ)
        try:
            func.__signature__ = sig.replace(parameters=params)  # type: ignore
        except (AttributeError, TypeError):
            # failed to update signature (ex. built-in or extension types)
            return