Skip to content

Add the new py:deco cross-reference role #13292

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

Merged
merged 3 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ Features added
Patch by Bénédikt Tran and Adam Turner.
* #13163: Always print the full context when Sphinx encounters an internal error.
Patch by Kevin Deldycke and Adam Turner.
* #13105: Introduce the :rst:role:`py:deco` role to cross-reference decorator
functions and methods in the Python domain.
Patch by Adam Turner.

Bugs fixed
----------
Expand Down
16 changes: 13 additions & 3 deletions doc/usage/domains/python.rst
Original file line number Diff line number Diff line change
Expand Up @@ -562,8 +562,7 @@ The following directives are provided for module and class contents:

(as opposed to ``.. py:decorator:: removename(func)``.)

There is no ``py:deco`` role to link to a decorator that is marked up with
this directive; rather, use the :rst:role:`py:func` role.
Refer to a decorator function using the :rst:role:`py:deco` role.

.. rst:directive:option:: single-line-parameter-list
:type: no value
Expand All @@ -589,7 +588,7 @@ The following directives are provided for module and class contents:

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

Refer to a decorator method using the :rst:role:`py:meth` role.
Refer to a decorator method using the :rst:role:`py:deco` role.

.. _annotation expression: https://typing.readthedocs.io/en/latest/spec/annotations.html#type-and-annotation-expressions

Expand Down Expand Up @@ -769,6 +768,17 @@ a matching identifier is found:
automatically by Sphinx if the :confval:`add_function_parentheses` config
value is ``True`` (the default).

.. rst:role:: py:deco

Reference a Python decorator; dotted names may be used.
The rendered output will be prepended with an at-sign (``@``),
for example: ``:py:deco:`removename``` produces :py:deco:`removename`.

.. py:decorator:: removename
:no-contents-entry:
:no-index-entry:
:no-typesetting:

.. rst:role:: py:data

Reference a module-level variable.
Expand Down
24 changes: 23 additions & 1 deletion sphinx/domains/python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from collections.abc import Iterable, Iterator, Sequence, Set
from typing import Any, ClassVar

from docutils.nodes import Element, Node
from docutils.nodes import Element, Node, TextElement

from sphinx.addnodes import desc_signature, pending_xref
from sphinx.application import Sphinx
Expand Down Expand Up @@ -592,6 +592,27 @@ def process_link(
return title, target


class _PyDecoXRefRole(PyXRefRole):
def __init__(
self,
fix_parens: bool = False,
lowercase: bool = False,
nodeclass: type[Element] | None = None,
innernodeclass: type[TextElement] | None = None,
warn_dangling: bool = False,
) -> None:
super().__init__(
fix_parens=True,
lowercase=lowercase,
nodeclass=nodeclass,
innernodeclass=innernodeclass,
warn_dangling=warn_dangling,
)

def update_title_and_target(self, title: str, target: str) -> tuple[str, str]:
return f'@{title}', target


def filter_meta_fields(
app: Sphinx, domain: str, objtype: str, content: Element
) -> None:
Expand Down Expand Up @@ -748,6 +769,7 @@ class PythonDomain(Domain):
'data': PyXRefRole(),
'exc': PyXRefRole(),
'func': PyXRefRole(fix_parens=True),
'deco': _PyDecoXRefRole(),
'class': PyXRefRole(),
'const': PyXRefRole(),
'attr': PyXRefRole(),
Expand Down