-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Disambiguate :type:
as a directive option or field-list item
#13242
Conversation
So, |
I'm not sure what the right term is, I meant that I posted a bit more on Discourse, as I think Sphinx should attempt to standardise on one or the other -- I was quite surprised to find this behaviour whilst debugging Erlend's original issue. |
Okay, so the key thing is that in some situations it must be a valid *type*
expression, which excludes `or`, requiring `|` instead. Your PR should
probably be precise about the distinction.
What is "runtime typing" mentioned in your Discourse post?
…On Wed, Jan 15, 2025 at 7:55 AM Adam Turner ***@***.***> wrote:
I'm not sure what the right term is, I meant that int or float is
'invalid' in this context because it is rejected by type checkers. Sphinx
has two effective modes at the moment, a 'strict' mode where only "valid
type expressions" are allowed, and a 'relaxed' mode where or and :term:`file-like
object` are parsed.
I posted a bit more on Discourse
<https://discuss.python.org/t/how-should-we-mark-up-multiple-types-in-a-type-field/48196/35>,
as I think Sphinx should attempt to standardise on one or the other -- I
was quite surprised to find this behaviour whilst debugging Erlend's
original issue.
—
Reply to this email directly, view it on GitHub
<#13242 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAWCWMXE6YDQWLR2S2PMLD32K2AF3AVCNFSM6AAAAABVF66EBKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKOJTGMYDKNZTGY>
.
You are receiving this because you commented.Message ID:
***@***.***>
--
--Guido van Rossum (python.org/~guido)
|
Sorry for the slight delay. I'm proposing to re-word the warning/admonition (#13256) to:
Hopefully this more accurately describes the differences between the two options.
Type annotations as seen in Python programmes and that pass type checkers, as opposed to prose-like descriptions of valid types (" A |
@AA-Turner given the current 2025 resources the change should contain the exact term type expression with this link, first mention seems to be in PEP 747, to put into context:
Finding the exact taxonomy is a "gotcha" since it's not in the official docs; neither in the Data Model nor Expressions. |
Proposing in this PR (which was merged) or in new PR? Consider me dumb but I am not good at mind reading any more.
Given that I've been writing TypeScript for the past few months (!), "sequences must use square brackets" sounds ambiguous. Can you just clarify that they should use
That is the opposite of runtime typing. :-) Those are statically checkable types (using mypy, pyright etc.). Runtime typing refers to the runtime type checks that the runtime does based on the actual (not inferred, nor user-declared) object types present at runtime like As @electric-coder already pointed out, the phrase to use for that syntax is type expressions. I am still unclear why Sphinx decided to make its own syntax for types -- is that feature so ancient that it predated PEP 484? Anyway, since the rest of the EB seems to prefer it, I am okay with using it, as long as it is supported everywhere. Otherwise we'd end up with two different syntaxes being used, depending on what kind of thing it describes, and that feels even more confusing (for end users and occasional documentation writers alike). |
Ah, sorry -- the updated text is in PR #13256. I merged that a few hours ago to avoid having incorrect/imprecise text on the website, but happy to make further improvement if there's remaining imprecision. I mainly follow typing developments through Discourse and PEPs so my vocabulary isn't great, I have ended up using "assignment expression" as I think this is the closest match between a defined/specified term and what Sphinx expects.
Wow!
Sounds good, I will update the text tomorrow.
I've used 'annotation expressions' in the update to the text, which indeed are of course static typing -- I was trying to distinguish between content in
Sphinx's
If I had a free choice, I would deprecate the 2008-style Does the editorial board have a strong view either way? Would the EB prefer that we keep the prose-style type syntax? |
I will ask the EB next time we meet. Last time we talked there was a lot of confusion over what was supported where and what could be easily added to the supported syntax. A majority of the EB prefers the ‘or’ syntax; it’s the first time I hear about the ‘of’ syntax. We have a bit more clarity now over what’s supported (two separate :type: thingies with different capabilities). It would be nice to know:
Depending on which is easier we might decide differently. @nedbat Anything I missed or mischaracterized? @Mariatta? @willingc? |
This is rooted in "tradition", if we randomly google top 20 Python libraries most are scientific/numerical and dominated by the old type syntax (
There's also a
example
Contrast with a more modern
The main issue is: what should be adopted by the the official Python documentation? @nedbat I think the initial argument that |
Yes |
That is an old mentality incompatible with Python:
In light of PEP 8 (the EB discussion at hand is about the standard library documentation):
An inventory of style guides and consistency (and their problems in taxonomy):
The upcoming EB decision needs foremost to be very clear on these fundamental problems. Because by not addressing them (hopefully with the community doing most of the hard work here) your are propagating preexisting historical issues that have gone unresolved thus far - and, what's worst, enshrining these ongoing problems into the standard lib docs. And notice very carefully one thing: the prose type expressions have never been formalized neither as mandatory nor recommended by the numpydoc style. They are just an example that became practice (in the sense of a habit) and predating PEP 484 continues propagating and proliferating - whereas PEP 484 type expressions are already uniform and unambiguously defined. |
You are preaching to the choir here, I agree that type expressions ought to be the future (but I am having a hard time convincing the rest of the EB, who admittedly have more experience in what newbies can understand). I do want to call out that IMO the EB's opinion was asked about the Python stdlib docs, which are never generated from docstrings, but written by hand to maximize clarity. The stdlib docstrings never use Sphinx syntax. So what Numpy and others who use typed docstrings do is of no concern here. We only care about the Sphinx "code" we write to generate nice cross-linked function signatures. |
I believe at the moment that the pre PEP 484-style syntax isn't in use at all in Python's documentation. As such, I'd be hesistant to start introducing it, as the PEP 484 style is used in several places (search for
The PEP 484-style
More difficult, for the same reason ( Taking the motivating example of If useful, I could try and find the time to attend the EB meeting in Feb, but I don't know how helpful that would be! A |
IMO the goal of having types in the documentation is not to have the exact type found in the code -- while |
I think that would be super useful! I'll check if the rest of the EB has any objections. It's Tue Feb 11 at 1:30pm US Pacific time. (Sorry, I know that's rather late for you.) |
An argument needs to be made: the first place a dev looks to for inspiration is the standard library. It sets the trends so a new type-prose-syntax adds to the learning curve instead of easing it - those beginner devs will find the proposed syntax to be a waste of their time (and they'll resent there's more than one such syntax to learn, because PEP 484 type expressions are also part of the standard library). At least that's how I feel about it, having been a newbie more recently than the EB members. |
So taking a step back, why does Sphinx need to parse the type expression at all? Why can’t it just treat it as regular text? |
It needs to be parsed for the link substitutions to be processed and resolved. So the authors can write an So that in the built docs you get this: instead of this:
Up until three years ago the feature was still marked as "experimental" in Sphinx, but it's stable enough now that it's become the expected norm in the ecosystem's documentation. (Quite tricky because Python is dynamic and a lot of magic goes into resolving and linking the types). |
@electric-coder I appreciate your advocacy. These are not easy questions. You quoted:
We accommodate non-English speakers by translating the docs. It doesn't make sense to choose a typing style that avoids English when the vast majority of the page content is in English. I agree with @gvanrossum here:
@electric-coder It's easy to champion
The goal of documentation is to explain and educate. Sometimes that is best accomplished with precision (using the exact Python types), but sometimes words work better. How can we let authors choose the approach that works best for the situation? @electric-coder as an aside, you've characterized the English approach as old, outdated, and the past. This is unfair. There are reasons English sometimes works better in documentation than formal type syntax, which can get quite complex. |
For that, all you need to do is tokenize, and for doc usage you don't need to do a very thorough job (no need to know that But if you do have a full parser, you could write |
A couple of choices:
In all cases the text has to explain the signature of the callback. I'm pretty sure we can use this tactic for all types deemed too complex to appear in the docs. EDIT
I think my proposal here can solve that by letting authors choose between |
It would be great to see this in action. Ideally the paragraph styling would be similar for the two choices. |
Here's how a documentation writer can't do it: first they get hit by the double #11007 meaning neither Conceptually there'd be several choices of explicitness, e.g. for def call_soon(
self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None
) -> Handle: ... Use an alias for .. py:function:: call_soon(callback, *args, context) -> Handle
:param callback: A :term:`term-callback` receiving a variadic generic.
:type callback: typing.Callable[[typing.Unpack[\*_Ts]], object] would look like: or The usual choice is that if you're explaining it in prose then omit |
@electric-coder, you seem to be missing entirely the point. The rhetorical question was not asking how to get that complicated type expression to render and properly link to other doc entries. Ned meant that this is clearly not something we want to see in docs, so complaints about why rendering this is broken or suggestions on how it can be rendered fail to address the point entirely. And I also fail to understand why you keep bringing up autodoc etc. -- we have no choice in that matter. What Ned asked for in the end is something that shows how you can describe a function argument or object attribute using something like
I just did a little experiment with the TarInfo.mode attribute, and learned the following:
From this I conclude that if it's a valid type expression it is linkified, while if it's not a valid type expression (and apparently I still don't understand why it needs to parse this before it can linkify it (I'd think tokenizing would be enough), but that seems to be what it does, and from a comment above I understand it's hard to get it changed. |
Also, I grepped the Doc directory, and found that actually there is almost no use of What I found:
So only one file out of 521 .rst files under Doc uses The syntax for parameters is actually different, you write As you can see, this uses I think I have exhausted my fact-finding research here. We'll discuss our answer at the EB meeting on Feb 11. |
Here are the docs for the two things in Sphinx:
|
I don't think it's that simple (ping @picnixz ) there's a thread centralizing over 50 linking bugs and the best available explanation is give in #9813 . Most were surfaced by autodoc but a lot are caused by how imports/types are handled by the Sphinx machinery. I can't explain it further but last I heard this is something that will need to be fixed over the next couple of years. |
The only thing that has to be in English are exposed objects and keywords (those don't translate). The proposal goes further, by saying type expressions should also include English. But I have yet to see one clear fact in support of that claim (that's what bothers me - and others will think the same). Besides the obvious technical problems that enshrining a new prose-type-expression style in the Python docs raises for the ecosystem, there's a long history of... besides also a history of... so just saying "it's English" isn't self-evident for me, out of technical reasons and otherwise. |
The EB has come to a conclusion, with AA-Turner's help. Suggestion to get back to this in the Discourse thread. |
Purpose
It is currently very confusing. We should make it less so.
Notably, @erlend-aasland's change failed to create a cross-reference, with the following rST:
This is because
:type:
is interepreted as the directive option, which runs throughsphinx.domains.python._annotations._parse_annotation()
and employs anast
unparser. The correct change would have been:The extra blank line seperates directive arguments and options from their content. In this context,
:type:
becomes a field list entry, which is then parsed withsphinx.domains.python._object.PyXrefMixin._delimiters_re
, a regular expression that includes the ability to split on'or'
.Note that I'm not suggesting that any of this makes sense, but at least we can improve the documentation as a first step...
References
d464f3f
(#116389)Preview
https://sphinx--13242.org.readthedocs.build/en/13242/usage/domains/python.html#directive-option-py-attribute-type
https://sphinx--13242.org.readthedocs.build/en/13242/usage/domains/python.html#info-field-lists
cc @erlend-aasland @nedbat
A