breathe icon indicating copy to clipboard operation
breathe copied to clipboard

KeyError: 'property'

Open MrKepzie opened this issue 4 years ago • 14 comments

Hi,

I'm getting the following crash when running breathe on the doxygen XML output. The doxygen HTML output works fine. The crash occurs both with breathe or using exhale as a meta generator.

# Sphinx version: 3.0.4
# Python version: 3.8.2 (CPython)
# Docutils version: 0.16 release
# Jinja2 version: 2.11.2
# Last messages:
#   reading sources... [  0%] UI/UICore
#   reading sources... [  0%] UI/index
#   reading sources... [  0%] UI/introduction
#   reading sources... [  0%] c++_code_guidelines
#   reading sources... [  0%] custom_dev_tools
#   reading sources... [  0%] git_workflow
#   reading sources... [  0%] index
#   reading sources... [  0%] misc_dev_hints
#   reading sources... [  0%] reference/classA
#   reading sources... [  0%] reference/classAGProject
# Loaded extensions:
#   sphinx.ext.mathjax (3.0.4) from /opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinx/ext/mathjax.py
#   sphinxcontrib.applehelp (1.0.2) from /opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinxcontrib/applehelp/__init__.py
#   sphinxcontrib.devhelp (1.0.2) from /opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinxcontrib/devhelp/__init__.py
#   sphinxcontrib.htmlhelp (1.0.3) from /opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinxcontrib/htmlhelp/__init__.py
#   sphinxcontrib.serializinghtml (1.1.4) from /opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinxcontrib/serializinghtml/__init__.py
#   sphinxcontrib.qthelp (1.0.3) from /opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinxcontrib/qthelp/__init__.py
#   alabaster (0.7.12) from /opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/alabaster/__init__.py
#   breathe (4.20.0) from /Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/__init__.py
#   exhale (0.2.3) from /Users/alexandre/Library/Python/3.8/lib/python/site-packages/exhale/__init__.py
#   sphinxjp.themes.basicstrap (unknown version) from /Users/alexandre/Library/Python/3.8/lib/python/site-packages/sphinxjp/themes/basicstrap/__init__.py
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinx/cmd/build.py", line 280, in build_main
    app.build(args.force_all, filenames)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinx/application.py", line 348, in build
    self.builder.build_update()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 297, in build_update
    self.build(to_build,
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 311, in build
    updated_docnames = set(self.read())
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 418, in read
    self._read_serial(docnames)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 439, in _read_serial
    self.read_doc(docname)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinx/builders/__init__.py", line 479, in read_doc
    doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinx/io.py", line 221, in read_doc
    pub.publish()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/core.py", line 217, in publish
    self.document = self.reader.read(self.source, self.parser,
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinx/io.py", line 126, in read
    self.parse()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/readers/__init__.py", line 77, in parse
    self.parser.parse(self.input, document)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinx/parsers.py", line 102, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 170, in run
    results = StateMachineWS.run(self, input_lines, input_offset,
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/statemachine.py", line 241, in run
    context, next_state, result = self.check_line(
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/statemachine.py", line 459, in check_line
    return method(match, context, next_state)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
    newabsoffset = self.nested_parse(
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
    state_machine.run(block, input_offset, memo=self.memo,
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/statemachine.py", line 241, in run
    context, next_state, result = self.check_line(
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/statemachine.py", line 459, in check_line
    return method(match, context, next_state)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2769, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
    newabsoffset = self.nested_parse(
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
    state_machine.run(block, input_offset, memo=self.memo,
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/statemachine.py", line 241, in run
    context, next_state, result = self.check_line(
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/statemachine.py", line 459, in check_line
    return method(match, context, next_state)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2342, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
    return method(self, expmatch)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2096, in directive
    return self.run_directive(
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
    result = directive_instance.run()
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/directives.py", line 301, in run
    return self.render(matches[0], project_info, filter_, target_handler, mask_factory,
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/directive/base.py", line 96, in render
    return object_renderer.render(node_stack[0], context)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 1810, in render
    result = method(self, node)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 1730, in dispatch_compound
    return self.visit_compound(node)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 915, in visit_compound
    return self.visit_class(node)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 866, in visit_class
    nodes = self.handle_declaration(nodeDef, declaration, content_callback=content,
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 527, in handle_declaration
    nodes_ = self.run_directive(obj_type, declaration, content_callback, options)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 492, in run_directive
    nodes = directive.run()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinx/domains/cpp.py", line 6527, in run
    return super().run()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/sphinx/directives/__init__.py", line 210, in run
    self.transform_content(contentnode)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 67, in transform_content
    callback(contentnode)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 861, in content
    rendered_data = self.render(file_data, parent_context)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 1810, in render
    result = method(self, node)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 785, in visit_doxygendef
    return self.render(node.compounddef)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 1810, in render
    result = method(self, node)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 1087, in visit_compounddef
    child_nodes = self.render(sectiondef)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 1810, in render
    result = method(self, node)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 1130, in visit_sectiondef
    node_list.extend(self.render_iterable(node.memberdef))
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 1820, in render_iterable
    output.extend(self.render(entry))
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 1810, in render
    result = method(self, node)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 1745, in dispatch_memberdef
    return self.visit_variable(node)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 1599, in visit_variable
    return self.handle_declaration(node, declaration, options=options)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 527, in handle_declaration
    nodes_ = self.run_directive(obj_type, declaration, content_callback, options)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 472, in run_directive
    directive = DomainDirectiveFactory.create(self.context.domain, args)
  File "/Users/alexandre/Library/Python/3.8/lib/python/site-packages/breathe/renderer/sphinxrenderer.py", line 299, in create
    cls, name = DomainDirectiveFactory.cpp_classes[args[0]]  # type: ignore
KeyError: 'property'

MrKepzie avatar Sep 09 '20 10:09 MrKepzie

It looks like it assumes the code is C++, but it has a "property" entity. Which language is it supposed to be?

jakobandersen avatar Sep 09 '20 11:09 jakobandersen

Its is c++ but has custom macros passed to Qt moc

MrKepzie avatar Sep 09 '20 13:09 MrKepzie

I'm not familiar enough with Qt to know how a property is interpreted by Doxygen and hence how it should be rendered. As a variable? Basically an entry just needs to be added to the dictionary in https://github.com/michaeljones/breathe/blob/master/breathe/renderer/sphinxrenderer.py#L201, mapping the property to the Sphinx type+name.

jakobandersen avatar Sep 09 '20 14:09 jakobandersen

I don't seem to figure out why Doxygen output contains attributes of type kind="property". Here's the begining of the XML output of doxygen for the faulty file:

<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.8.18">
  <compounddef id="classAGProject" kind="class" language="C++" prot="public">
    <compoundname>AGProject</compoundname>
    <basecompoundref refid="classProjectInstance" prot="public" virt="non-virtual">ProjectInstance</basecompoundref>
    <includes refid="Project_8h" local="no">Project.h</includes>
      <sectiondef kind="property">
      <memberdef kind="property" id="classAGProject_1aa1d1248d58ed0cf85b3d59fe61cec677" prot="public" static="no" readable="yes" writable="no" gettable="no" privategettable="no" protectedgettable="no" settable="no" privatesettable="no" protectedsettable="no">
        <type><ref refid="classProjectItem" kindref="compound">ProjectItem</ref></type>
        <definition>ProjectItem AGProject::rootItem</definition>
        <argsstring></argsstring>
        <name>rootItem</name>
        <read>getRootProjectItem</read>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="/Users/alexandre/development/comper/AutoGraph/AppLib/Project.h" line="113" column="17" bodyfile="/Users/alexandre/development/comper/AutoGraph/AppLib/Project.h" bodystart="114" bodyend="-1"/>
      </memberdef>

The body of the C++ class contains this Qt macro:

Q_PROPERTY(ProjectItem* rootItem READ getRootProjectItem CONSTANT)

Which is expanded by the preprocessor as:

QT_ANNOTATE_CLASS(qt_property, VA_ARGS)

Which expands to nothing. Doxygen must be picking up on this. I'll try defining it explicitly to something else.

According to https://stackoverflow.com/questions/4914118/how-to-doxygen-comment-qt-properties Doxygen natively adds supports for Qt properties.

MrKepzie avatar Sep 09 '20 15:09 MrKepzie

I was able to get by adding this at the end of cpp_classes:

    'property': (CMacroObject, 'macro'),

MrKepzie avatar Sep 09 '20 16:09 MrKepzie

If Doxygen has native support for this, we could consider adding a mapping like posted above to Breathe if this is how properties work in general (as in: de facto standard usage of keyword). Otherwise a proper fix could be user-configurable types in cpp_classes via the usual configuration file.

vermeeren avatar Sep 10 '20 17:09 vermeeren

Just commenting to add that we were also bitten by this with our codebase and this fix was helpful. I'm still fighting some other errors, but this got me past one of them!

psifertex avatar Oct 20 '20 23:10 psifertex

I don't think the mapping to CMacroObject is a good idea, it is not a macro declaration. I guess a "property" is more akin to a member variable? Perhaps Breathe could construct a member declaration and send to Sphinx, and then put an additional annotation on the resulting doctree? Though, from https://doc.qt.io/qt-5/properties.html it looks like there can be quite a number of configuration knobs for properties. What should show up in the documentation? From the perspective of the user of the class, which usage patterns are enabled by declaring a property?

jakobandersen avatar Oct 24 '20 09:10 jakobandersen

Hello. I would like to use breathe for various Qt-based projects and probably you can expect more users because the Qt documentation tool (qdoc) became virtually unusable for anything except the Qt itself (there is a lot of difficulties, e.g. this one).

What should show up in the documentation?

A class is expected to get a new section "Properties" (example). A property can have a description and a set of associated methods. It is typical to have a getter (READ part in Q_PROPERTY macro), a setter (WRITE), and a notifier (NOTIFY) (example). The methods don't have their own documentation text — only the property itself is documented instead.

Some properties have reset methods (example), some can be CONSTANT and some can be backed by a member variable (MEMBER) instead of explicit getter/setter (Qt generates the getter/setter pair automatically).

It would be nice to get rid of the fatal error at first :). Then we can have basic support (property name + text). Advanced properties support would be welcome at any point later. :)

Thank you breathe developers for the project. I'm going to work around with CMacroObject for now and hope for basic support sometime later.

Kaffeine avatar Dec 05 '20 22:12 Kaffeine

I just came across this problem myself and "solved" it in exactly the same way, although obviously the documentation is not correct because it can't generate the relevant documentation, but it does at least parse.

fizzyade avatar Jan 29 '21 14:01 fizzyade

I also solved the same issue with the same temporary fix as @MrKepzie

sekargovindarajan avatar Mar 05 '21 14:03 sekargovindarajan

Hi,

I am also having this issue. I will also go for @MrKepzie fix in the meantime

# Sphinx version: 4.0.2
# Python version: 3.6.9 (CPython)
# Docutils version: 0.16 release
# Jinja2 version: 3.0.1
# Last messages:
#   updating environment:
#   
#   [extensions changed ('exhale')]
#   
#   3363 added, 0 changed, 0 removed
#   
#   reading sources... [  0%] api/classCalibrationEngine
#   
#   reading sources... [  0%] api/classCalibrationFilterImageModel
#   
# Loaded extensions:
#   sphinx.ext.mathjax (4.0.2) 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 (2.0.0) from /usr/local/lib/python3.6/dist-packages/sphinxcontrib/htmlhelp/__init__.py
#   sphinxcontrib.serializinghtml (1.1.5) 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
#   breathe (4.30.0) from /usr/local/lib/python3.6/dist-packages/breathe/__init__.py
#   exhale (0.2.3) from /usr/local/lib/python3.6/dist-packages/exhale/__init__.py
#   sphinx_rtd_theme (unknown version) from /usr/local/lib/python3.6/dist-packages/sphinx_rtd_theme/__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 350, in build
    self.builder.build_update()
  File "/usr/local/lib/python3.6/dist-packages/sphinx/builders/__init__.py", line 294, in build_update
    len(to_build))
  File "/usr/local/lib/python3.6/dist-packages/sphinx/builders/__init__.py", line 306, in build
    updated_docnames = set(self.read())
  File "/usr/local/lib/python3.6/dist-packages/sphinx/builders/__init__.py", line 413, in read
    self._read_serial(docnames)
  File "/usr/local/lib/python3.6/dist-packages/sphinx/builders/__init__.py", line 434, in _read_serial
    self.read_doc(docname)
  File "/usr/local/lib/python3.6/dist-packages/sphinx/builders/__init__.py", line 474, 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 188, 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 108, 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 100, 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/breathe/directives.py", line 293, in run
    self.directive_args)
  File "/usr/local/lib/python3.6/dist-packages/breathe/directive/base.py", line 96, in render
    return object_renderer.render(node_stack[0], context)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 2279, in render
    result = method(self, node)  # type: ignore
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 2166, in dispatch_compound
    return self.visit_compound(node)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 1063, in visit_compound
    return self.visit_class(node)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 1007, in visit_class
    display_obj_type=display_obj_type)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 637, in handle_declaration
    nodes_ = self.run_directive(obj_type, declaration, content_callback, options)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 596, in run_directive
    nodes = directive.run()
  File "/usr/local/lib/python3.6/dist-packages/sphinx/domains/cpp.py", line 6976, in run
    return super().run()
  File "/usr/local/lib/python3.6/dist-packages/sphinx/directives/__init__.py", line 209, in run
    self.transform_content(contentnode)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 67, in transform_content
    callback(contentnode)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 1001, in content
    rendered_data = self.render(file_data, parent_context)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 2279, in render
    result = method(self, node)  # type: ignore
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 924, in visit_doxygendef
    return self.render(node.compounddef)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 2279, in render
    result = method(self, node)  # type: ignore
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 1257, in visit_compounddef
    child_nodes = self.render(sectiondef)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 2279, in render
    result = method(self, node)  # type: ignore
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 1299, in visit_sectiondef
    node_list.extend(self.render_iterable(node.memberdef))
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 2289, in render_iterable
    output.extend(self.render(entry))
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 2279, in render
    result = method(self, node)  # type: ignore
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 2181, in dispatch_memberdef
    return self.visit_variable(node)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 1993, in visit_variable
    return self.handle_declaration(node, declaration, options=options)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 637, in handle_declaration
    nodes_ = self.run_directive(obj_type, declaration, content_callback, options)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 576, in run_directive
    directive = DomainDirectiveFactory.create(self.context.domain, args)
  File "/usr/local/lib/python3.6/dist-packages/breathe/renderer/sphinxrenderer.py", line 324, in create
    cls, name = DomainDirectiveFactory.cpp_classes[args[0]]  # type: ignore
KeyError: 'property'

Austriker avatar Jul 01 '21 13:07 Austriker

From the XML in https://github.com/michaeljones/breathe/issues/574#issuecomment-689622875 and the (Doxgen?-)-rendered example in https://github.com/michaeljones/breathe/issues/574#issuecomment-739421987 I think I have an idea of how this could be supported in Breathe. However, as I'm not familiar with Qt it would be great if one of you could create a minimal example project with a class that has every (or most) reasonable type of property declaration in it. This is needed to check the XML and figure out a scheme for how to extract data.

jakobandersen avatar Jul 06 '21 09:07 jakobandersen

So can we merge the workaround? This is still an issue 3 years later

waj334 avatar Feb 21 '23 22:02 waj334