python / editorial-board

Communications of the Python Documentation Editorial Board
3 stars 1 forks source link

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

Open erlend-aasland opened 1 month ago

erlend-aasland commented 1 month ago

Recently, we've marked up some functions and methods using parameter lists[^1]. When a parameter can take multiple types, we've used | to separate the types, instead of using or, as recommended by the Sphinx docs^2:

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 |:

Arguments against |:

Arguments in favour of or:

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"

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

gvanrossum commented 1 month ago
gvanrossum commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 4 weeks ago

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 commented 4 weeks ago

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

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](https://github.com/python/editorial-board/assets/25624924/b83f88d9-465e-4fe0-85fb-af2ec8a80759) ![image](https://github.com/python/editorial-board/assets/25624924/98b07932-403d-49ae-8ad6-a086d1ab09f3)
nedbat commented 4 weeks ago

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".