Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asserts out with template specialization for pointer types with breathe #5496

Closed
t-b opened this issue Sep 27, 2018 · 10 comments
Closed

asserts out with template specialization for pointer types with breathe #5496

t-b opened this issue Sep 27, 2018 · 10 comments
Assignees
Milestone

Comments

@t-b
Copy link

t-b commented Sep 27, 2018

Problem

Bugs out with the following assertion

E:\projekte\breathe-doxygen-filter-test\source\contents.rst:5: WARNING: Too many template argument lists compared to parameter lists. Argume
nt lists: 1, Parameter lists: 0, Extra empty parameters lists prepended: 1. Declaration:
        TemplateClass<T *>
E:\projekte\breathe-doxygen-filter-test\source\output\class\classTemplateClass.rst:4: WARNING: Duplicate declaration.
E:\projekte\breathe-doxygen-filter-test\source\output\class\classTemplateClass_3_01T_01_5_01_4.rst:4: WARNING: Too many template argument li
sts compared to parameter lists. Argument lists: 1, Parameter lists: 0, Extra empty parameters lists prepended: 1. Declaration:
        TemplateClass<T *>
E:\projekte\breathe-doxygen-filter-test\source\output\class\classTemplateClass_3_01T_01_5_01_4.rst:4: WARNING: Duplicate declaration.

Exception occurred:
  File "c:\anaconda2\lib\site-packages\sphinx\domains\cpp.py", line 4060, in _add_symbols
    assert len(withDecl) <= 1
AssertionError
The full traceback has been saved in c:\users\thomas\appdata\local\temp\sphinx-err-jugxnl.log, if you want to report the issue to the develo
pers.
Please also report this if it was a user error, so that a better error message can be provided next time.
A bug report can be filed in the tracker at <https://github.com/sphinx-doc/sphinx/issues>. Thanks!

C++ declarations:

/*!
A generic template class.
*/
template<typename T>
class TemplateClass
{
};

/*!
A partial specialization of TemplateClass for pointer types.
*/
template<typename T>
class TemplateClass<T*>
{
};

breathe code.

.. doxygenclass:: TemplateClass
   :project: test
   :no-link:

.. doxygenclass:: TemplateClass< T * >
   :project: test
   :no-link:

Procedure to reproduce the problem

git clone https://github.com/t-b/breathe-doxygen-filter-test
cd breathe-doxygen-filter-test
./run.sh

Error logs / results

# Sphinx version: 1.8.1
# Python version: 2.7.12 (CPython)
# Docutils version: 0.14 
# Jinja2 version: 2.10
# Last messages:
#   Running Sphinx v1.8.1
#   building [mo]: targets for 0 po files that are out of date
#   building [html]: targets for 6 source files that are out of date
#   updating environment:
#   6 added, 0 changed, 0 removed
#   reading sources... [ 16%] contents
#   reading sources... [ 33%] output/class/classTemplateClass
#   reading sources... [ 50%] output/class/classTemplateClass_3_01T_01_5_01_4
#   reading sources... [ 66%] output/classlist
#   reading sources... [ 83%] output/file/test_8cpp
# Loaded extensions:
#   sphinx.ext.mathjax (1.8.1) from c:\anaconda2\lib\site-packages\sphinx\ext\mathjax.pyc
#   alabaster (0.7.10) from c:\anaconda2\lib\site-packages\alabaster\__init__.pyc
#   breathe (4.10.0) from c:\anaconda2\lib\site-packages\breathe\__init__.pyc
Traceback (most recent call last):
  File "c:\anaconda2\lib\site-packages\sphinx\cmd\build.py", line 304, in build_main
    app.build(args.force_all, filenames)
  File "c:\anaconda2\lib\site-packages\sphinx\application.py", line 341, in build
    self.builder.build_update()
  File "c:\anaconda2\lib\site-packages\sphinx\builders\__init__.py", line 347, in build_update
    len(to_build))
  File "c:\anaconda2\lib\site-packages\sphinx\builders\__init__.py", line 360, in build
    updated_docnames = set(self.read())
  File "c:\anaconda2\lib\site-packages\sphinx\builders\__init__.py", line 468, in read
    self._read_serial(docnames)
  File "c:\anaconda2\lib\site-packages\sphinx\builders\__init__.py", line 490, in _read_serial
    self.read_doc(docname)
  File "c:\anaconda2\lib\site-packages\sphinx\builders\__init__.py", line 534, in read_doc
    doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
  File "c:\anaconda2\lib\site-packages\sphinx\io.py", line 318, in read_doc
    pub.publish()
  File "c:\anaconda2\lib\site-packages\docutils\core.py", line 217, in publish
    self.settings)
  File "c:\anaconda2\lib\site-packages\docutils\readers\__init__.py", line 72, in read
    self.parse()
  File "c:\anaconda2\lib\site-packages\docutils\readers\__init__.py", line 78, in parse
    self.parser.parse(self.input, document)
  File "c:\anaconda2\lib\site-packages\sphinx\parsers.py", line 88, in parse
    self.statemachine.run(inputstring, document, inliner=self.inliner)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 171, in run
    input_source=document['source'])
  File "c:\anaconda2\lib\site-packages\docutils\statemachine.py", line 239, in run
    context, state, transitions)
  File "c:\anaconda2\lib\site-packages\docutils\statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 2753, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 395, in new_subsection
    node=section_node, match_titles=True)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 282, in nested_parse
    node=node, match_titles=match_titles)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "c:\anaconda2\lib\site-packages\docutils\statemachine.py", line 239, in run
    context, state, transitions)
  File "c:\anaconda2\lib\site-packages\docutils\statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 2326, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 2338, in explicit_construct
    return method(self, expmatch)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 2081, in directive
    directive_class, match, type_name, option_presets)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 2130, in run_directive
    result = directive_instance.run()
  File "c:\anaconda2\lib\site-packages\breathe\directive\file.py", line 91, in run
    return self.handle_contents(file_, project_info)
  File "c:\anaconda2\lib\site-packages\breathe\directive\file.py", line 61, in handle_contents
    node_list.extend(object_renderer.render(node_stack[0], context))
  File "c:\anaconda2\lib\site-packages\breathe\renderer\sphinxrenderer.py", line 1304, in render
    result = method(self, node)
  File "c:\anaconda2\lib\site-packages\breathe\renderer\sphinxrenderer.py", line 630, in visit_compounddef
    nodelist.extend(self.render_iterable(node.innerclass))
  File "c:\anaconda2\lib\site-packages\breathe\renderer\sphinxrenderer.py", line 1314, in render_iterable
    output.extend(self.render(entry))
  File "c:\anaconda2\lib\site-packages\breathe\renderer\sphinxrenderer.py", line 1304, in render
    result = method(self, node)
  File "c:\anaconda2\lib\site-packages\breathe\renderer\sphinxrenderer.py", line 907, in visit_ref
    return self.visit_compound(node, False, get_node_info=get_node_info)
  File "c:\anaconda2\lib\site-packages\breathe\renderer\sphinxrenderer.py", line 508, in visit_compound
    name, kind)
  File "c:\anaconda2\lib\site-packages\breathe\renderer\sphinxrenderer.py", line 486, in render_signature
    nodes = self.run_domain_directive(kind, self.context.directive_args[1], augment=augment)
  File "c:\anaconda2\lib\site-packages\breathe\renderer\sphinxrenderer.py", line 351, in run_domain_directive
    nodes = domain_directive.run()
  File "c:\anaconda2\lib\site-packages\sphinx\domains\cpp.py", line 6312, in run
    return ObjectDescription.run(self)
  File "c:\anaconda2\lib\site-packages\sphinx\directives\__init__.py", line 161, in run
    name = self.handle_signature(sig, signode)
  File "c:\anaconda2\lib\site-packages\sphinx\domains\cpp.py", line 6332, in handle_signature
    symbol = parentSymbol.add_declaration(ast, docname=self.env.docname)
  File "c:\anaconda2\lib\site-packages\sphinx\domains\cpp.py", line 4151, in add_declaration
    return self._add_symbols(nestedName, templateDecls, declaration, docname)
  File "c:\anaconda2\lib\site-packages\sphinx\domains\cpp.py", line 4060, in _add_symbols
    assert len(withDecl) <= 1
AssertionError

Environment info

  • OS: Win
  • Python version: 2.7.12
  • Sphinx version: 1.8.1
@jakobandersen
Copy link
Contributor

jakobandersen commented Sep 27, 2018

Thanks a lot! From your output I think I know what is going on, and is seems I can be triggered as simple as:

.. cpp:class:: A

    Declaration.

.. cpp:class:: A

    Duplicate declaration.

.. cpp:class:: A

    Also duplicate, triggers the assert.

I'll try to make a fix soon(TM).

@ax3l
Copy link

ax3l commented Oct 11, 2018

The bug affects me as well and it looks like it was introduced in 1.8.*

@hchapman
Copy link

Just ran into this myself. Downgraded and sphinx 1.7 does not have the issue, whereas 1.8 did.

jakobandersen added a commit to jakobandersen/sphinx that referenced this issue Oct 11, 2018
If a symbol was declared more than 2 times, it would crash.

Fixes sphinx-doc#5496.
jakobandersen added a commit to jakobandersen/sphinx that referenced this issue Oct 11, 2018
If a symbol was declared more than 2 times, it would crash.

Fixes sphinx-doc#5496.
jakobandersen added a commit to jakobandersen/sphinx that referenced this issue Oct 11, 2018
If a symbol was declared more than 2 times, it would crash.

Fixes sphinx-doc#5496.
@jakobandersen
Copy link
Contributor

The issue should be fixed with PR #5526, though I have only tested with direct Sphinx input. @t-b, @ax3l, and @hchapman, if relatively easy for you, can you confirm it fixes your projects?

@ax3l
Copy link

ax3l commented Oct 11, 2018

I think I can only test it with my project locally if I somehow install the PR via pip. But with @t-b 's minimal example I am confident it will work for me as well, otherwise I will report back.

@jakobandersen
Copy link
Contributor

Great, merged to the 1.8 branch.
Note that while the assertion should no longer trigger, there will now be (another) warning about duplicate symbols. This is intended and an old problem which Sphinx is just (much) more verbose about now.
To get rid of them projects probably need #4981.

@t-b
Copy link
Author

t-b commented Oct 24, 2018

@jakobandersen Could you reopen?

With a clean test repo from above the first run passes.

But it bugs out on the second run with

# Sphinx version: 1.8.2+/da3c355
# Python version: 2.7.12 (CPython)
# Docutils version: 0.14 
# Jinja2 version: 2.10
# Last messages:
#   Running Sphinx v1.8.2+/da3c355
#   loading pickled environment...
#   done
#   building [mo]: targets for 0 po files that are out of date
#   building [html]: targets for 0 source files that are out of date
#   updating environment:
#   []
#   0 added, 4 changed, 0 removed
#   reading sources... [ 25%] contents
# Loaded extensions:
#   sphinx.ext.mathjax (1.8.2+/da3c355) from h:\projekte\devel\sphinx\sphinx\ext\mathjax.pyc
#   alabaster (0.7.10) from c:\anaconda2\lib\site-packages\alabaster\__init__.pyc
#   breathe (4.10.0) from c:\anaconda2\lib\site-packages\breathe\__init__.pyc
Traceback (most recent call last):
  File "h:\projekte\devel\sphinx\sphinx\cmd\build.py", line 304, in build_main
    app.build(args.force_all, filenames)
  File "h:\projekte\devel\sphinx\sphinx\application.py", line 341, in build
    self.builder.build_update()
  File "h:\projekte\devel\sphinx\sphinx\builders\__init__.py", line 347, in build_update
    len(to_build))
  File "h:\projekte\devel\sphinx\sphinx\builders\__init__.py", line 360, in build
    updated_docnames = set(self.read())
  File "h:\projekte\devel\sphinx\sphinx\builders\__init__.py", line 468, in read
    self._read_serial(docnames)
  File "h:\projekte\devel\sphinx\sphinx\builders\__init__.py", line 490, in _read_serial
    self.read_doc(docname)
  File "h:\projekte\devel\sphinx\sphinx\builders\__init__.py", line 534, in read_doc
    doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
  File "h:\projekte\devel\sphinx\sphinx\io.py", line 318, in read_doc
    pub.publish()
  File "c:\anaconda2\lib\site-packages\docutils\core.py", line 217, in publish
    self.settings)
  File "c:\anaconda2\lib\site-packages\docutils\readers\__init__.py", line 72, in read
    self.parse()
  File "c:\anaconda2\lib\site-packages\docutils\readers\__init__.py", line 78, in parse
    self.parser.parse(self.input, document)
  File "h:\projekte\devel\sphinx\sphinx\parsers.py", line 88, in parse
    self.statemachine.run(inputstring, document, inliner=self.inliner)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 171, in run
    input_source=document['source'])
  File "c:\anaconda2\lib\site-packages\docutils\statemachine.py", line 239, in run
    context, state, transitions)
  File "c:\anaconda2\lib\site-packages\docutils\statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 2326, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 2338, in explicit_construct
    return method(self, expmatch)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 2081, in directive
    directive_class, match, type_name, option_presets)
  File "c:\anaconda2\lib\site-packages\docutils\parsers\rst\states.py", line 2130, in run_directive
    result = directive_instance.run()
  File "c:\anaconda2\lib\site-packages\breathe\directives.py", line 312, in run
    self.directive_args)
  File "c:\anaconda2\lib\site-packages\breathe\directive\base.py", line 85, in render
    return object_renderer.render(node_stack[0], context)
  File "c:\anaconda2\lib\site-packages\breathe\renderer\sphinxrenderer.py", line 1304, in render
    result = method(self, node)
  File "c:\anaconda2\lib\site-packages\breathe\renderer\sphinxrenderer.py", line 1235, in dispatch_compound
    return self.visit_compound(node)
  File "c:\anaconda2\lib\site-packages\breathe\renderer\sphinxrenderer.py", line 508, in visit_compound
    name, kind)
  File "c:\anaconda2\lib\site-packages\breathe\renderer\sphinxrenderer.py", line 486, in render_signature
    nodes = self.run_domain_directive(kind, self.context.directive_args[1], augment=augment)
  File "c:\anaconda2\lib\site-packages\breathe\renderer\sphinxrenderer.py", line 351, in run_domain_directive
    nodes = domain_directive.run()
  File "h:\projekte\devel\sphinx\sphinx\domains\cpp.py", line 6318, in run
    return ObjectDescription.run(self)
  File "h:\projekte\devel\sphinx\sphinx\directives\__init__.py", line 161, in run
    name = self.handle_signature(sig, signode)
  File "h:\projekte\devel\sphinx\sphinx\domains\cpp.py", line 6338, in handle_signature
    symbol = parentSymbol.add_declaration(ast, docname=self.env.docname)
  File "h:\projekte\devel\sphinx\sphinx\domains\cpp.py", line 4157, in add_declaration
    return self._add_symbols(nestedName, templateDecls, declaration, docname)
  File "h:\projekte\devel\sphinx\sphinx\domains\cpp.py", line 4030, in _add_symbols
    assert len(withDecl) > 0
AssertionError

third run passes, fourth not and so on.

@ax3l
Copy link

ax3l commented Nov 5, 2018

ping @jakobandersen there seems to be a regression

@jakobandersen
Copy link
Contributor

Thanks, I'll take a look at it.

@jakobandersen
Copy link
Contributor

The assertion problem should be fixed in the 1.8 branch now (really).

While it shouldn't crash now, there is still a deeper issue with partial builds and duplicate declarations. Basically, if a declaration is modified/deleted and it has duplicates, then all documents with those duplicates should be rebuild as well. I'm not sure how to trigger this automatically though.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 9, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants