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

Request for decision: how should we mark up types in parameter lists #7

Open
erlend-aasland opened this issue Jun 6, 2024 · 8 comments

Comments

@erlend-aasland
Copy link

Recently, we've marked up some functions and methods using parameter lists1. When a parameter can take multiple types, we've used | to separate the types, instead of using or, as recommended by the Sphinx docs23:

Multiple types in a type field will be linked automatically if separated by the word “or”:

:type an_arg: int or None
:vartype a_var: str or int
:rtype: float or str

I created a PR to align our markup with the Sphinx recommendation, but it turned out slightly controversial.

I'll try and summarise the arguments in favour of |:

  • brevity
  • similar to type hints, so it is easy to grasp if you're into typing

Arguments against |:

  • similar, but not equal, to type hints, so it is confusing4

Arguments in favour of or:

  • easier for beginners: int or None is clear and contains no "weird symbols"4
  • aligns with "the Sphinx way"5

My personal preference would be or. I don't think the extra character is too verbose compared with |, I think it is easier to grasp for beginners (and I don't think it will be a hindrance for more experienced users), and I think it is wise to avoid the similarity with type hints because that's not what it is.

An example, where I think or is superior: "path-like object or None"

Footnotes

  1. examples: https://docs.python.org/3/library/functions.html#eval and https://docs.python.org/3/library/sqlite3.html#sqlite3.connect

  2. https://www.sphinx-doc.org/en/master/tutorial/describing-code.html#id5

  3. https://www.sphinx-doc.org/en/master/usage/domains/python.html#info-field-lists

  4. https://github.com/python/cpython/pull/116389#issuecomment-1979766838 2

  5. https://github.com/python/cpython/pull/116389#issuecomment-1986203040

@gvanrossum
Copy link
Member

gvanrossum commented Jun 6, 2024

  • In principle I like that using | at least "rhymes" with type annotations -- I'd expect that to help more than it hinders, even if the similarity isn't perfect. (And nobody stays a newbie very long.)
  • To what extent are these not like type hints? Is the difference important enough to confuse rather than enlighten? Humans are very good at overlooking slight differences if there are helpful similarities.
  • The | looks like a slash in italics, making its use in the sqlite3.connect example more odd than necessary. The eval example doesn't use italics, which looks much better. Why the difference? If the | has to be rendered in italics, I think or looks better.
  • "No weird symbols" doesn't feel like a strong argument when our target audience is at the very least learning to program.
  • I'm not very impressed by "this is the Sphinx way". Sphinx can be at time pretty idiosyncratic; I think we should do what feels right to us and make Sphinx do what we want. (Do you have a reference to the Sphinx guideline? The link is not very enlightening.)

@gvanrossum
Copy link
Member

Another thought: besides unions, there are other potentially useful notations from Python's type hints syntax. For example, list[str] or Iterable[int] or tuple[int, int]. If we think those notations are potentially useful to describe parameter types, that might sway the argument towards |. OTOH, if we think that's too technical for end-user-friendly documentation, the argument for | is much weaker and or starts looking more attractive.

@erlend-aasland
Copy link
Author

The | looks like a slash in italics, making its use in the sqlite3.connect example more odd than necessary. The eval example doesn't use italics, which looks much better. Why the difference? If the | has to be rendered in italics, I think or looks better.

eval is marked up using explicit references, so it seems Sphinx renders them as it's explicitly been told to, in this case using the :class: and :term: roles, and double backquotes.

OTOH, sqlite3.connect is implicitly marked up by Sphinx — the types are mostly spelled out in plain text in the .rst file – and in this case, italics is used. This leads me to believe that italics is the default rendering for types in parameter lists.

I'm not very impressed by "this is the Sphinx way". Sphinx can be at time pretty idiosyncratic; I think we should do what feels right to us and make Sphinx do what we want. (Do you have a reference to the Sphinx guideline? The link is not very enlightening.)

It's in this link: https://www.sphinx-doc.org/en/master/usage/domains/python.html#info-field-lists
... but unfortunately it's not at the top of that anchor; you have to scroll a little bit. I therefore included the quote and their example in the OP:

Multiple types in a type field will be linked automatically if separated by the word “or”

:type an_arg: int or None
:vartype a_var: str or int
:rtype: float or str

I still think or is better, since I believe it makes for more user-friendly documentation. If we wanted something closer to type hints, why not just use actual type hints in the signatures? (Disclaimer: I'm not suggesting to add actual type hints to the signatures, and I don't think it is a good idea)

@gvanrossum
Copy link
Member

If we wanted something closer to type hints, why not just use actual type hints in the signatures? (Disclaimer: I'm not suggesting to add actual type hints to the signatures, and I don't think it is a good idea)

That seems like a strawman. We all agree it's not a good idea to literally use type annotations in the signature -- it would be too verbose. But type expressions have other uses (e.g. in casts) and just because in the docs we don't integrate the types in the parameter list (like we do in code) doesn't mean we can't use (a readable subset of) type expressions in the longer parameter descriptions.

At the same time I don't feel particularly strong about this, and I'll wait for the other EB member to speak up. This is defintely the kind of thing where the EB's decision will be valuable guidance for documentation authors going forward.

@erlend-aasland
Copy link
Author

That seems like a strawman.

Sorry, that was not my intention.

This is defintely the kind of thing where the EB's decision will be valuable guidance for documentation authors going forward.

Indeed it is! Looking forward to the decision :)

@ezio-melotti
Copy link
Member

Another alternative that was brought up during the docs meeting is a way to show/hide types. This could be implemented in different ways:

  • a global setting that applies to all docs
  • a switch to show/hide them for all the page
  • a "button" next to the signature to expand it and show more details (see mockup below)
  • a tooltip that appears on hover on the signature or individual parameters

These ideas have some downsides, but also some advantages (e.g. it would allow us to be as verbose as we want/need without affecting the current look of the docs or people that don't care about types). The actual pros/cons will also depend on the implementation itself.

Quick example mockup

This is just to give an idea -- it could simply be a > or + or (?) next to the signature.

image
image

@nedbat
Copy link
Member

nedbat commented Jun 9, 2024

It's not linked here yet, but there was a discussion about this on discuss.python.org: How should we mark up multiple types in a type field? @willngc and I came around to "English is better" for a few reasons, mostly based on the squishy nature of what types actually mean and focusing on what would be most helpful for the readers who need the most help.

Another alternative that was brought up during the docs meeting is a way to show/hide types.

This sounded interesting until I saw the example. It's not hiding types, it's hiding the entire description of the parameter list. That doesn't seem useful to me. If I could make one change to the shown example, it would be to not put the entire signature on one line, but that's a section heading, so probably not easy.

It's interesting to note in the example shown that database is described as "path-like object" (English) while isolation_level is "str | None" (annotation). I would change isolation_level to "optional str".

@erlend-aasland
Copy link
Author

It's not linked here yet, but there was a discussion about this on discuss.python.org: How should we mark up multiple types in a type field? @willngc and I came around to "English is better" for a few reasons, mostly based on the squishy nature of what types actually mean and focusing on what would be most helpful for the readers who need the most help.

Is this the EB decision? If so, let's close this as completed.

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

4 participants