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

Improve cross-reference documentation #12944

Merged
merged 4 commits into from
Oct 3, 2024
Merged

Conversation

timhoffm
Copy link
Contributor

@timhoffm timhoffm commented Oct 2, 2024

Closes #12940.

Rewrite / reformat the introductory paragraph on cross-references and the python cross-reference docs.

I also propose to move the :any: role documentation to the bottom of the page. It's a rather niche application since specific roles are typically more concise, less error-prone and not more effort to type.

It's a rather niche application since specific roles are
typically more concise, less error-prone and not more
effort to type.
@mgeier
Copy link
Contributor

mgeier commented Oct 3, 2024

I also propose to move the :any: role documentation to the bottom of the page. It's a rather niche application since specific roles are typically more concise, less error-prone and not more effort to type.

I'm fine with moving the documentation down, but I want to object to it being a "niche application".
If it really is, then it shouldn't be!

I'm using it in basically all of my Python module documentations as default_role, as recommended in the documentation, and it works great.

This makes my Python docstrings more concise, much more readable (in the Python source) and less effort to type.


UPDATE: I now recommend using py:obj as default_role, see #12944 (comment).

@AA-Turner AA-Turner merged commit 4080be1 into sphinx-doc:master Oct 3, 2024
8 checks passed
@timhoffm timhoffm deleted the doc-ref branch October 3, 2024 17:09
Comment on lines +52 to +71
Some of the built-in cross-reference roles are:

* :rst:role:`:any: <any>`,
:rst:role:`:doc: <doc>`,
:rst:role:`:ref: <ref>`
* :rst:role:`:confval: <confval>`,
:rst:role:`:envvar: <envvar>`,
:rst:role:`:option: <option>`
* :rst:role:`:manpage: <manpage>`,
:rst:role:`:pep: <pep>`,
:rst:role:`:rfc: <rfc>`
* :rst:role:`download`,
:rst:role:`:index: <index>`
:rst:role:`:numref: <numref>`,
:rst:role:`:keyword: <keyword>`,
:rst:role:`:term: <term>`,
:rst:role:`:token: <token>`
* :rst:role:`!:func:`
(this uses the :confval:`primary_domain`, e.g. :rst:role:`:py:func: <py:func>`)
* :ref:`Domain cross-reference roles <ref-objects>`
Copy link
Contributor Author

@timhoffm timhoffm Oct 3, 2024

Choose a reason for hiding this comment

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

As a short feedback, I find this listing not too helpful for the following reasons:

  • The listing alomost replicates the toc of the the page.
    grafik
    The only missing items there are manpage, pep, rfc. But possibly they should also get a section on this page?
  • The roles are given without context. While names are partially self-explanatory, you could give some category names to the bullet points.
  • Stating "some" with a long list is unsettling. If possible we should make the list complete, or at the very least change the wording to "The most important ..." or similar.

Given the toc, I suggest that we can live without that list. But if you want to keep it, I suggest a bit of rework based on the above comments.

Copy link
Member

Choose a reason for hiding this comment

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

Gone: 5eb68b2

The intent was to highlight the breath of roles that support cross referencing, but was perhaps ill-conceived.

A

Choose a reason for hiding this comment

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

@timhoffm

typo:

(...) prefix shortens the link text the last component of the target.

should be:

(...) prefix shortens the link text to the last component of the target.



The roles are given without context. While names are partially self-explanatory, you could give some category names to the bullet points.

In this case less is more. I feel the TOC is repetitive by always starting with the verb "Cross-referencing XYZ" but the corresponding headings work well reading through the document. Adding more intro text under each heading would be a mistake because it would add clutter and waste the reader's time. (As a comparison: did you ever notice how the first half of most videos should be skipped because it just repeats an intro we already know? So lets skip the formalism of adding intros under the headings.)



The only missing items there are manpage, pep, rfc. But possibly they should also get a section on this page?

Untangling scope overlap of the Cross-referencing syntax doc with the Roles doc should be posted separately as an issue. It seems like a complex decision.



I'm using it in basically all of my Python module documentations as default_role, as recommended in the documentation, and it works great.

@mgeier We've had a number of users asking for help about ambiguous error messages caused by :any: when later something changes in the code (and they were using shortened syntax in the qualified name for example). Personally I always pinpoint the exact role to reduce ambiguity for myself and the reader -this also helps keep error messages more accurate- hence I don't use default_role.

This makes my Python docstrings more concise

I only write cross-references in the docstring when I absolutely must.

Copy link
Contributor

Choose a reason for hiding this comment

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

@electric-coder

This makes my Python docstrings more concise

I only write cross-references in the docstring when I absolutely must.

Well, that's your users' loss!

My docs are full of cross-references, see e.g. https://python-sounddevice.readthedocs.io/en/0.5.0/api/convenience-functions.html

Maybe you don't like writing them because they are so clunky when specifying the exact role?
Maybe you should do your users a favor and consider using default_role = 'any'?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A suitable default role depends on the type of documentation (size, how much and which kind of cross-links do you need, etc.) For example at matplotlib, we use the py:obj default role as a good middle-ground. We have a lot of code references and being able to write them often with just adding backticks keeps the doc sources very readable (particularly useful for docstrings that are often also used in plain text). For Python objects there is little ambiguity because the naming is determined by the code and you almost always want to have the function/class name exactly as is in the rendered docs.
We keep other references explicit, e.g. using :doc: or :ref: to prevent ambiguity. Also, by their nature, they are often longer and break the flow of reading anyway, so that adding the explicit prefixes does not make them significantly more clunky than they already are.

Copy link
Contributor

Choose a reason for hiding this comment

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

For example at matplotlib, we use the py:obj default role as a good middle-ground.

That is a good point, thanks for mentioning it!

When I experimented with this many years ago, py:obj had a severe limitation: it didn't allow me to use parentheses like this: `my_function()`. But it worked (and still works) fine with any.
That was the main reason why I used any in my documentations and I subsequently completely forgot about py:obj ... until now.

I just checked, and this limitation seems to have been lifted in the meantime!

Therefore, I now agree that :any: is a niche application and most Sphinx users should choose default_role = 'py:obj' in most of their (Python-based) projects!

I'm also doing that in the project I used as an example above: spatialaudio/python-sounddevice#567

@electric-coder
Copy link

electric-coder commented Oct 6, 2024

Maybe you don't like writing them because they are so clunky when specifying the exact role?

Actually no, I write a lot of cross-references in the .rst but I keep them out of the .py (hence out of the docstring) to keep the modules shorter. Considering the usual 80 char limit minus indentation it's better to unload reST complexity into its own file keeping just the bare minimum for autodoc. Besides, I also like the I/O spec just below the signatures (that's what users will be looking for most times) but in the docs you linked the arguments are specified only at the bottom after long explanations and I think that makes for a worst reader experience.

Sometimes I wish I had not taken the trouble of linking all my types like you :)

@mgeier
Copy link
Contributor

mgeier commented Oct 13, 2024

@electric-coder there is certainly a trade-off between writing documentation close to the source code and writing documentation without the limitations that you mention.

Either way, I'm convinced that a good amount of cross-references is very helpful for readers. At least it is for me!

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

Successfully merging this pull request may close these issues.

Document suppressing cross-references via ! prefix
4 participants