-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Support PEP 695 and PEP 696 syntax in py:function
and py:class
directives.
#11444
Support PEP 695 and PEP 696 syntax in py:function
and py:class
directives.
#11444
Conversation
a8553f5
to
bfb843b
Compare
@JelleZijlstra The following .. py:class:: Sequence[T](Iterable[T])
.. py:function:: add[T](x: T, y: T)
.. py:function:: _add(x: T, y: T) renders as Would it be acceptable ? or do you prefer that the type parameters are straight instead of in italics? |
That looks great to me! I don't have strong feelings on whether to use italics. It makes sense to use the same style for type parameters as for annotations. |
I tried to find some "complex" examples for this new syntax but I would like to know whether there is a way to generate test cases based on the AST Python grammar in such a way that we could detect corner cases more easily (I especially want to test the new regex which seems... well.. simple?). As AA-Turner said, cpython would need to upgrade the minimal sphinx version if my PR is merged so you'll still need to stick with the old syntax (PEP 695 is really amazing btw). |
bfb843b
to
685d1b1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
685d1b1
to
882d9d8
Compare
py:function
and py:class
directives.py:function
and py:class
directives.
I remembered the LaTeX writer only today. But in order to make this PR work with LaTeX, a bit more work needs to be done (and this involves changing the macros). Since I haven't worked enough with the LaTeX core, I am not confident in implementing this. @jfbu What would be the best approach in the LaTeX writer ? my idea was to essentially handle the type parameters list the same way the regular parameter list is handled but the delimiters '()' are hardcoded on the LaTeX side. So, my idea was to rewrite the macro for creating a function/class signature with an additional parameter that would take the type parameters to format. But then, the visitor must be updated and the flow will be a bit different (for now, it just ignores type parameters node, so it does not even render them). |
@picnixz Will the type parameter list obey "one type per line", is this what you mean with "multiline support is enabled for it", and I suppose no new config variable is related to this (I did not check too much for current lack of availability your work so far). As to the hard-coded things in the current sphinxlatexobjects.sty file such as |
Yes, the idea is to have the same behaviour for the tplist as for the arglist. Essentially, I don't want to separate the two mechanisms for now so currently the writers do exactly the same for a type parameters list node or a parameters list node.
Good idea. Since only
That was my idea ! but since I never touched this part of the code (and since it is barely commented) I didn't want to modify anything. Also, it's quite difficult to navigate through LaTeX code in general since autocompletion features are not well-supported =/. Anyway, the best idea is simply to assume that we have now two lists to render separately but with the same idea and both of them support the same functionalities, except that their delimiters are different. Concerning the Python implementation, it currently does the following:
However with the I think this part of the code was essentially modified by @TLouf in #11011 so maybe they may have some insight to share. I also need to update the other writers (and test them actually), especially the Other remarksThere were more parts where the code needed to be modified because I remembered the autodoc as well. From Python 3.12 and onwards, autodocumented generic classes are (for now) not supported in the sense that the type parameters list is simply ignored (and not even stored). It is only matched but another PR needs to address this. Final remarks
I have upcoming conferences so I need to prepare the presentations and attend the conferences, so I won't be available from mid-June to mid-July. After that, I'll have some time in August but then again I'll be travelling from late-August to mid-September. I still think I'll manage to finish things before leaving but I'll ping you when I am stuck, so thank you in advance. |
With the latest implementation, this is how LaTeX and HTML are rendered. I eventually decided to split the multi-line support as follows:
I kinda visually tested the "unusal writers" but we'll probably need to add tests at some point (although I don't think that there are a lot of projects using the Example.. py:function:: foo(a, b, c)
foo(very_long_1, very_long_2, very_long_3)
foo[X, Y, Z](a, b, c)
foo[X, Y, Z](very_long_1, very_long_2, very_long_3)
foo[VERY_LONG_1, VERY_LONG_2, VERY_LONG_3](a, b, c)
foo[VERY_LONG_1, VERY_LONG_2, VERY_LONG_3](very_long_1, very_long_2, very_long_3) No multi-line supportHTMLLaTeXWith multi-line supportHTMLLaTeX |
b212fb4
to
e28c44d
Compare
@jfbu If you want to have a look, I ended up implementing a c/c of what was already written. If possible, I'd like you to review these parts (whenever you're available) and tell me whether some parts are superfluous or not (I am not entirely sure that all my Also, I purposely duplicated the different implementations so that we can, in a second phase, refactor them more easily. Technically speaking, it should be possible to have one single macro doing all the work or we could split some "same" functionalities as private macros and then use them directly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a very superficial look only to check LaTeX macros added to support this feature, and this looks good to me. In future we should think into replacing \sphinxcode{(}
et al. into better abstraction such as \sphinxarglistopen
or \sphinxarglistleftdelimiter
or whatever.
e58ecb9
to
a924d4a
Compare
# Conflicts: # sphinx/writers/text.py
@picnixz -- I've merged now as a base implementation, any improvements we need to make shouldn't hold up the feature -- thank you for your great work on this! A |
@picnixz @AA-Turner good this was merged; sorry I am not much available currently for (LaTeX) maintenance |
Add support for PEP 695 and PEP 696.
Generic classes can be documented with
.. py:class::
using PEP 695 syntax:Generic functions can be documented with
.. py:function::
using PEP 695 syntax:Default values for type bounds are supported.
Generic type aliases introduced in this PEP are not yet supported (and I don't know if we should).
Closes #11438.
Implementation details
Since PEP 696 is not yet accepted, it is not possible to use an AST-approach or to use the current implementation of
signature_from_ast
. The reason is that variadic positional and keyword arguments cannot have default values (a SyntaxError is raised when parsing the code), so I used a token-based approach.In addition, PEP 695 specifications allow the type parameter bound to be any kind of expression, that is,
P: int + int
should be valid. Since the tokenizer consumes whitespace outside of literals, I implemented a small prettifier which automatically adds spaces around arithmetic operators (there is a test showing the different results).Notes
I am opening a PR now because I don't know if there are other places that need attention and thus it would be good to let me know where other places need to be changed. Also, the current implementation tries to limit the changes on the writer's side and thus the type parameters list is handled the same way the parameters list is (so the multiline support is enabled for it as well).