breathe icon indicating copy to clipboard operation
breathe copied to clipboard

visit_friendclass assertion kills the build for complex types

Open JohnVidler opened this issue 3 years ago • 0 comments

Versions:

Sphinx - 4.5.0
breathe - 4.34.0
exhale - 0.3.4
doxygen - 1.9.1

Relevent input files: ManagedString.h --> https://github.com/lancaster-university/codal-core/blob/master/inc/types/ManagedString.h

On line 2192 of spinxrenderer.py ( https://github.com/michaeljones/breathe/blob/master/breathe/renderer/sphinxrenderer.py#L2192 ) the line assert typ in ("friend class", "friend struct", "class", "struct") is too restrictive, and causes the entire render process to fail when typ is a valid, if complex type, such as const ManagedString &

Experimentally, I have simply commented out the assertion to see what the result is, and it does seem to produce correct output HTML, but patching this in for each build is obviously fragile.

I'm seeing this when attempting to build a pretty complex codebase which includes some slightly magic classes for handling memory in an embedded system (The Micro:bit), the full build logs for this can be found here: https://github.com/lancaster-university/codal-documentation/runs/7097058452 and I modified the file to immediately raise an exception when reaching this point, and print the contents of the typ variable:

...
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 2612 source files that are out of date
updating environment: [new config] 2612 added, 0 changed, 0 removed
/opt/build/docs/source/api/classcodal_1_1CodalComponent.rst:56: WARNING: Duplicate C++ declaration, also defined at api/classcodal_1_1CodalComponent:56.                                                                          
Declaration is '.. cpp:type:: enum codal::CodalComponent::deepSleepCallbackReason deepSleepCallbackReason'.
/opt/build/docs/source/api/classcodal_1_1CodalComponent.rst:56: WARNING: Duplicate C++ declaration, also defined at api/classcodal_1_1CodalComponent:56.
Declaration is '.. cpp:struct:: deepSleepCallbackData'.

Exception occurred:
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 2190, in visit_friendclass
    raise Exception( F"FORCED ERR: TYP = {typ}" )
Exception: FORCED ERR: TYP = const ManagedString &

The complete exception log is as follows:

# Sphinx version: 4.5.0
# Python version: 3.10.4 (CPython)
# Docutils version: 0.17.1 release
# Jinja2 version: 3.1.2
# Last messages:
#   reading sources... [  1%] api/classcodal_1_1LevelDetector
#   reading sources... [  1%] api/classcodal_1_1LevelDetectorSPL
#   reading sources... [  1%] api/classcodal_1_1LinearAnalogSensor
#   reading sources... [  2%] api/classcodal_1_1LowLevelTimer
#   reading sources... [  2%] api/classcodal_1_1MAG3110
#   reading sources... [  2%] api/classcodal_1_1MMA8453
#   reading sources... [  2%] api/classcodal_1_1MMA8653
#   reading sources... [  2%] api/classcodal_1_1MPU6050
#   reading sources... [  2%] api/classcodal_1_1ManagedBuffer
#   reading sources... [  2%] api/classcodal_1_1ManagedString
# Loaded extensions:
#   sphinx.ext.mathjax (4.5.0) from /usr/local/lib/python3.10/dist-packages/sphinx/ext/mathjax.py
#   sphinxcontrib.applehelp (1.0.2) from /usr/local/lib/python3.10/dist-packages/sphinxcontrib/applehelp/__init__.py
#   sphinxcontrib.devhelp (1.0.2) from /usr/local/lib/python3.10/dist-packages/sphinxcontrib/devhelp/__init__.py
#   sphinxcontrib.htmlhelp (2.0.0) from /usr/local/lib/python3.10/dist-packages/sphinxcontrib/htmlhelp/__init__.py
#   sphinxcontrib.serializinghtml (1.1.5) from /usr/local/lib/python3.10/dist-packages/sphinxcontrib/serializinghtml/__init__.py
#   sphinxcontrib.qthelp (1.0.3) from /usr/local/lib/python3.10/dist-packages/sphinxcontrib/qthelp/__init__.py
#   alabaster (0.7.12) from /usr/local/lib/python3.10/dist-packages/alabaster/__init__.py
#   breathe (4.34.0) from /usr/local/lib/python3.10/dist-packages/breathe/__init__.py
#   exhale (0.3.4) from /usr/local/lib/python3.10/dist-packages/exhale/__init__.py
#   sphinx.ext.githubpages (4.5.0) from /usr/local/lib/python3.10/dist-packages/sphinx/ext/githubpages.py
#   sphinx_book_theme (unknown version) from /usr/local/lib/python3.10/dist-packages/sphinx_book_theme/__init__.py
#   pydata_sphinx_theme (unknown version) from /usr/local/lib/python3.10/dist-packages/pydata_sphinx_theme/__init__.py
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/sphinx/cmd/build.py", line 276, in build_main
    app.build(args.force_all, filenames)
  File "/usr/local/lib/python3.10/dist-packages/sphinx/application.py", line 330, in build
    self.builder.build_update()
  File "/usr/local/lib/python3.10/dist-packages/sphinx/builders/__init__.py", line 286, in build_update
    self.build(to_build,
  File "/usr/local/lib/python3.10/dist-packages/sphinx/builders/__init__.py", line 300, in build
    updated_docnames = set(self.read())
  File "/usr/local/lib/python3.10/dist-packages/sphinx/builders/__init__.py", line 407, in read
    self._read_serial(docnames)
  File "/usr/local/lib/python3.10/dist-packages/sphinx/builders/__init__.py", line 428, in _read_serial
    self.read_doc(docname)
  File "/usr/local/lib/python3.10/dist-packages/sphinx/builders/__init__.py", line 468, in read_doc
    doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
  File "/usr/local/lib/python3.10/dist-packages/sphinx/io.py", line 181, in read_doc
    pub.publish()
  File "/usr/local/lib/python3.10/dist-packages/docutils/core.py", line 217, in publish
    self.document = self.reader.read(self.source, self.parser,
  File "/usr/local/lib/python3.10/dist-packages/sphinx/io.py", line 101, in read
    self.parse()
  File "/usr/local/lib/python3.10/dist-packages/docutils/readers/__init__.py", line 78, in parse
    self.parser.parse(self.input, document)
  File "/usr/local/lib/python3.10/dist-packages/sphinx/parsers.py", line 89, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 170, in run
    results = StateMachineWS.run(self, input_lines, input_offset,
  File "/usr/local/lib/python3.10/dist-packages/docutils/statemachine.py", line 239, in run
    context, next_state, result = self.check_line(
  File "/usr/local/lib/python3.10/dist-packages/docutils/statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 2769, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
    newabsoffset = self.nested_parse(
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
    state_machine.run(block, input_offset, memo=self.memo,
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/usr/local/lib/python3.10/dist-packages/docutils/statemachine.py", line 239, in run
    context, next_state, result = self.check_line(
  File "/usr/local/lib/python3.10/dist-packages/docutils/statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 2769, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 393, in new_subsection
    newabsoffset = self.nested_parse(
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 281, in nested_parse
    state_machine.run(block, input_offset, memo=self.memo,
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/usr/local/lib/python3.10/dist-packages/docutils/statemachine.py", line 239, in run
    context, next_state, result = self.check_line(
  File "/usr/local/lib/python3.10/dist-packages/docutils/statemachine.py", line 451, in check_line
    return method(match, context, next_state)
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 2342, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 2354, in explicit_construct
    return method(self, expmatch)
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 2096, in directive
    return self.run_directive(
  File "/usr/local/lib/python3.10/dist-packages/docutils/parsers/rst/states.py", line 2146, in run_directive
    result = directive_instance.run()
  File "/usr/local/lib/python3.10/dist-packages/breathe/directives/class_like.py", line 62, in run
    return self.render(
  File "/usr/local/lib/python3.10/dist-packages/breathe/directives/__init__.py", line 121, in render
    return object_renderer.render(node_stack[0], context)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 2603, in render
    result = method(self, node)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 2483, in dispatch_compound
    return self.visit_compound(node)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 1154, in visit_compound
    return self.visit_class(node)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 1094, in visit_class
    nodes = self.handle_declaration(
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 667, in handle_declaration
    nodes_ = self.run_directive(obj_type, declaration, content_callback, options)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 619, in run_directive
    nodes = directive.run()
  File "/usr/local/lib/python3.10/dist-packages/sphinx/domains/cpp.py", line 7216, in run
    return super().run()
  File "/usr/local/lib/python3.10/dist-packages/sphinx/directives/__init__.py", line 201, in run
    self.transform_content(contentnode)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 70, in transform_content
    callback(contentnode)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 1089, in content
    rendered_data = self.render(file_data, parent_context)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 2603, in render
    result = method(self, node)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 1008, in visit_doxygendef
    return self.render(node.compounddef)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 2603, in render
    result = method(self, node)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 1360, in visit_compounddef
    child_nodes = self.render(sectiondef)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 2603, in render
    result = method(self, node)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 1402, in visit_sectiondef
    node_list.extend(self.render_iterable(node.memberdef))
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 2613, in render_iterable
    output.extend(self.render(entry))
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 2603, in render
    result = method(self, node)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 2507, in dispatch_memberdef
    return self.visit_friendclass(node)
  File "/usr/local/lib/python3.10/dist-packages/breathe/renderer/sphinxrenderer.py", line 2190, in visit_friendclass
    raise Exception( F"FORCED ERR: TYP = {typ}" )
Exception: FORCED ERR: TYP = const ManagedString &

JohnVidler avatar Jun 29 '22 07:06 JohnVidler