File: roles.py

package info (click to toggle)
python-sphinxcontrib-django 2.5-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 608 kB
  • sloc: python: 1,448; makefile: 20; sh: 6
file content (114 lines) | stat: -rw-r--r-- 3,995 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
"""
This module adds cross-reference types which are used in the documentation of Django and Sphinx to
allow intersphinx mappings to these custom types.
The supported text roles are:

Django:

* ``:setting:``, e.g. ``:setting:`INSTALLED_APPS``` renders as :setting:`INSTALLED_APPS`
* ``:templatetag:``, e.g. ``:templatetag:`block``` renders as :templatetag:`block`
* ``:templatefilter:``, e.g. ``:templatefilter:`add``` renders as :templatefilter:`add`
* ``:fieldlookup:``, e.g. ``:fieldlookup:`equals``` renders as :fieldlookup:`equals`

Sphinx:

* ``:event:``, e.g. ``:event:`autodoc-skip-member``` renders as :event:`autodoc-skip-member`
* ``:confval:``, e.g. ``:confval:`extensions``` renders as :confval:`extensions`

This module can also be used separately in ``conf.py``::

    extensions = [
        "sphinxcontrib_django.roles",
    ]
"""
from __future__ import annotations

import django
import os
import logging
import sys

from sphinx.application import Sphinx
from sphinx.config import Config
from sphinx.errors import ExtensionError

from . import __version__

logger = logging.getLogger(__name__)


def setup(app: Sphinx) -> dict:
    """
    Allow this module to be used as Sphinx extension.

    This is also called from the top-level :meth:`~sphinxcontrib_django.setup`.

    It adds cross-reference types via :meth:`~sphinx.application.Sphinx.add_crossref_type`.

    :param app: The Sphinx application object
    """
    # Load sphinx.ext.intersphinx extension
    app.setup_extension("sphinx.ext.intersphinx")

    # Add default intersphinx mappings after config is initialized
    app.connect("config-inited", add_default_intersphinx_mappings)

    # Allow intersphinx mappings to custom Django roles
    django_crossref_types = ["setting", "templatetag", "templatefilter", "fieldlookup"]
    # Allow intersphinx mappings to custom Sphinx roles
    sphinx_crossref_types = ["event", "confval"]

    for crossref_type in django_crossref_types + sphinx_crossref_types:
        try:
            app.add_crossref_type(directivename=crossref_type, rolename=crossref_type)
        except ExtensionError as e:
            logger.warning("Unable to register cross-reference type: %s", e)

    return {
        "version:": __version__,
        "parallel_read_safe": True,
        "parallel_write_safe": True,
    }


def add_default_intersphinx_mappings(app: Sphinx, config: Config) -> None:
    """
    This function provides a default intersphinx mapping to the documentations of Python, Django
    and Sphinx if ``intersphinx_mapping`` is not given in ``conf.py``.

    Called on the :event:`config-inited` event.

    :param app: The Sphinx application object
    :param config: The Sphinx configuration
    """
    def check_object_path(key, url, path):
        if os.path.isfile(path):
            return {key: (url, path)}
        return {}

    if not config.intersphinx_mapping:
        DEFAULT_INTERSPHINX_MAPPING = {}
        DEFAULT_INTERSPHINX_MAPPING.update(
            check_object_path(
                'python',
                f"https://docs.python.org/{sys.version_info.major}.{sys.version_info.minor}/",
                f"/usr/share/doc/python{sys.version_info.major}.{sys.version_info.minor}/html/objects.inv"
            )
        )
        DEFAULT_INTERSPHINX_MAPPING.update(
            check_object_path(
                'sphinx',
                'https://www.sphinx-doc.org/en/master/',
                '/usr/share/doc/sphinx-doc/html/objects.inv'
            )
        )
        DEFAULT_INTERSPHINX_MAPPING.update(
            check_object_path(
                'django',
                'https://docs.djangoproject.com/en/' + '.'.join((str(c) for c in django.VERSION[:2])) + '/_objects/',
                '/usr/share/doc/python-django-doc/html/objects.inv'
            )
        )

        # TYPING: type hints are missing `.intersphinx_mapping` attribute.
        config.intersphinx_mapping = DEFAULT_INTERSPHINX_MAPPING  # type: ignore[attr-defined ]