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

DOC: Clarify recommendations regarding use of backticks #525

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

mdhaber
Copy link

@mdhaber mdhaber commented Jan 14, 2024

The Style guide currently gives the following recommendations about backticks:

In the Parameters section:

Enclose variables in single backticks

In Other points to keep in mind:

For inline display use double backticks

In Common reST concepts:

Variable, module, function, and class names should be written between single back-ticks (numpy).

Contributors (and even maintainers) frequently interpret and/or apply these recommendations inconsistently. This PR attempts to clarify the recommendations to avoid multiple interpretations.

doc/format.rst Outdated Show resolved Hide resolved
doc/format.rst Outdated Show resolved Hide resolved

- Module, function, and class names should be enclosed within ```single
backticks```. These are intended to render as hyperlinks (e.g. `numpy`). If
the hyperlinks do not render as intended, [insert reference to documentation
Copy link
Author

Choose a reason for hiding this comment

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

Where should users be referred?

Copy link
Author

Choose a reason for hiding this comment

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

Suggestions on that to include here?

Copy link
Contributor

Choose a reason for hiding this comment

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

To me, the important distinction to make is: double-backticks is for monospace/code literals, single backticks are for references. If you want to attempt to link to something, use single backticks. If you just want monospace formatting without an attempted link, use double-backticks (the exception of course being numpydoc parameters).

Comment on lines +760 to +761
``monospaced`` hyperlink to the relevant definition in a future version of
numpydoc.
Copy link
Author

Choose a reason for hiding this comment

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

Perhaps this should be removed, but I wanted to mention it because it is the only reason I can see for using single backticks instead of double backticks. Otherwise, use of single backticks only causes problems with name collisions and renders in italics (which usually means "emphasis") where monospace (which means code) would be more clear.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd just remove this - it's probably more detail than most users are interested in (and is not necessarily correct - the actual rendering of e.g. italics is actually dictated by the sphinx theme).

@mdhaber mdhaber requested a review from rossbar January 14, 2024 18:52
@mdhaber mdhaber changed the title Clarify use of backticks DOC: Clarify recommendations regarding use of backticks Jan 14, 2024
Copy link
Contributor

@stefanv stefanv left a comment

Choose a reason for hiding this comment

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

Thanks @mdhaber! This looks good overall; I just have a few naive questions.

Enclose variables in single backticks. The colon must be preceded
by a space, or omitted if the type is absent.
The colon must be preceded by a space, or omitted if the type is absent.
When referring to a parameter in the description field or elsewhere within
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps this would be simpler as "referring to any parameter of the function being documented", or something along that vein?

Copy link
Author

Choose a reason for hiding this comment

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

So basically remove "in the description field or...". That's probably fine. I think I wanted to point out specifically that this advice was not limited to references within the parameter documentation, but maybe it's better overall to just keep it simple.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd vote for simple as well, something like:

When referring to a parameter elsewhere in the docstring, enclose its name in single backticks.

Copy link
Contributor

Choose a reason for hiding this comment

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

Where else can the variable live? Returns? Class docs, etc.?

Copy link
Author

Choose a reason for hiding this comment

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

I'm not sure I understand. Is the question about what constitutes a "parameter", where else a parameter might be mentioned, or something else?

doc/format.rst Show resolved Hide resolved
@@ -717,7 +726,9 @@ Other points to keep in mind
(i.e. scalar types, sequence types), those arguments can be documented
with type `array_like`.

* Links : If you need to include hyperlinks in your docstring, note that
* Links : Sphinx will automatically create hyperlinks to module, function,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this recommended practice? I think most libraries use :pyfunc: etc. Genuinely asking, I don't know.

Copy link
Author

Choose a reason for hiding this comment

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

It's what is done in SciPy, I think. I think Sphinx only needs more information if there is a name collision.

Copy link
Contributor

Choose a reason for hiding this comment

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

Again, I think this reaches beyond what numpydoc would recommend (see above). The original information here about name collisions is relevant

Is this recommended practice?

I think it's a tradeoff. With the standard configuration default_role = "py:obj:", using single backticks is equivalent to writing `:py:obj:`target`, which will attempt to link against most things (func, ref, meth, attr, etc.). The primary motivation for excluding the explicit roles is docstring readability in the terminal. However there's nothing to say that you can't or shouldn't use the explicit roles - that's perfectly valid and is up to the library to decide.

Copy link
Author

Choose a reason for hiding this comment

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

It's fine with me to add something about this being a project specific thing and mention the more explicit options, but if it is very common for projects to use single backticks, I think something should be mentioned. What can we say without over-stepping numpydoc's role?

* Links : If you need to include hyperlinks in your docstring, note that
* Links : Sphinx will automatically create hyperlinks to module, function,
and class documentation if a recognized name is included within single
backticks (e.g. `numpy`). If you need to include other hyperlinks, note that
Copy link
Author

@mdhaber mdhaber Jan 14, 2024

Choose a reason for hiding this comment

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

Suggested change
backticks (e.g. `numpy`). If you need to include other hyperlinks, note that
backticks (e.g. ```numpy``` renders as `numpy`). If you need to include other hyperlinks, note that

But it is not rendering correctly right now.

Copy link
Contributor

@rossbar rossbar left a comment

Choose a reason for hiding this comment

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

Thanks for bringing this up @mdhaber ! There's a lot of nice improvements here, though I think a lot of the recommendations on what to enclose in single backticks are beyond numpydoc's purview and shouldn't necessarily be recommended here.

The linking via single backticks is handled by sphinx proper, not numpydoc, and depends on the configuration and thoroughness of auto-generated stubs for each individual project.

I tend to think of the markup as:

  • double-backticks == monospace formatting with no linking
  • single-backticks == attempted linking

The thing that breaks the above is numpydoc's parameter recommendation, which is what I'd like to fix in #484

Enclose variables in single backticks. The colon must be preceded
by a space, or omitted if the type is absent.
The colon must be preceded by a space, or omitted if the type is absent.
When referring to a parameter in the description field or elsewhere within
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd vote for simple as well, something like:

When referring to a parameter elsewhere in the docstring, enclose its name in single backticks.

doc/format.rst Show resolved Hide resolved

When referring to an attribute in the description field or elsewhere within
Copy link
Contributor

Choose a reason for hiding this comment

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

The recommendations for methods/attributes are tricky - this is actually not something that numpydoc handles directly. The :meth: and :attr: are roles are built-in to sphinx itself. The fact that putting method and attribute names in single backticks references the relevant doc is a consequence of the sphinx default_role (which I believe is :py:obj: if not explicitly configured), which handles cross-references without any specific type information.

However, there are many cases where this would not be recommended - i.e. if a project uses something other than :py:obj: as the default role, then the cross-referencing may not work as expected leading broken links and nitpick warnings from sphinx. More likely, if a method or attribute does not have its own doc stub (i.e. it's excluded from the relevant autosummary directive), then this will also result in broken links.

In other words, I don't think this is a recommendation that numpydoc should be making. While it is generally good advice (for a standard sphinx configuration) it's not strictly handled by numpydoc thus not really part of the docstring standard, rather more general sphinx/rst advice. My vote would be to exclude these two recommendations, or link to relevant external sphinx docs to explain when wrapping Python objects in single backticks makes sense.

Copy link
Author

@mdhaber mdhaber Jan 20, 2024

Choose a reason for hiding this comment

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

I see. I would prefer not to remove these entirely.

Is it within numpydoc's purview to recommend that these be rendered as links?

If so, do I understand correctly that typical options will be 1) just single backticks, 2) single backticks preceded by :attr:, or 3) single backticks preceded by some other role, and that the choice is up to the project?

Copy link
Contributor

Choose a reason for hiding this comment

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

The single-backquote-around-a-parameter concept is part of the original numpydoc specification, though, so I'm not sure we can steer clear of it.

Not sure what to say about projects that reconfigure the default role. Technically, their docstrings are no longer numpydoc compliant, but it's not a big deal as long as they consistently use whichever roles they do.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks @stefanv for bringing this up again.

@rossbar can you suggest a compromise here? I think we need to address methods and attributes in some capacity. What can we say about them?

Copy link
Contributor

Choose a reason for hiding this comment

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

The single-backquote-around-a-parameter concept is part of the original numpydoc specification, though, so I'm not sure we can steer clear of it.

Yes, but this is only for the function parameters - recommending that class attributes and methods also be wrapped in single backticks relates to sphinx, not numpydoc, and is nowhere currently mentioned in the numpydoc standard. Generally speaking it's a fine thing to recommend, and if this were a sphinx tutorial I would be +1 for adding it - I'm only leery because this document "defines" the numpydoc docstring standard, and as written this would likely introduce more broken links in documentation (nor does it relate to the "function parameters should be in single backticks" recommendation that has been around since the beginning).

Not sure what to say about projects that reconfigure the default role. Technically, their docstrings are no longer numpydoc compliant

That's not strictly true - the numpydoc standard doesn't prescribe how projects configure the default_role and there are certainly cases where projects may want to override it. To make matters even more confusing, the default_role configuration value can be overridden with the .. default-role:: directive on a per-file basis. The only place where there's currently a collision is the long-standing "function parameters should be in single backticks" recommendation. Currently, numpydoc recommends this but does not implement anything specific for it, so the rendered docs end up using the default_role. The real solution here is to fix this in numpydoc - see #484.

can you suggest a compromise here? I think we need to address methods and attributes in some capacity. What can we say about them?

Since this is generally good advice, I'd be perfectly happy to put it in with softer wording; i.e. something that is very clearly a suggestion and not a necessary part of docstring formatting. Perhaps a less wordy version of:

When combined with `sphinx.ext.autodoc` or `sphinx.ext.autosummary`, included
{attributes/methods} become valid link targets and can be referenced elsewhere in the
docstring with single backticks. See <link to autoclass> for details.

This is hopefully clear, concise, and should do the job for ~95% of use-cases in practice. I'd personally be inclined to include a footnote after "single backticks" to add an additional note about the default role, e.g.

docstring with single backticks[^1]. See <link to autoclass> for details.

[^1]: Depending on the configuration of the `default_role <link to default role>`_ for your project.

but it's not necessary.

Copy link
Contributor

Choose a reason for hiding this comment

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

👍 My expectation is only for backticks, anywhere in the docstring, to link to parameter names. It looks like we are in agreement on that, and I'm fine with whatever else is added as Sphinx guidance.

Copy link
Author

@mdhaber mdhaber Feb 14, 2024

Choose a reason for hiding this comment

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

"function parameters should be in single backticks"

Is that documented, though? I see "Enclose variables in single backticks" (emphasis mine). That is in the Parameters section, but I thought that if "variables" were limited to "function parameters" it would say so. The ambiguity there is what led me to try to clarify.

See <link to autoclass> for details.

Is this what you have in mind?
https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#directive-autoclass

Depending on the configuration of the ``default_role <link to default role>``_ for your project.

This?
https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-default_role

Why does numpydoc make a recommendation about single backticks around parameters if it doesn't do anything with them? Has the intent always been that eventually they would link as you do in gh-484; it just hasn't happened yet?

Copy link
Contributor

Choose a reason for hiding this comment

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

My best guess is that the intent was to state "function parameters", but 2008 is a long time ago.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why does numpydoc make a recommendation about single backticks around parameters if it doesn't do anything with them?

Yeah this is likely an accident of fate - single backticks has always changed the formatting in the rendered docs (even if it was only to the formatting of broken rst links)

doc/format.rst Outdated Show resolved Hide resolved
@@ -717,7 +726,9 @@ Other points to keep in mind
(i.e. scalar types, sequence types), those arguments can be documented
with type `array_like`.

* Links : If you need to include hyperlinks in your docstring, note that
* Links : Sphinx will automatically create hyperlinks to module, function,
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, I think this reaches beyond what numpydoc would recommend (see above). The original information here about name collisions is relevant

Is this recommended practice?

I think it's a tradeoff. With the standard configuration default_role = "py:obj:", using single backticks is equivalent to writing `:py:obj:`target`, which will attempt to link against most things (func, ref, meth, attr, etc.). The primary motivation for excluding the explicit roles is docstring readability in the terminal. However there's nothing to say that you can't or shouldn't use the explicit roles - that's perfectly valid and is up to the library to decide.

Co-authored-by: Ross Barnowski <rossbar@berkeley.edu>
Co-authored-by: Matt Haberland <mhaberla@calpoly.edu>
Copy link
Author

@mdhaber mdhaber left a comment

Choose a reason for hiding this comment

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

Thanks all. @rossbar can you make suggestions on what we can write in these tricky spots? I'd rather not remove them altogether. The hope here was to make numpydoc's recommendations about backticks usage something that can be read and followed. If numpydoc doesn't have a requirement about something, maybe that's fine, but can we say that explicitly? Given all the misuse and confusion (I can produce dozens of PRs if need be), I think it's worth saying something.

Enclose variables in single backticks. The colon must be preceded
by a space, or omitted if the type is absent.
The colon must be preceded by a space, or omitted if the type is absent.
When referring to a parameter in the description field or elsewhere within
Copy link
Author

Choose a reason for hiding this comment

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

Suggested change
When referring to a parameter in the description field or elsewhere within
When referring to a parameter elsewhere within

by a space, or omitted if the type is absent.
The colon must be preceded by a space, or omitted if the type is absent.
When referring to a parameter in the description field or elsewhere within
the same function or class docstring, enclose its name in single backticks.
Copy link
Author

Choose a reason for hiding this comment

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

Suggested change
the same function or class docstring, enclose its name in single backticks.
the docstring, enclose its name in single backticks.

Enclose variables in single backticks. The colon must be preceded
by a space, or omitted if the type is absent.
The colon must be preceded by a space, or omitted if the type is absent.
When referring to a parameter in the description field or elsewhere within
Copy link
Author

Choose a reason for hiding this comment

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

I'm not sure I understand. Is the question about what constitutes a "parameter", where else a parameter might be mentioned, or something else?


When referring to an attribute in the description field or elsewhere within
Copy link
Author

Choose a reason for hiding this comment

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

Thanks @stefanv for bringing this up again.

@rossbar can you suggest a compromise here? I think we need to address methods and attributes in some capacity. What can we say about them?

@@ -606,6 +611,8 @@ becomes useful to have an additional **Methods** section:

"""

When referring to a method in the description field or elsewhere within
Copy link
Author

Choose a reason for hiding this comment

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

Suggested change
When referring to a method in the description field or elsewhere within
When referring to a method elsewhere within

@@ -717,7 +726,9 @@ Other points to keep in mind
(i.e. scalar types, sequence types), those arguments can be documented
with type `array_like`.

* Links : If you need to include hyperlinks in your docstring, note that
* Links : Sphinx will automatically create hyperlinks to module, function,
Copy link
Author

Choose a reason for hiding this comment

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

It's fine with me to add something about this being a project specific thing and mention the more explicit options, but if it is very common for projects to use single backticks, I think something should be mentioned. What can we say without over-stepping numpydoc's role?


- Module, function, and class names should be enclosed within ```single
backticks```. These are intended to render as hyperlinks (e.g. `numpy`). If
the hyperlinks do not render as intended, [insert reference to documentation
Copy link
Author

Choose a reason for hiding this comment

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

Suggestions on that to include here?

Copy link
Contributor

@rossbar rossbar left a comment

Choose a reason for hiding this comment

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

FWIW I found this summary from @jnothman over in a related scikit-learn issue very relevant: scikit-learn/scikit-learn#11186 (comment)

@timhoffm
Copy link
Contributor

timhoffm commented May 14, 2024

IMHO, the recommendation for single backticks should be complemented with an explanation. Something like

Single backticks are historically used as a means of highlighting. Sphinx tries to resolve them with the default_role, which in the default configuration results in italics. If you use a different default_role in Sphinx you may need to resort to different ways of highlighting, e.g. double backticks or *param* to prevent unintended links or link errors.

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.

None yet

5 participants