[pydocstyle] Skip section detection inside RST directive bodies (D214, D405, D413) - #23635
Conversation
…214`, `D405`, `D413`) Closes astral-sh#23562 Content inside reStructuredText directives (e.g., `.. code-block:: yaml`) was incorrectly identified as docstring section headers. For example, `references:` inside a code-block would trigger D405 (capitalization), D214 (over-indentation), and D413 (missing blank line). This adds RST directive body tracking to `from_docstring` in the section parser. When a line starting with `.. ` is detected, all subsequent lines indented deeper than the directive are skipped from section detection. Real sections after directives continue to be detected correctly.
|
ntBre
left a comment
There was a problem hiding this comment.
Thanks for working on this and sorry for the delay. This looks good to me overall, I just had one question about nested section handling. CI is also failing, but I think it's just from a change to our lines of context in the snapshot tests and should be easy to regenerate.
|
Updated this, thanks. I changed the directive tracking from a single active indent to a stack, so exiting an inner directive keeps the outer directive body active. I also added the nested |
ntBre
left a comment
There was a problem hiding this comment.
Thank you! And sorry again for the delay. This looks good to me. I think I was too hasty with abandoning the Option in favor of a stack. I pushed a small suggestion from Codex to simplify back to an Option and merged the snapshot updates from main, but this otherwise looked great to me.
Summary
Fixes #23562.
Content inside reStructuredText directives (e.g.,
.. code-block:: yaml) was incorrectly identified as docstring section headers. For example,references:inside a code-block would trigger D405 (capitalization), D214 (over-indentation), and D413 (missing blank line).The root cause is that the section parser in
from_docstring(docstrings/sections.rs) iterates docstring lines and callsis_docstring_sectionwith no awareness of RST directive blocks. The wordreferencesmatchesSectionKind::References, the suffix:passes the section name check, and the preceding blank line (required by RST after the directive declaration) satisfies the end-of-paragraph heuristic.There is already existing RST awareness in
blanks_and_section_underline(theis_sphinxcheck at lines 1593 and 1691), but that serves a different purpose — it preserves blank lines when a real section header likeExample:has a.. code-block::directive as its body content. This fix is complementary: it prevents content inside a directive body from being misidentified as section headers in the first place.This adds RST directive body tracking to
from_docstring. When a line starting with..is detected (an RST directive), all subsequent lines indented deeper than the directive are skipped from section detection. Real sections after directives continue to be detected correctly.Test Plan
Added
sphinx_directive.pytest fixture with cases for:.. code-block:: yamlcontainingreferences:(the exact case from ruff incorrectly reformatting Sphinx docstrings #23562)Returns:).. code-block: yaml).. note::containing.. code-block::)Notes:) following a directive — verifies sections after directives are still detectedRegistered test cases for
D214,D405, andD413against the new fixture. All 72 pydocstyle tests pass:Also manually verified the original reproduction case no longer triggers D405/D214/D413 false positives.