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

Referenced targets defined in docstrings are unresolved in summaries #293

Open
funkyfuture opened this issue Sep 16, 2023 · 8 comments
Open

Comments

@funkyfuture
Copy link
Contributor

assuming that a documented docstring contains a hyperlink in this form:

def foo():
    """
    See this_ for more.

    .. _this: https://this.net
    """

the build doesn't find that target: ERROR: Unknown target name: "this".

a workaround is to define the targets in the text document that includes the automodule directive which eventually includes the function.

@2bndy5
Copy link
Collaborator

2bndy5 commented Sep 16, 2023

I think you're just fighting scoping. What happens if you define the URL first, then refer to it after it is defined?

@funkyfuture
Copy link
Contributor Author

thanks for the hint, that works. but i'd consider that a workaround as well as it deviates from the common behaviour. and the source code's contents are rather weird, it's like starting a text with end notes.

@funkyfuture
Copy link
Contributor Author

it may be worth mentioning that this only affects HTML pages with summaries, for the individual page that documents foo everything is fine. setting the generate_synopses option to None doesn't change the results.

@2bndy5
Copy link
Collaborator

2bndy5 commented Sep 16, 2023

As for being specific to this theme, I don't know where to fix that; the "pages with summaries" tidbit sounds like a lead. The stuff you put in docstrings gets parsed "separately" from rst file content; this is due to using the sphinx.ext.autodoc extension's API. Some of that API maybe monkey-patched by this theme to implement certain features. @funkyfuture Can you disclose more detail like a sample project (in a .zip file) that can reproduce this?


I don't think of it as a workaround; it's just more declarative writing to me.

If I reference a substitution more than once in multiple docstrings of a module, then I'd put the definition in either the

  • module-level docstring (requires use of automodule directive)
  • rst_prolog to use a substitution in multiple pages.

Both of which use the define-substitution first approach. If I need to use the same substitution multiple times in the same docstring, then I still put it before the first reference. It may look like "starting a text with end notes", but I see it as a rst comment or rst metadata (and my eyes skim past it).

Although I do see that the docutils example does not define the substitution first.

@funkyfuture
Copy link
Contributor Author

thanks for the feedback.

i meanwhile found out that my initial description doesn't cover all. i found one case where the mentioned workaround doesn't help and also the references to sections with :ref:`Section Title` can be affected.

i'm occasionaly working on migrating / evaluating an existing, not too uncomplex documentation to this theme; i can provide an archive, but would like to progress a little more before i share it.


it's just more declarative writing to me.

but should the usage of a theme require a specific style for docstrings?

If I reference a substitution more than once in multiple docstrings

i may have several references to the same external target all across the general prose and docstrings of a documentation. particularly within docstrings the possible redundancy is useful as the docstrings are self-contained and complete for readers of the source code.

but I see it as a rst comment or rst metadata (and my eyes skim past it).

as a human reader whose first impulse is not to parse the text into abstract categories, i don't agree. neither have i ever seen that form in the wild. functionally the foot-/endnote allegory works for me.

@jbms
Copy link
Owner

jbms commented Sep 16, 2023

The summary is currently generated by first applying any text transformations to the docstring (e.g. sphinx.ext.napoleon) and then extracting the first paragraph (by presence of newline characters) textually, then parsing it as rST within the context of the summary document.

https://github.com/jbms/sphinx-immaterial/blob/52384ce01d95151d65d1b865dd7e73ad5a4d6e00/sphinx_immaterial/apidoc/python/apigen.py#L584C35-L584C35

def _summarize_rst_content(content: List[str]) -> List[str]:

This saves the cost of parsing an entire long docstring only to throw away most of the result, and also avoids other issues that might occur such as duplicate labels, assuming no labels are defined in the first paragraph.

However, it doesn't work with the footnote hyperlink syntax. A different strategy would be needed to support that.

@funkyfuture funkyfuture changed the title Hyperlink targets defined in docstrings get lost Referenced targets defined in docstrings are unresolved in summaries Sep 17, 2023
@funkyfuture
Copy link
Contributor Author

thanks for the explanation. without knowledge of the overall build process; wouldn't it be best to produce (and cache) all the HTML output and derive the summaries from that?

or what about dismissing links to other resources in the summaries altogether? atm i think that is a proper result, in any case it's preferable to broken links.

@jbms
Copy link
Owner

jbms commented Sep 17, 2023

The document is built by first parsing each rST document into an intermediate document tree, performing a number of transformations on all of the document trees, and then converting each document tree to html.

I think the footnote-type references are resolved as an early transformation right after parsing the rST.

Extracting summaries from the html is problematic because the document trees are all built before any html is generated. In principle the summary could be extracted from the document tree of the one document that contains the full version of the description, and then substituted like a resolved reference where the summary is required.

Not sure if that would be the best solution, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants