-
Notifications
You must be signed in to change notification settings - Fork 21
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
Correctly handle case where "See Also" section follows "Examples" in global_enable_try_examples
#251
Merged
steppi
merged 7 commits into
jupyterlite:main
from
agriyakhetarpal:fix/don't-add-see-also-trailing-sections
Jan 13, 2025
Merged
Correctly handle case where "See Also" section follows "Examples" in global_enable_try_examples
#251
Changes from 3 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
f24cd2d
Add `..seealso` section as a pattern
agriyakhetarpal 10abc82
Fix escaping of regex characters
agriyakhetarpal 5f187f3
Reword comment about SymPy's special case
agriyakhetarpal 79e864e
Add subset of docutils + Sphinx directives to end at
agriyakhetarpal 08e70bd
Revert "Add subset of docutils + Sphinx directives to end at"
agriyakhetarpal 5397180
Reword comment about "See Also" section
agriyakhetarpal 631dfeb
Remove references to historical PRs
agriyakhetarpal File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is again not quite right. If you check line 311, it also checks for admonitions. The regex
rf"\.\. (rubric|admonition)::\s*{header}
will match..
followed by one ofrubric
oradmonition
, followed by any number of whitespace, followed by one of the headers in_non_example_docstring_headers
.But in at least SymPy, the See Also section doesn't get a directive like
.. admonition:: See Also
but just.. seealso:
. What I'm curious about is, for current versions of numpydocs, does a See Also section get the directive.. admonition:: See Also
like I assumed, or was I incorrect about this?Since the above logic does check for See Also sections, it can't be relevant that the See Also section shows up for old numpydoc versions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At some point someone should sit down and figure out what the generated directives can actually look like for each section header in mainline numpydoc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I spent some time debugging this and while I couldn't get a definite answer about what happens where in the code, here's what I have realised –
There are two things at play here:
.. seealso::
directive that's native to Sphinx, and a "See Also" section that upstreamnumpydoc
can interpret and convert to a rubric/admonition, which we correctly parse and escape with TryExamples'_next_section_pattern
if we retain compatibility with upstreamnumpydoc
.numpydoc
is dated and can't do this for SymPy's documentation, and thus we don't get to catch it.Therefore, a "See Also" section in the documentation for SciPy for an example, will caught in
numpydoc
, and this problem isn't specific to just.. seealso::
, all native Sphinx-based directives won't get caught. It's just that this hasn't been reported as a bug before because of the following reasons:A. most projects don't put anything after "Examples", and only SymPy that we know of (so far) has done so
B. Upstream
numpydoc
does indeed reorder the sections to some extent (which was my original comment a few commits ago, so I was right). Even if a project does add a section after "Examples", it gets caught by the pattern or re-ordered before it's rendered in the HTML.As a confirmation for point A, I tried another Sphinx directive from the page I linked above, such as
.. versionadded::
, and here we go:SymPy documentation screenshot with erroneous versionadded directive
The same experiment with NumPy confirms point B. For example, the docstring below:
NumPy's exceptions.AxisError docstring (modified)
where the "See Also" section is after the "Examples" section – where we could assume that it would be ordered in the same manner. However, generating the NumPy docs, it shows up before the examples:
Screenshot 1 from NumPy documentation
But, if you were to add the
.. versionadded::
directive or similar ones for NumPy, they are not reordered. I added a.. versionchanged:: Agriya debugging
directive after the Examples section, and this is what we get:NumPy documentation screenshots 2 and 3 with a native Sphinx-based directive after the Examples section
The HTML
and the interactive notebook
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to add almost all of the directives listed under https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#paragraph-level-markup to be able to restrict them from percolating into the notebooks; I don't think it makes sense to leave it with just
.. seealso
especially if others like..versionadded
are also included with both SymPy'snumpydoc
and the upstreamnumpydoc
.I used this command
to get a list:
and we know some Sphinx-specific directives (outside docutils) manually that aren't present in this list:
Only a subset of them will need to be added to the regex pattern, I assume?
(Edit: added a subset, please keep reading below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remembered this
numpydoc
PR from last year that was xref-ed from the NumPy PR where I had reported some incorrect ordering of the Attributes section, as it was showing up after the Examples section. It sheds some light on how the sections are ordered/reordered: numpy/numpydoc#571.The order preservation is mandated here: https://github.com/numpy/numpydoc/blob/6d5eb428b8acea6ced4d86d086e36daf3f03ffbf/numpydoc/validate.py#L28-L41, and via an error message in https://github.com/numpy/numpydoc/blob/6d5eb428b8acea6ced4d86d086e36daf3f03ffbf/numpydoc/validate.py#L61. We know that dictionaries are ordered in Python post 3.7.
Comparing the relevant code with SymPy's
numpydoc
: https://github.com/sympy/sympy/blob/3c33a8283cd02e2e012b57435bd6212ed915a0bc/doc/ext/docscrape_sphinx.py#L208-L240, not only are the headings and sections different, but also that upstreamnumpydoc
has a structural templating mechanism thingy where an order is enforced, and SymPy's version explicitly calls_str_see_also
at the point where it wants the section to appear.So, to answer your question (quoting it below) with all I've mentioned:
If upstream
numpydoc
had not enforced the order, we would have also faced this SymPy-specific problem in NumPy. It is about the ordering of the sections rather than what the sections are themselves (whether Sphinx directives or named sections innumpydoc
).Upstream
numpydoc
also has https://github.com/numpy/numpydoc/blob/6d5eb428b8acea6ced4d86d086e36daf3f03ffbf/numpydoc/validate.py#L24-L27 to run checks version-changed directives like the above, but it does not enforce an order for them as they are not a part of standard sections but are directives.So, I think we should indeed add at least a few of these directives to the patterns we need to ignore – maybe just the most commonly used ones from the above list will work. This would help in both getting SymPy to play nicely, and in the scenario that some docstrings are incorrectly added to any other projects that use the modern
numpydoc
, we don't let that mistake in with the interactive examples.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the same time, if someone were to put a directive in the middle of a doctest, that could cause a bug report for us because the doctest would end midway... but I feel we're technically correct and we could say "works as intended" and close it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a minimal set of directives to halt at in commit 79e864e and this shouldn't cause any problematic behaviour with most websites, while also getting us working with SymPy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still confused. The documentation for
TryExamples
says thisCan you end up with a raw Sphinx heading directive inside of the processed docstring when using numpydoc or sphinx.ext.napoleon when using them properly?
I still think if the current implementation only works because of the enforced ordering, then it's because it was only working incidentally because of the enforced ordering, because the code is trying to catch all possible next section directive patterns for numpydoc.