@@ -8,11 +8,13 @@
88from functools import lru_cache
99from typing import TYPE_CHECKING, Any, Callable, Match, Pattern, Sequence
101011+from jinja2 import pass_context
1112from markupsafe import Markup
1213from mkdocstrings.loggers import get_logger
13141415if TYPE_CHECKING:
15-from griffe.dataclasses import Alias, Object
16+from griffe.dataclasses import Alias, Function, Object
17+from jinja2.runtime import Context
1618from mkdocstrings.handlers.base import CollectorItem
17191820logger = get_logger(__name__)
@@ -60,33 +62,51 @@ def do_format_code(code: str, line_length: int) -> str:
6062return formatter(code, line_length)
6163626463-def do_format_signature(signature: str, line_length: int) -> str:
64-"""Format a signature using Black.
65-66- Parameters:
67- signature: The signature to format.
68- line_length: The line length to give to Black.
69-70- Returns:
71- The same code, formatted.
72- """
73-code = signature.strip()
74-if len(code) < line_length:
75-return code
65+def _format_signature(name: Markup, signature: str, line_length: int) -> str:
66+name = str(name).strip() # type: ignore[assignment]
67+signature = signature.strip()
68+if len(name + signature) < line_length:
69+return name + signature
76707771# Black cannot format names with dots, so we replace
7872# the whole name with a string of equal length
79-name_length = code.index("(")
80-name = code[:name_length]
73+name_length = len(name)
8174formatter = _get_black_formatter()
82-formatable = f"def {'x' * name_length}{code[name_length:]}: pass"
75+formatable = f"def {'x' * name_length}{signature}: pass"
8376formatted = formatter(formatable, line_length)
84778578# We put back the original name
8679# and remove starting `def ` and trailing `: pass`
8780return name + formatted[4:-5].strip()[name_length:-1]
8881898283+@pass_context
84+def do_format_signature(
85+context: Context,
86+callable_path: Markup,
87+function: Function,
88+line_length: int,
89+*,
90+crossrefs: bool = False, # noqa: ARG001
91+) -> str:
92+"""Format a signature using Black.
93+94+ Parameters:
95+ callable_path: The path of the callable we render the signature of.
96+ line_length: The line length to give to Black.
97+ crossrefs: Whether to cross-reference types in the signature.
98+99+ Returns:
100+ The same code, formatted.
101+ """
102+env = context.environment
103+template = env.get_template("signature.html")
104+signature = template.render(context.parent, function=function)
105+signature = _format_signature(callable_path, signature, line_length)
106+signature = str(env.filters["highlight"](signature, language="python", inline=False))
107+return signature
108+109+90110def do_order_members(
91111members: Sequence[Object | Alias],
92112order: Order,