Skip to content

Fix LaTeX builder crash on tables with no body rows - #14291

Open
veeceey wants to merge 1 commit into
sphinx-doc:masterfrom
veeceey:fix/latex-empty-table-stopiteration
Open

Fix LaTeX builder crash on tables with no body rows#14291
veeceey wants to merge 1 commit into
sphinx-doc:masterfrom
veeceey:fix/latex-empty-table-stopiteration

Conversation

@veeceey

@veeceey veeceey commented Feb 10, 2026

Copy link
Copy Markdown

Summary

Fixes #14271.

LaTeXFootnoteVisitor.depart_table() unconditionally calls next(node.findall(nodes.tbody)), which raises StopIteration when a table has header rows but no body rows. This happens when external parsers like myst_parser produce a docutils table node tree from Markdown tables that have only a header row (e.g. | Key | P | Summary |\n| --- | --- | --- |).

The fix:

  • Use next(..., None) to safely handle the missing tbody
  • When tbody is present, behavior is unchanged (footnotes are inserted at the head of tbody)
  • When tbody is absent, any collected table footnotes are placed after the table node instead, preserving footnote rendering

Test:

  • Added test_latex_table_empty_body which constructs a table node with thead but no tbody (mirroring what myst_parser produces) and verifies that LaTeXFootnoteVisitor processes it without raising StopIteration
  • Verified the test fails with StopIteration on the unfixed code and passes with the fix
  • All existing LaTeX builder tests continue to pass

Test plan

  • New unit test test_latex_table_empty_body passes
  • All existing LaTeX table tests pass (9/9)
  • All existing LaTeX footnote tests pass (5/5)
  • Full LaTeX test suite passes (82 passed, 11 skipped for missing LaTeX styles)
  • ruff check passes on both modified files

The LaTeXFootnoteVisitor.depart_table() method called
next(node.findall(nodes.tbody)) which raises StopIteration when a
table has header rows but no body rows (as produced by e.g. myst_parser
from Markdown). Handle the missing tbody gracefully by placing any
collected footnotes after the table node instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@veeceey

veeceey commented Feb 19, 2026

Copy link
Copy Markdown
Author

Friendly ping - any chance someone could take a look at this when they get a chance? Happy to make any changes if needed.

@veeceey
veeceey force-pushed the fix/latex-empty-table-stopiteration branch from 795d52a to 6bbbc96 Compare February 24, 2026 07:47
Comment on lines +2108 to +2110
from docutils.utils import new_document

from sphinx.builders.latex.transforms import LaTeXFootnoteVisitor

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put those imports at the top.

fntext = footnotetext('', *footnote.children, ids=footnote['ids'])
tbody.insert(0, fntext)
tbody = next(node.findall(nodes.tbody), None)
if tbody is not None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swap the if-blocks (more natural to have if tbody is None first)

# If there is no tbody (e.g. a table with only header rows),
# place any collected footnotes after the table node instead.
table_parent = node.parent
if table_parent is not None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check that the parent is indeed a table.

assert app.warning.getvalue() == ''


def test_latex_table_empty_body() -> None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a new test case but not handwritten one.

@jfbu jfbu added this to the 9.1.1 milestone Jun 9, 2026
@jdillard jdillard added the awaiting:response Waiting for a response from the author of this issue label Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting:response Waiting for a response from the author of this issue builder:latex

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error generating latex from Markdown with empty table

4 participants