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

Support PEP 695 and PEP 696 syntax in py:function and py:class directives. #11444

Merged
merged 25 commits into from Jul 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
882d9d8
Add partial support for PEP 695 and PEP 696 syntax (#11438)
picnixz May 28, 2023
031afb8
Fix linter
picnixz May 30, 2023
da95253
rename a test for better clarity
picnixz May 30, 2023
0f985da
fix linter check
picnixz May 30, 2023
5c353f2
fix linter check
picnixz May 30, 2023
cf0d946
remove unused code
picnixz May 30, 2023
81c3bbc
improve tests
picnixz Jun 1, 2023
f553df1
fix linter check
picnixz Jun 1, 2023
08a6840
update .gitignore to ignore the autogenerated (persistent) test-file …
picnixz Jun 3, 2023
489ec30
PEP 695/696 skeleton support for autodoc
picnixz Jun 3, 2023
4eaa0ed
allow independent multi-line support for type parameters and argument…
picnixz Jun 3, 2023
a843d7c
implement visitor methods for type parameters
picnixz Jun 3, 2023
178b8a2
refactor visitor methods for parameters list-like nodes
picnixz Jun 3, 2023
d1293f7
implement LaTeX support
picnixz Jun 3, 2023
e28c44d
fix linter issues
picnixz Jun 3, 2023
9a88771
update LaTeX info strings
picnixz Jun 3, 2023
d66e98a
update CHANGES
picnixz Jun 3, 2023
a1b89bb
update documentation
picnixz Jun 3, 2023
02df300
update LaTeX code and writer
picnixz Jun 6, 2023
160b5cc
update LaTeX doc
picnixz Jun 6, 2023
a924d4a
update Python domain doc
picnixz Jun 6, 2023
79a2b06
fix typo in LaTeX doc
picnixz Jun 6, 2023
8a1800b
Merge branch 'master' into feature/11438-PEP-695-support
picnixz Jul 16, 2023
7127d63
Merge branch 'master' into feature/11438-PEP-695-support
AA-Turner Jul 23, 2023
ba39b4f
Updates
AA-Turner Jul 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGES
Expand Up @@ -34,6 +34,12 @@ Features added
* #11157: Keep the ``translated`` attribute on translated nodes.
* #11451: Improve the traceback displayed when using :option:`sphinx-build -T`
in parallel builds. Patch by Bénédikt Tran
* #11438: Add support for the :rst:dir:`py:class` and :rst:dir:`py:function`
directives for PEP 695 (generic classes and functions declarations) and
PEP 696 (default type parameters). Multi-line support (#11011) is enabled
for type parameters list and can be locally controlled on object description
directives, e.g., :rst:dir:`py:function:single-line-type-parameter-list`.
Patch by Bénédikt Tran.

Bugs fixed
----------
Expand Down
7 changes: 7 additions & 0 deletions doc/latex.rst
Expand Up @@ -1464,6 +1464,7 @@ Macros
``\sphinxtermref``; ``\emph{#1}``
``\sphinxsamedocref``; ``\emph{#1}``
``\sphinxparam``; ``\emph{#1}``
``\sphinxtypeparam``; ``\emph{#1}``
``\sphinxoptional``; ``[#1]`` with larger brackets, see source

.. versionadded:: 1.4.5
Expand All @@ -1485,6 +1486,12 @@ Macros
signatures (see :confval:`maximum_signature_line_length`). It defaults
to ``\texttt{,}`` to make these end-of-line separators more distinctive.

Signatures of Python functions are rendered as ``name<space>(parameters)``
or ``name<space>[type parameters]<space>(parameters)`` (see :pep:`695`)
where the length of ``<space>`` is set to ``0pt`` by default.
This can be changed via ``\setlength{\sphinxsignaturelistskip}{1ex}``
for instance.

- More text styling:

.. csv-table::
Expand Down
21 changes: 18 additions & 3 deletions doc/usage/configuration.rst
Expand Up @@ -3025,9 +3025,24 @@ Options for the Python domain

.. confval:: python_maximum_signature_line_length

If a signature's length in characters exceeds the number set, each
argument will be displayed on an individual logical line. This is a
domain-specific setting, overriding :confval:`maximum_signature_line_length`.
If a signature's length in characters exceeds the number set,
each argument or type parameter will be displayed on an individual logical line.
This is a domain-specific setting,
overriding :confval:`maximum_signature_line_length`.

For the Python domain, the signature length depends on whether
the type parameters or the list of arguments are being formatted.
For the former, the signature length ignores the length of the arguments list;
for the latter, the signature length ignores the length of
the type parameters list.

For instance, with `python_maximum_signature_line_length = 20`,
only the list of type parameters will be wrapped
while the arguments list will be rendered on a single line

.. code:: rst

.. py:function:: add[T: VERY_LONG_SUPER_TYPE, U: VERY_LONG_SUPER_TYPE](a: T, b: U)

.. versionadded:: 7.1

Expand Down
99 changes: 91 additions & 8 deletions doc/usage/restructuredtext/domains.rst
Expand Up @@ -192,12 +192,16 @@ declarations:
The following directives are provided for module and class contents:

.. rst:directive:: .. py:function:: name(parameters)
.. py:function:: name[type parameters](parameters)

Describes a module-level function. The signature should include the
parameters as given in the Python function definition, see :ref:`signatures`.
Describes a module-level function.
The signature should include the parameters,
together with optional type parameters,
as given in the Python function definition, see :ref:`signatures`.
For example::

.. py:function:: Timer.repeat(repeat=3, number=1000000)
.. py:function:: Timer.repeat(repeat=3, number=1_000_000)
.. py:function:: add[T](a: T, b: T) -> T

For methods you should use :rst:dir:`py:method`.

Expand Down Expand Up @@ -240,6 +244,15 @@ The following directives are provided for module and class contents:

.. versionadded:: 7.1

.. rst:directive:option:: single-line-type-parameter-list
:type: no value

Ensure that the function's type parameters are emitted on a single
logical line, overriding :confval:`python_maximum_signature_line_length`
and :confval:`maximum_signature_line_length`.

.. versionadded:: 7.1


.. rst:directive:: .. py:data:: name

Expand Down Expand Up @@ -274,9 +287,12 @@ The following directives are provided for module and class contents:
the module specified by :rst:dir:`py:currentmodule`.

.. rst:directive:: .. py:exception:: name
.. py:exception:: name(parameters)
.. py:exception:: name[type parmeters](parameters)

Describes an exception class. The signature can, but need not include
parentheses with constructor arguments.
Describes an exception class.
The signature can, but need not include parentheses with constructor arguments,
or may optionally include type parameters (see :pep:`695`).

.. rubric:: options

Expand All @@ -293,12 +309,28 @@ The following directives are provided for module and class contents:
Describe the location where the object is defined. The default value is
the module specified by :rst:dir:`py:currentmodule`.

.. rst:directive:option:: single-line-parameter-list
:type: no value

See :rst:dir:`py:class:single-line-parameter-list`.

.. versionadded:: 7.1

.. rst:directive:option:: single-line-type-parameter-list
:type: no value

See :rst:dir:`py:class:single-line-type-parameter-list`.

.. versionadded:: 7.1

.. rst:directive:: .. py:class:: name
.. py:class:: name(parameters)
.. py:class:: name[type parmeters](parameters)

Describes a class. The signature can optionally include parentheses with
parameters which will be shown as the constructor arguments. See also
:ref:`signatures`.
Describes a class.
The signature can optionally include type parameters (see :pep:`695`)
or parentheses with parameters which will be shown as the constructor arguments.
See also :ref:`signatures`.

Methods and attributes belonging to the class should be placed in this
directive's body. If they are placed outside, the supplied name should
Expand Down Expand Up @@ -348,6 +380,13 @@ The following directives are provided for module and class contents:

.. versionadded:: 7.1

.. rst:directive:option:: single-line-type-parameter-list
:type: no value

Ensure that the class type parameters are emitted on a single logical
line, overriding :confval:`python_maximum_signature_line_length` and
:confval:`maximum_signature_line_length`.

.. rst:directive:: .. py:attribute:: name

Describes an object data attribute. The description should include
Expand Down Expand Up @@ -410,6 +449,7 @@ The following directives are provided for module and class contents:
the module specified by :rst:dir:`py:currentmodule`.

.. rst:directive:: .. py:method:: name(parameters)
.. py:method:: name[type parameters](parameters)

Describes an object method. The parameters should not include the ``self``
parameter. The description should include similar information to that
Expand Down Expand Up @@ -469,6 +509,15 @@ The following directives are provided for module and class contents:

.. versionadded:: 7.1

.. rst:directive:option:: single-line-type-parameter-list
:type: no value

Ensure that the method's type parameters are emitted on a single logical
line, overriding :confval:`python_maximum_signature_line_length` and
:confval:`maximum_signature_line_length`.

.. versionadded:: 7.2

.. rst:directive:option:: staticmethod
:type: no value

Expand All @@ -478,19 +527,22 @@ The following directives are provided for module and class contents:


.. rst:directive:: .. py:staticmethod:: name(parameters)
.. py:staticmethod:: name[type parameters](parameters)

Like :rst:dir:`py:method`, but indicates that the method is a static method.

.. versionadded:: 0.4

.. rst:directive:: .. py:classmethod:: name(parameters)
.. py:classmethod:: name[type parameters](parameters)

Like :rst:dir:`py:method`, but indicates that the method is a class method.

.. versionadded:: 0.6

.. rst:directive:: .. py:decorator:: name
.. py:decorator:: name(parameters)
.. py:decorator:: name[type parameters](parameters)

Describes a decorator function. The signature should represent the usage as
a decorator. For example, given the functions
Expand Down Expand Up @@ -531,8 +583,18 @@ The following directives are provided for module and class contents:

.. versionadded:: 7.1

.. rst:directive:option:: single-line-type-parameter-list
:type: no value

Ensure that the decorator's type parameters are emitted on a single
logical line, overriding :confval:`python_maximum_signature_line_length`
and :confval:`maximum_signature_line_length`.

.. versionadded:: 7.2

.. rst:directive:: .. py:decoratormethod:: name
.. py:decoratormethod:: name(signature)
.. py:decoratormethod:: name[type parameters](signature)

Same as :rst:dir:`py:decorator`, but for decorators that are methods.

Expand Down Expand Up @@ -561,6 +623,27 @@ argument support), you can use brackets to specify the optional parts:

It is customary to put the opening bracket before the comma.

Python 3.12 introduced *type parameters*, which are type variables
declared directly within the class or function definition:

.. code:: python

class AnimalList[AnimalT](list[AnimalT]):
...

def add[T](a: T, b: T) -> T:
return a + b

The corresponding reStructuredText documentation would be:

.. code:: rst

.. py:class:: AnimalList[AnimalT]

.. py:function:: add[T](a: T, b: T) -> T

See :pep:`695` and :pep:`696` for details and the full specification.

.. _info-field-lists:

Info field lists
Expand Down
19 changes: 19 additions & 0 deletions sphinx/addnodes.py
Expand Up @@ -258,10 +258,27 @@ def astext(self):
return f'({super().astext()})'


class desc_type_parameter_list(nodes.Part, nodes.Inline, nodes.FixedTextElement):
"""Node for a general type parameter list.

As default the type parameters list is written in line with the rest of the signature.
Set ``multi_line_parameter_list = True`` to describe a multi-line type parameters list.
In that case each type parameter will then be written on its own, indented line.
"""
child_text_separator = ', '

def astext(self):
return f'[{super().astext()}]'


class desc_parameter(nodes.Part, nodes.Inline, nodes.FixedTextElement):
"""Node for a single parameter."""


class desc_type_parameter(nodes.Part, nodes.Inline, nodes.FixedTextElement):
"""Node for a single type parameter."""


class desc_optional(nodes.Part, nodes.Inline, nodes.FixedTextElement):
"""Node for marking optional parts of the parameter list."""
child_text_separator = ', '
Expand Down Expand Up @@ -537,7 +554,9 @@ def setup(app: Sphinx) -> dict[str, Any]:
app.add_node(desc_type)
app.add_node(desc_returns)
app.add_node(desc_parameterlist)
app.add_node(desc_type_parameter_list)
app.add_node(desc_parameter)
app.add_node(desc_type_parameter)
app.add_node(desc_optional)
app.add_node(desc_annotation)

Expand Down