Coverage for src/mkdocstrings_handlers/python/rendering.py: 100.00%
24 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-09 18:38 +0100
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-09 18:38 +0100
1"""This module implements rendering utilities."""
3import sys
4from typing import Any, Callable
6from markupsafe import Markup
7from mkdocstrings import CollectorItem, get_logger
9log = get_logger(__name__)
12def do_brief_xref(path: str) -> Markup:
13 """Filter to create cross-reference with brief text and full identifier as hover text.
15 Arguments:
16 path: The path to shorten and render.
18 Returns:
19 A span containing the brief cross-reference and the full one on hover.
20 """
21 brief = path.split(".")[-1]
22 return Markup("<autoref identifier={path} optional hover>{brief}</autoref>").format(path=path, brief=brief)
25def sort_object(obj: CollectorItem, sort_function: Callable[[CollectorItem], Any]) -> None:
26 """Sort the collected object's children.
28 Sorts the object's children list, then each category separately, and then recurses into each.
30 Arguments:
31 obj: The collected object, as a dict. Note that this argument is mutated.
32 sort_function: The sort key function used to determine the order of elements.
33 """
34 obj["children"].sort(key=sort_function)
36 for category in ("attributes", "classes", "functions", "methods", "modules"):
37 obj[category].sort(key=sort_function)
39 for child in obj["children"]:
40 sort_object(child, sort_function=sort_function)
43def sort_key_alphabetical(item: CollectorItem) -> Any:
44 """Return an item's name or the final unicode character.
46 Arguments:
47 item: A collected item.
49 Returns:
50 Name or final unicode character.
51 """
52 # chr(sys.maxunicode) is a string that contains the final unicode
53 # character, so if 'name' isn't found on the object, the item will go to
54 # the end of the list.
55 return item.get("name", chr(sys.maxunicode))
58def sort_key_source(item: CollectorItem) -> Any:
59 """Return an item's starting line number or -1.
61 Arguments:
62 item: A collected item.
64 Returns:
65 Starting line number or -1.
66 """
67 # if 'line_start' isn't found on the object, the item will go to
68 # the start of the list.
69 return item.get("source", {}).get("line_start", -1)
72def rebuild_category_lists(obj: dict) -> None:
73 """Recursively rebuild the category lists of a collected object.
75 Since `pytkdocs` dumps JSON on standard output, it must serialize the object-tree and flatten it to reduce data
76 duplication and avoid cycle-references. Indeed, each node of the object-tree has a `children` list, containing
77 all children, and another list for each category of children: `attributes`, `classes`, `functions`, `methods`
78 and `modules`. It replaces the values in category lists with only the paths of the objects.
80 Here, we reconstruct these category lists by picking objects in the `children` list using their path.
82 For each object, we recurse on every one of its children.
84 Arguments:
85 obj: The collected object, loaded back from JSON into a Python dictionary.
86 """
87 for category in ("attributes", "classes", "functions", "methods", "modules"):
88 obj[category] = [obj["children"][path] for path in obj[category]]
89 obj["children"] = [child for _, child in obj["children"].items()]
90 for child in obj["children"]:
91 rebuild_category_lists(child)