pyTooling.Sphinx

Summary

Doc-string:

documented

File

Expected

Covered

Uncovered

Coverage

__init__.py

73

73

0

100.0%

Overall (25 files)

1008

1004

4

99.6%

Packages

Package

Expected

Covered

Uncovered

Coverage

Resources

1

1

0

100.0%

Modules

Module

Expected

Covered

Uncovered

Coverage

Abbreviation

41

41

0

100.0%

CodeCoverage

70

70

0

100.0%

CodeCoveragePages

22

22

0

100.0%

CondensedClass

28

27

1

96.4%

CondensedSource

28

28

0

100.0%

DependencyTable

129

127

2

98.4%

DocCoverage

76

76

0

100.0%

ExternalLink

61

61

0

100.0%

GitHubMarkdown

30

30

0

100.0%

HTML

56

56

0

100.0%

LaTeX

24

24

0

100.0%

Markdown

44

44

0

100.0%

Node

27

27

0

100.0%

Pages

47

47

0

100.0%

Roles

7

7

0

100.0%

SchemaGraph

13

13

0

100.0%

Shields

32

32

0

100.0%

Tree

31

31

0

100.0%

UnicodeTable

48

48

0

100.0%

Unittest

90

89

1

98.9%

UnittestPages

17

17

0

100.0%

Workaround

6

6

0

100.0%

XMLSchemaGraph

7

7

0

100.0%

Source

pyTooling.Sphinx/__init__.pydocumentedundocumentedignoredexcludednot counted
31"""
32A Sphinx extension providing the roles, nodes and directives shared by pyTooling and its sibling projects.
33
34Every project in the family used to carry its own :file:`doc/prolog.inc` - eighteen hand-copied files, 36 to 67
35lines each, already drifted apart - declaring the same roles as **ReST source** that is re-parsed into every
36document of every project. This extension declares them once:
37
38.. code-block:: Python
39
40   # doc/conf.py
41   extensions = [
42     ...,
43     "pyTooling.Sphinx",
44   ]
45
46.. rubric:: What it registers
47
48* the **style roles**, together with the stylesheet they need - so the styling is a CSS file instead of a
49  ``raw:: html`` block smuggled into every page - and the LaTeX package :file:`pyTooling.Sphinx.sty`, which strikes
50  through and underlines in LaTeX:
51
52  * ``:bolditalic:``, ``:underline:``, ``:strike:`` and ``:xlarge:`` - weight, decoration and size;
53  * ``:red:``, ``:green:``, ``:blue:`` and ``:purple:`` - colour, each from a CSS custom property a project can
54    redefine;
55  * ``:deletion:`` and ``:addition:`` - the two a diff needs.
56
57* the **code role**:
58
59  * ``:pycode:`` - highlights inline Python.
60
61* the **abbreviation roles**, named as in LaTeX' ``acro`` package:
62
63  * ``:acs:``, ``:acl:`` and ``:acf:`` - an abbreviation, its long form, or both;
64  * ``:acsp:``, ``:aclp:`` and ``:acfp:`` - their plurals.
65
66* the **directives**:
67
68  * :rst:dir:`condensed-class` - renders a class' public interface from its source;
69  * :rst:dir:`dependency-table` - renders a project's dependencies from its requirements files, which
70    :file:`conf.py` declares under ``pyTooling_Dependency_Requirements``;
71  * :rst:dir:`xmlschema-graph` - draws an XML schema as a Graphviz graph. It sets up :mod:`sphinx.ext.graphviz`
72    itself, and needs :mod:`xmlschema` only in a project that uses it.
73  * :rst:dir:`shields` - renders a project's badges from shields.io, in rows, from the coordinates its options
74    state: the GitHub repository, the PyPI package, the licenses, the workflow and the documentation's URL.
75  * :rst:dir:`tree` - draws a hierarchy written as an indented list as a tree, each node foldable in HTML.
76  * :rst:dir:`unicode-table` - lists icons with their Unicode names and code points, which HTML copies into the
77    clipboard on a click; the script doing so is linked like the stylesheet.
78  * :rst:dir:`abbreviations` - lists abbreviations, which the abbreviation roles refer to.
79
80* the domain ``report`` - unit test, code coverage and documentation coverage reports as tables -, with the
81  configuration values ``pyTooling_Unittest_Testsuites``, ``pyTooling_CodeCoverage_Packages`` and
82  ``pyTooling_DocCoverage_Packages`` declaring the reports. Reading a report needs the extra ``reports``
83  (pyEDAA.Reports), which is imported only then:
84
85  * :rst:dir:`report:unittest-summary` - a unit test report, per testsuite and testcase; a report declared with
86    ``pages`` gets a page per testsuite and testcase (:mod:`~pyTooling.Sphinx.UnittestPages`), which the roles
87    ``:ts:`` and ``:tc:`` - also ``:report:ts:`` and ``:report:tc:`` - refer to;
88  * :rst:dir:`report:code-coverage` and :rst:dir:`report:code-coverage-legend` - a code coverage report and its
89    coverage levels;
90  * :rst:dir:`report:doc-coverage` and :rst:dir:`report:doc-coverage-legend` - a package's documentation coverage
91    and its coverage levels; a package declared with ``pages`` gets a page per package and module
92    (:class:`~pyTooling.Sphinx.DocCoverage.DocCoverageReportPages`), which the role ``:doccov:`` refers to.
93
94* the **nodes** the directives emit, listed in :data:`NODES` with their visitors per output format.
95
96* the **external link icons** - in HTML, an icon behind each external link, chosen by its target, and the size behind
97  each download -, with the configuration values ``pyTooling_ExternalLink_Icons``, ``pyTooling_ExternalLink_NewTab``,
98  ``pyTooling_ExternalLink_Hosts``, ``pyTooling_ExternalLink_DownloadSizes``, ``pyTooling_ExternalLink_RemoteSizes``
99  and ``pyTooling_ExternalLink_RemoteSizeTimeout`` (:mod:`~pyTooling.Sphinx.ExternalLink`).
100
101Two classes aren't registered, because they are base-classes for a project's own directives:
102:class:`~pyTooling.Sphinx.BaseDirective` offers typed option access and table construction
103over the untyped mapping and the hand-assembled node trees docutils presents, and
104:class:`~pyTooling.Sphinx.SchemaGraph.SchemaGraph` draws a schema file named as a directive's
105argument, leaving only the reading of that schema to a derived class.
106
107.. attention::
108
109   This package requires **Python 3.12 or newer**, because it requires Sphinx 9.1 and Sphinx 9.1 does.
110
111.. seealso::
112
113   :mod:`pyTooling.Documentation`
114      |rarr| The doc-string helpers, which need no Sphinx.
115"""
116__author__ =            "Patrick Lehmann"
117__email__ =             "Paebbels@gmail.com"
118__copyright__ =         "2026-2026, Patrick Lehmann"
119__license__ =           "Apache License, Version 2.0"
120__version__ =           "1.0.0"
121__keywords__ =          ["Sphinx", "Sphinx Extension", "Documentation", "Directive", "Role", "Domain", "docutils"]
122__project_url__ =       "https://github.com/pyTooling/pyTooling.Sphinx"
123__documentation_url__ = "https://pyTooling.github.io/pyTooling.Sphinx"
124__issue_tracker_url__ = "https://GitHub.com/pyTooling/pyTooling.Sphinx/issues"
125
...
169
171__all__ = [
172	"STYLESHEET", "SCRIPT", "LATEX_PACKAGE", "SUBSTITUTIONS", "NODES", "LINE_ANCHOR", "REPORT_ROLES"
173]
174
175STYLESHEET = "pyTooling.css"
176"""Name of the stylesheet, in :mod:`pyTooling.Sphinx.Resources`."""
177
178SCRIPT = "pyTooling.js"
179"""
180Name of the script, in :mod:`pyTooling.Sphinx.Resources`: it gives the copy buttons of the ``unicode-table``
181directive their function.
182"""
183
184LATEX_PACKAGE = "pyTooling.Sphinx"
185"""
186Name of the LaTeX package, whose file :file:`pyTooling.Sphinx.sty` is in :mod:`pyTooling.Sphinx.Resources`: it
187defines the commands LaTeX writes for the style roles ``:strike:`` and ``:underline:``.
188"""
189
190SUBSTITUTIONS = """
191.. |degree| unicode:: U+00B0
192   :trim:
193
194.. |br| replace:: :br:`.`
195
196.. |hr| replace:: :hr:`.`
197"""
198"""
199Substitutions that have to stay substitutions, because ``|br|`` is written as one in every project.
200
201``|br|`` and ``|hr|`` delegate to the ``:br:`` and ``:hr:`` roles rather than writing HTML themselves, so they
202reach every output format instead of only HTML - see :func:`~pyTooling.Sphinx.Roles.breakRole`.
203"""
204
205NODES: tuple[RegisteredNode, ...] = (
206	{"name": "TreeItem",           "node": TreeItem,           "html": translateTreeItem},
207	{"name": "TreeLabel",          "node": TreeLabel,          "html": translateTreeLabel},
208	{"name": "TreeSeparator",      "node": TreeSeparator,      "html": translateTreeSeparator},
209	{"name": "TreeDescription",    "node": TreeDescription,    "html": translateTreeDescription},
210	{"name": "TreeLegend",         "node": TreeLegend,         "html": translateTreeLegend},
211	{"name": "TreeLegendItem",     "node": TreeLegendItem,     "html": translateTreeLegendItem},
212	{"name": "CopyButton",         "node": CopyButton,         "html": translateCopyButton},
213	{"name": "Abbreviation",       "node": Abbreviation,       "html": translateAbbreviation},
214	{"name": "Landscape",          "node": Landscape,          "html": translateLandscapeAsHTML,
215	 "latex": translateLandscapeAsLaTeX},
216	{"name": "CoverageListing",    "node": CoverageListing,    "html": translateCoverageListingAsHTML,
217	 "latex": translateCoverageListingAsLaTeX},
218	{"name": "DocCoverageListing", "node": DocCoverageListing, "html": translateDocCoverageListingAsHTML,
219	 "latex": translateDocCoverageListingAsLaTeX},
220	{"name": "Emoji",              "node": Emoji,              "html": translateEmoji},
221	{"name": "TaskListCheckbox",   "node": TaskListCheckbox,   "html": translateTaskListCheckboxAsHTML,
222	 "latex": translateTaskListCheckboxAsLaTeX},
223	{"name": "LineBreak",          "node": LineBreak,          "html": translateLineBreakAsHTML,
224	 "latex": translateLineBreakAsLaTeX},
225	{"name": "ReportIndentation",  "node": ReportIndentation,  "html": translateReportIndentationAsHTML,
226	 "latex": translateReportIndentationAsLaTeX},
227	{"name": "FoldedDependencies", "node": FoldedDependencies, "html": translateFoldedDependencies},
228	{"name": "FoldedSummary",      "node": FoldedSummary,      "html": translateFoldedSummary},
229)
230"""
231The nodes the extension registers, each with its visitors per output format.
232
233A format without visitors of its own - e.g. LaTeX for the tree's nodes - writes a node with the visitors of its
234base-class.
235"""
236
238@export
239class SphinxExtensionError(ExtensionError, DocumentationError):
240	"""
241	Base-exception of all exceptions raised by :mod:`pyTooling.Sphinx`.
242
243	It derives from **both** hierarchies on purpose: :exc:`~sphinx.errors.ExtensionError` is what Sphinx catches and
244	reports with the position of the directive, and :exc:`~pyTooling.Documentation.DocumentationError` is what a
245	caller of pyTooling catches. Neither would be enough alone.
246	"""
247
249@export
250class ReportExtensionError(SphinxExtensionError):
251	"""
252	The exception raised by the ``report`` domain.
253
254	It is raised e.g. for a mistake in the domain's configuration values or options.
255	"""
256
258@export
259class ReportsPackageMissingError(ReportExtensionError):
260	"""
261	The exception raised when a report is read, but the optional packages of the extra ``reports`` aren't installed.
262
263	The message names what was attempted and the packages it needs; a note says how to install them.
264	"""
265
266	def __init__(self, task: str, packages: str = "'pyEDAA.Reports'") -> None:
267		"""
268		Initialize the exception with what was attempted and the packages it needs.
269
270		:param task:     What needs the packages, e.g. ``Reading a unit test report``.
271		:param packages: Optional, the packages needed, quoted. Default: ``'pyEDAA.Reports'``.
272		"""
		...
275
277@export
278class LegendStyle(StringEnum):
279	"""
280	How a legend directive of domain ``report`` lays out the coverage levels, as its option ``:style:`` states it.
281	"""
282
283	HorizontalTable = "horizontal-table"  #: A table with a column per level.
284	VerticalTable =   "vertical-table"    #: A table with a row per level.
285
286	DEFAULT =         HorizontalTable     #: Without the option, a legend has a column per level.
287
289@export
290def strip(option: str) -> str:
291	"""
292	Option converter removing surrounding whitespace.
293
294	:param option: The option's value as it was written.
295	:returns:      The value without surrounding whitespace.
296	"""
	...
298
300@export
301def stripAndNormalize(option: str) -> str:
302	"""
303	Option converter removing surrounding whitespace and lowering the case.
304
305	:param option: The option's value as it was written.
306	:returns:      The value without surrounding whitespace, in lower case.
307	"""
	...
309
311@export
312class BaseDirective(ObjectDescription[str]):
313	"""
314	Base-class for a directive, offering typed option access and table construction.
315
316	A derived class sets :attr:`directiveName` - which is what the error messages name - and declares
317	``option_spec`` as any directive does. What it gets in return is a ``_Parse***Option`` per type instead of
318	reaching into :attr:`options` and validating by hand, and a ``_Create***TableHeader`` per table shape instead of
319	assembling :class:`~docutils.nodes.tgroup`, :class:`~docutils.nodes.colspec`, :class:`~docutils.nodes.thead`
320	and :class:`~docutils.nodes.row` in the right order.
321	"""
322
323	has_content =               False  #: A boolean; ``True`` if content is allowed.
324	required_arguments =        0      #: Number of required directive arguments.
325	optional_arguments =        0      #: Number of optional arguments after the required ones.
326	final_argument_whitespace = False  #: A boolean; ``True`` if the last argument may contain spaces.
327	option_spec =               {}     #: Mapping of option names to validator functions.
328
329	directiveName: str  #: Name the directive is invoked by, used in every error message.
330
331	def _ParseBooleanOption(self, optionName: str, default: Nullable[bool] = None) -> bool:
332		"""
333		Read an option written as ``yes``/``true`` or ``no``/``false``.
334
335		:param optionName:             Name of the option to read.
336		:param default:                Optional, the value to return when the option wasn't given.
337		:returns:                      The option's value.
338		:raises SphinxExtensionError:  If the option wasn't given and has no default.
339		:raises SphinxExtensionError:  If the option's value is neither of the two accepted spellings.
340		"""
		...
359
360	def _ParseStringOption(self, optionName: str, default: Nullable[str] = None, regexp: str = "\\w+") -> str:
361		"""
362		Read an option that has to match a regular expression.
363
364		The pattern defaults to one or more word characters.
365
366		:param optionName:             Name of the option to read.
367		:param default:                Optional, the value to return when the option wasn't given.
368		:param regexp:                 Optional, the pattern the value has to match.
369		:returns:                      The option's value.
370		:raises SphinxExtensionError:  If the option wasn't given and has no default.
371		:raises SphinxExtensionError:  If the option's value doesn't match the pattern.
372		"""
		...
389
390	def _CreateSingleRowTableHeader(
391		self,
392		columns: list[tuple[str, Nullable[int]]],
393		identifier: str,
394		classes: list[str]
395	) -> nodes.tgroup:
396		"""
397		Create a table with a single header row.
398
399		:param columns:    One ``(title, width)`` pair per column; a width of ``None`` leaves it to the writer.
400		:param identifier: Identifier of the table.
401		:param classes:    CSS classes to put on the table.
402		:returns:          The table's column group, with the header row already in it.
403		"""
		...
419
420	def _CreateDoubleRowTableHeader(
421		self,
422		columns: list[tuple[str, Nullable[list[tuple[str, int]]], Nullable[int]]],
423		identifier: str,
424		classes: list[str]
425	) -> nodes.tgroup:
426		"""
427		Create a table whose header spans two rows, so a column can group sub-columns.
428
429		A column's ``subColumns`` is ``None`` when it spans both header rows, and otherwise holds the
430		``(title, width)`` pairs below it.
431
432		:param columns:    One ``(title, subColumns, width)`` triple per column.
433		:param identifier: Identifier of the table.
434		:param classes:    CSS classes to put on the table.
435		:returns:          The table's column group, with both header rows already in it.
436		"""
		...
473
474	def _CreateRotatedTableHeader(
475		self,
476		columns: list[tuple[str, Nullable[list[str]]]],
477		identifier: str,
478		classes: list[str]
479	) -> nodes.tgroup:
480		"""
481		Create a table whose header titles are rotated, for many narrow columns.
482
483		:param columns:    One ``(title, classes)`` pair per column; the classes are put on the header cell.
484		:param identifier: Identifier of the table.
485		:param classes:    CSS classes to put on the table.
486		:returns:          The table's column group, with the header row already in it.
487		"""
		...
505
506	def _internalError(
507		self,
508		container: nodes.container,
509		location: str,
510		message: str,
511		exception: Exception
512	) -> list[nodes.Node]:
513		"""
514		Report an exception a directive couldn't recover from, in the log **and** on the page.
515
516		A directive that fails silently leaves a hole in the documentation that nobody notices. This puts the message
517		where a reader sees it and the traceback where a maintainer does. The exception's notes - e.g. how to install a
518		missing package - are logged below it.
519
520		:param container: The container the message is put into.
521		:param location:  Name of the logger, which is what the log line is attributed to.
522		:param message:   What went wrong, in one sentence.
523		:param exception: The exception that was caught.
524		:returns:         The container, as the list a directive's ``run`` returns.
525		"""
		...
539
541@export
542def installStaticFiles(sphinx: Sphinx) -> None:
543	"""
544	Call-back for Sphinx' ``builder-inited`` event, writing the stylesheet and the script into the build and linking
545	them.
546
547	A file is named by the hash of its content, so a browser re-reads it when it changes and re-uses it when it doesn't.
548	Older copies are removed when the content changed.
549
550	:param sphinx: The Sphinx application.
551	"""
	...
570
572@export
573def installLaTeXPackage(sphinx: Sphinx) -> None:
574	"""
575	Call-back for Sphinx' ``builder-inited`` event, writing the LaTeX package :data:`LATEX_PACKAGE` into the build of a
576	LaTeX builder, where the document's ``\\usepackage`` finds it.
577
578	:param sphinx: The Sphinx application.
579	"""
	...
586
588@export
589def extendProlog(sphinx: Sphinx, config: Any) -> None:
590	"""
591	Call-back for Sphinx' ``config-inited`` event, appending the shared substitutions to ``rst_prolog``.
592
593	A role can be registered; a **substitution** cannot - ``|br|`` is substitution syntax, and every project writes
594	it that way already. Appending them here is what lets a project delete them from its own prolog without changing
595	a single document.
596
597	:param sphinx: The Sphinx application.
598	:param config: The configuration, after :file:`conf.py` was read.
599	"""
	...
601
603@export
604def setLaTeXDefaults(sphinx: Sphinx, config: Config) -> None:
605	"""
606	Call-back for Sphinx' ``config-inited`` event, setting LaTeX defaults, unless :file:`conf.py` sets them.
607
608	* ``latex_table_style``: ``["booktabs"]``, without Sphinx' default ``colorrows``.
609	* ``latex_elements["maxlistdepth"]``: ``"10"`` nested lists, e.g. a :rst:dir:`tree` with more than 4 levels.
610
611	:param sphinx: The Sphinx application.
612	:param config: The configuration, after :file:`conf.py` was read.
613	"""
	...
618
620@export
621class ReportEntry(NamedTuple):
622	"""
623	An object of a report shown by a generated page - a testcase, a source file, ...: where it is, and its names.
624
625	An object is shown by a page of its own, or - with an anchor - by a part of another page.
626	"""
627
628	docName:   str                    #: Name of the generated document showing the object.
629	reportID:  str                    #: Identifier of the report in its configuration value.
630	path:      tuple[str, ...]        #: Names of the objects from the report's root down to this object's own name.
631	separator: str                    #: Separator of the names in a qualified name, e.g. ``.`` or ``/``.
632	title:     Nullable[str]          #: Title of the object written for a reader, if the report has one.
633	anchor:    Nullable[str] = None   #: Anchor of the object's part of the page, or ``None`` for the whole page.
634
635	@readonly
636	def Name(self) -> str:
637		"""
638		Read-only property to return the object's own name, the last element of :attr:`path`.
639
640		:returns: The name.
641		"""
		...
643
644	@readonly
645	def QualifiedName(self) -> str:
646		"""
647		Read-only property to return the qualified name: the names of :attr:`path` joined by :attr:`separator`.
648
649		:returns: The qualified name, e.g. ``pytest.tests.unit.Arithmetic.Addition.test_Positive``.
650		"""
		...
652
653	def Matches(self, name: str) -> bool:
654		"""
655		Check whether a name is the qualified name or a suffix of it, which starts at an element of :attr:`path`.
656
657		:param name: The name as written in a reference, without a report ID.
658		:returns:    ``True`` if the name is the qualified name or one of its suffixes.
659		"""
		...
661
663@export
664class ReportRoleDefinition(NamedTuple):
665	"""
666	What a role of domain ``report`` refers to: a kind of object of the reports declared in a configuration value.
667	"""
668
669	objectType:  str           #: The object type, as listed by the domain, e.g. ``testcase``.
670	configValue: str           #: The configuration value declaring the reports; its first report is the default one.
671	reports:     str           #: The reports, as a warning names them, e.g. ``unit test reports``.
672	lineAnchors: bool = False  #: Whether a target may end in ``#<line number>``, linking to the line on the page.
673
675LINE_ANCHOR = re_compile(r"#(\d+)$")
676"""The line number a target of a role with line anchors may end in, e.g. ``#12`` of ``src/Counter.vhdl#12``."""
677
678REPORT_ROLES = {
679	"tc":     ReportRoleDefinition("testcase",  "pyTooling_Unittest_Testsuites",   "unit test reports"),
680	"ts":     ReportRoleDefinition("testsuite", "pyTooling_Unittest_Testsuites",   "unit test reports"),
681	"cov":    ReportRoleDefinition("source",    "pyTooling_CodeCoverage_Packages", "code coverage reports", True),
682	"doccov": ReportRoleDefinition("module",    "pyTooling_DocCoverage_Packages",  "documentation coverage reports"),
683}
684"""The roles referring to the objects of reports with pages, by role name."""
685
687@export
688class ReportRole(XRefRole):
689	"""
690	A role of domain ``report`` referring to an object of a report with pages.
691
692	Role ``tc`` refers to a testcase, ``ts`` to a testsuite.
693
694	Sphinx registers a role outside a domain without one, so the reference would be resolved by nobody; this role puts
695	its domain - ``report``, or the one of a domain derived from :class:`ReportDomain` - on the reference, and uses its
696	name as the reference's type. So it works as ``:report:tc:`` and as the global ``:tc:``.
697	"""
698
699	_domain: str  #: Name of the domain resolving the role's references.
700
701	def __init__(self, *, domain: str = "report", **kwargs: Any) -> None:
702		"""
703		Initializes a role of domain ``report``, or of a domain derived from :class:`ReportDomain`.
704
705		:param domain:      Optional, name of the domain resolving the role's references. Default: ``"report"``.
706		:param kwargs:      The parameters of :class:`~sphinx.roles.XRefRole`, e.g. ``innernodeclass``.
707		:raises ValueError: If parameter 'domain' is None.
708		:raises TypeError:  If parameter 'domain' is not of type :class:`str`.
709		"""
		...
720
721	def run(self) -> tuple[list[nodes.Node], list[nodes.system_message]]:
722		"""
723		Create the reference, or only the text if the role is written with ``!``.
724
725		:returns: The nodes and messages a role returns.
726		"""
		...
735
737@export
738class ReportDomain(Domain):
739	"""
740	The Sphinx domain ``report``, integrating unit test, code coverage and documentation coverage reports.
741
742	Its directives are registered by :func:`setup`, and read their reports from the files declared in :file:`conf.py`.
743
744	A report with generated pages contributes an object per page - e.g. a unit test report its testsuites and
745	testcases -, which the roles of :data:`REPORT_ROLES` refer to, e.g. ``:report:tc:``, also registered as ``:tc:``. A
746	reference names an object by its qualified name, or by a suffix of it, optionally preceded by the report's
747	identifier and a colon; without one, the first report of the role's configuration value is meant.
748
749	A domain of another family of reports - e.g. a build summary of a simulation framework - derives from it: it names
750	its roles in :attr:`_ROLES`, and declares :attr:`name`, :attr:`object_types`, :attr:`initial_data`, :attr:`roles` and
751	:attr:`dangling_warnings` from them, as this domain does from :data:`REPORT_ROLES`. Its roles are
752	:class:`ReportRole` instances naming the domain.
753	"""
754
755	_ROLES: ClassVar[dict[str, ReportRoleDefinition]] = REPORT_ROLES  #: The domain's roles, by role name.
756
757	name =         "report"  #: Name of the domain, the prefix of its directives.
758	label =        "rpt"     #: Name of the domain, as displayed.
759	data_version = 2         #: Version of the domain data's layout; a pickled environment of another version is dropped.
760
761	object_types = {
762		definition.objectType: ObjType(definition.objectType, roleName) for roleName, definition in REPORT_ROLES.items()
763	}  #: The objects: per role, the objects of the reports with generated pages.
764	initial_data: dict[str, Any] = {
765		roleName: {} for roleName in REPORT_ROLES
766	}  #: The data of an empty documentation: per role, no object.
767	roles = {
768		roleName: ReportRole(innernodeclass=nodes.inline, warn_dangling=True) for roleName in REPORT_ROLES
769	}  #: The roles, also registered without the domain's prefix.
770	dangling_warnings = {
771		roleName: f"{definition.objectType} '%(target)s' not found in the {definition.reports}"
772		for roleName, definition in REPORT_ROLES.items()
773	}  #: The warning for a reference to an unknown object, per role.
774
775	def AddEntry(self, roleName: str, entry: ReportEntry) -> None:
776		"""
777		Register an object, which has a generated page.
778
779		:param roleName: The role referring to the object, e.g. ``tc`` for a testcase.
780		:param entry:    The object.
781		"""
		...
783
784	def FindEntries(self, roleName: str, target: str) -> list[ReportEntry]:
785		"""
786		Find the objects a reference's target names.
787
788		A target is ``[<report ID>:]<name>``. If the part before the first colon isn't the identifier of a report, the
789		whole target is the name in the default report - the first one of the role's configuration value -, as e.g. a
790		parametrized testcase's name may contain a colon. A name is a qualified name or a suffix of one (see
791		:meth:`ReportEntry.Matches`); an exact qualified name wins over suffixes.
792
793		:param roleName: The role referring to the object, e.g. ``tc`` for a testcase.
794		:param target:   The reference's target.
795		:returns:        The matching entries: none, one, or several if the name is ambiguous.
796		"""
		...
812
813	def clear_doc(self, docname: str) -> None:
814		"""
815		Forget the objects of a document, before it is generated again.
816
817		:param docname: Name of the document.
818		"""
		...
823
824	def merge_domaindata(self, docnames: Iterable[str], otherdata: dict[str, Any]) -> None:
825		"""
826		Take over the objects a parallel reader collected for its documents.
827
828		:param docnames:  Names of the documents the other reader read.
829		:param otherdata: The other reader's domain data.
830		"""
		...
838
839	def resolve_xref(
840		self,
841		env: BuildEnvironment,
842		fromdocname: str,
843		builder: Builder,
844		typ: str,
845		target: str,
846		node: pending_xref,
847		contnode: nodes.Element
848	) -> Nullable[nodes.Element]:
849		"""
850		Resolve a reference to an object of a report into a link to its page.
851
852		The link shows the object's name, or the title written in the role; in HTML, its title written for a reader - if
853		the report has one - is shown on hover. It points to the object's anchor, if it has one, and to a line, if the
854		target ends in one. An ambiguous name is warned about and shown as text.
855
856		:param env:         The build environment.
857		:param fromdocname: Name of the document holding the reference.
858		:param builder:     The builder writing the documents.
859		:param typ:         The role's name, e.g. ``tc``.
860		:param target:      The object referred to.
861		:param node:        The reference.
862		:param contnode:    The reference's text.
863		:returns:           The link, the text if the name is ambiguous or the builder doesn't write the page, or
864		                    ``None`` if nothing matches.
865		"""
		...
897
898	def resolve_any_xref(
899		self,
900		env: BuildEnvironment,
901		fromdocname: str,
902		builder: Builder,
903		target: str,
904		node: pending_xref,
905		contnode: nodes.Element
906	) -> list[tuple[str, nodes.reference]]:
907		"""
908		Resolve a reference of role ``:any:`` to an object of a report with an unambiguous name.
909
910		:param env:         The build environment.
911		:param fromdocname: Name of the document holding the reference.
912		:param builder:     The builder writing the documents.
913		:param target:      The text referred to.
914		:param node:        The reference.
915		:param contnode:    The reference's text.
916		:returns:           A role and link per kind of object the text names unambiguously.
917		"""
		...
927
928	def get_objects(self) -> Iterator[tuple[str, str, str, str, str, int]]:
929		"""
930		Name the objects of the reports, for the search and for other documentations referring to them.
931
932		An object's name is ``<report ID>:<qualified name>``. A testcase gets a lower search priority than a testsuite,
933		as a report may have thousands of them.
934
935		:returns: A tuple per object: name, display name, type, document, anchor and search priority.
936		"""
		...
945
947@export
948def checkReportConfiguration(sphinx: Sphinx, config: Config) -> None:
949	"""
950	Call-back for Sphinx' ``config-inited`` event, checking the reports' configuration values and loading their settings.
951
952	A mistake is logged as an error rather than stopping the build; a directive naming that report fails on its own.
953
954	:param sphinx: The Sphinx application.
955	:param config: The configuration, after :file:`conf.py` was read.
956	"""
	...
972
974@export
975def readReports(sphinx: Sphinx) -> None:
976	"""
977	Call-back for Sphinx' ``builder-inited`` event, reading the report files, analyzing the documented packages, and
978	registering the reports' pages.
979
980	:param sphinx: The Sphinx application.
981	"""
	...
994
996@export
997def setup(sphinx: Sphinx) -> dict[str, Any]:
998	"""
999	Register the roles, the nodes, the directives and the domain ``report`` with Sphinx.
1000
1001	The modules are imported here rather than with the package, and none of them imports an optional dependency at
1002	module level - e.g. pyEDAA.Reports is imported only when a report is read - so the extension works without them.
1003
1004	:param sphinx: The Sphinx application to register with.
1005	:returns:      The extension's metadata.
1006	"""
	...