# Buggy code
def merge_typehints(
    app: Sphinx, domain: str, objtype: str, contentnode: Element
) -> None:
    if domain != "py":
        return
    if app.config.autodoc_typehints != "description":
        return
    if objtype == "class" and app.config.autoclass_content not in ("init", "both"):
        return

    signature = cast(addnodes.desc_signature, contentnode.parent[0])
    if signature["module"]:
        fullname = ".".join([signature["module"], signature["fullname"]])
    else:
        fullname = signature["fullname"]
    annotations = app.env.temp_data.get("annotations", {})
    if annotations.get(fullname, {}):
        field_lists = [n for n in contentnode if isinstance(n, nodes.field_list)]
        if field_lists == []:
            field_list = insert_field_list(contentnode)
            field_lists.append(field_list)

        for field_list in field_lists:
            modify_field_list(field_list, annotations[fullname])


# Traceback (KeyError)
# Sphinx version: 3.0.4
# Python version: 3.5.6 (CPython)
# Docutils version: 0.14
# Jinja2 version: 2.11.2
# Last messages:
#   reading sources... [ 54%] source/qcSTR
#
#   reading sources... [ 58%] source/statSTR
#
#   reading sources... [ 62%] trtools.compareSTR
#
#   reading sources... [ 66%] trtools.dumpSTR
#
#   reading sources... [ 70%] trtools.dumpSTR.filters
#
# Loaded extensions:
#   sphinx.ext.autodoc.type_comment (3.0.4) from /storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/ext/autodoc/type_comment.py
#   sphinxcontrib.qthelp (1.0.3) from /storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinxcontrib/qthelp/__init__.py
#   sphinx.ext.napoleon (3.0.4) from /storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/ext/napoleon/__init__.py
#   sphinxcontrib.serializinghtml (1.1.4) from /storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinxcontrib/serializinghtml/__init__.py
#   sphinxcontrib.devhelp (1.0.2) from /storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinxcontrib/devhelp/__init__.py
#   sphinx.ext.autodoc (3.0.4) from /storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/ext/autodoc/__init__.py
#   sphinx.ext.mathjax (3.0.4) from /storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/ext/mathjax.py
#   sphinxcontrib.applehelp (1.0.2) from /storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinxcontrib/applehelp/__init__.py
#   sphinxcontrib.htmlhelp (1.0.3) from /storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinxcontrib/htmlhelp/__init__.py
#   alabaster (0.7.12) from /storage/conda/envs/trtools_dev/lib/python3.5/site-packages/alabaster/__init__.py
Traceback (most recent call last):
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/cmd/build.py", line 280, in build_main
app.build(args.force_all, filenames)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/application.py", line 348, in build
self.builder.build_update()
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/builders/__init__.py", line 299, in build_update
len(to_build))
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/builders/__init__.py", line 311, in build
updated_docnames = set(self.read())
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/builders/__init__.py", line 418, in read
self._read_serial(docnames)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/builders/__init__.py", line 439, in _read_serial
self.read_doc(docname)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/builders/__init__.py", line 479, in read_doc
doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/io.py", line 221, in read_doc
pub.publish()
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/core.py", line 217, in publish
self.settings)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/io.py", line 126, in read
self.parse()
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/readers/__init__.py", line 78, in parse
self.parser.parse(self.input, document)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/parsers.py", line 102, in parse
self.statemachine.run(inputlines, document, inliner=self.inliner)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 171, in run
input_source=document['source'])
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/statemachine.py", line 239, in run
context, state, transitions)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/statemachine.py", line 460, in check_line
return method(match, context, next_state)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2753, in underline
self.section(title, source, style, lineno - 1, messages)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 327, in section
self.new_subsection(title, lineno, messages)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 395, in new_subsection
node=section_node, match_titles=True)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
node=node, match_titles=match_titles)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/statemachine.py", line 239, in run
context, state, transitions)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/statemachine.py", line 460, in check_line
return method(match, context, next_state)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2326, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2338, in explicit_construct
return method(self, expmatch)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2081, in directive
directive_class, match, type_name, option_presets)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2130, in run_directive
result = directive_instance.run()
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/ext/autodoc/directive.py", line 157, in run
result = parse_generated_content(self.state, params.result, documenter)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/ext/autodoc/directive.py", line 100, in parse_generated_content
nested_parse_with_titles(state, content, node)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/util/nodes.py", line 339, in nested_parse_with_titles
return state.nested_parse(content, 0, node, match_titles=1)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
node=node, match_titles=match_titles)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/statemachine.py", line 239, in run
context, state, transitions)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/statemachine.py", line 460, in check_line
return method(match, context, next_state)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2328, in explicit_markup
self.explicit_list(blank_finish)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2358, in explicit_list
match_titles=self.state_machine.match_titles)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 319, in nested_list_parse
node=node, match_titles=match_titles)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/statemachine.py", line 239, in run
context, state, transitions)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/statemachine.py", line 460, in check_line
return method(match, context, next_state)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2631, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2338, in explicit_construct
return method(self, expmatch)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2081, in directive
directive_class, match, type_name, option_presets)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2130, in run_directive
result = directive_instance.run()
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/domains/__init__.py", line 285, in run
return super().run()
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/directives/__init__.py", line 209, in run
self.state.nested_parse(self.content, self.content_offset, contentnode)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
node=node, match_titles=match_titles)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 196, in run
results = StateMachineWS.run(self, input_lines, input_offset)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/statemachine.py", line 239, in run
context, state, transitions)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/statemachine.py", line 460, in check_line
return method(match, context, next_state)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2326, in explicit_markup
nodelist, blank_finish = self.explicit_construct(match)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2338, in explicit_construct
return method(self, expmatch)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2081, in directive
directive_class, match, type_name, option_presets)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/parsers/rst/states.py", line 2130, in run_directive
result = directive_instance.run()
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/domains/__init__.py", line 285, in run
return super().run()
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/directives/__init__.py", line 212, in run
self.domain, self.objtype, contentnode)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/application.py", line 445, in emit
return self.events.emit(event, *args)
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/events.py", line 107, in emit
results.append(listener.handler(self.app, *args))
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/sphinx/ext/autodoc/typehints.py", line 50, in merge_typehints
if signature['module']:
File "/storage/conda/envs/trtools_dev/lib/python3.5/site-packages/docutils/nodes.py", line 567, in __getitem__
return self.attributes[key]
KeyError: 'module'

# Fixed code
def merge_typehints(
    app: Sphinx, domain: str, objtype: str, contentnode: Element
) -> None:
    if domain != "py":
        return
    if app.config.autodoc_typehints != "description":
        return
    if objtype == "class" and app.config.autoclass_content not in ("init", "both"):
        return

    try:
        signature = cast(addnodes.desc_signature, contentnode.parent[0])
        if signature["module"]:
            fullname = ".".join([signature["module"], signature["fullname"]])
        else:
            fullname = signature["fullname"]
    except KeyError:
        # signature node does not have valid context info for the target object
        return

    annotations = app.env.temp_data.get("annotations", {})
    if annotations.get(fullname, {}):
        field_lists = [n for n in contentnode if isinstance(n, nodes.field_list)]
        if field_lists == []:
            field_list = insert_field_list(contentnode)
            field_lists.append(field_list)

        for field_list in field_lists:
            modify_field_list(field_list, annotations[fullname])