|
6 | 6 | import re |
7 | 7 | import sys |
8 | 8 | from collections import ChainMap |
| 9 | +from functools import lru_cache |
9 | 10 | from typing import Any, Sequence |
10 | 11 |
|
11 | 12 | from griffe.dataclasses import Alias, Object |
|
14 | 15 |
|
15 | 16 | from mkdocstrings.extension import PluginError |
16 | 17 | from mkdocstrings.handlers.base import BaseRenderer, CollectorItem |
| 18 | +from mkdocstrings.loggers import get_logger |
17 | 19 |
|
| 20 | +logger = get_logger(__name__) |
18 | 21 | # TODO: CSS classes everywhere in templates |
19 | 22 | # TODO: name normalization (filenames, Jinja2 variables, HTML tags, CSS classes) |
20 | 23 | # TODO: Jinja2 blocks everywhere in templates |
@@ -145,15 +148,11 @@ def do_format_signature(self, signature: str, line_length: int) -> str: |
145 | 148 | Returns: |
146 | 149 | The same code, formatted. |
147 | 150 | """ |
148 | | - from black import Mode, format_str |
149 | | - |
150 | 151 | code = signature.strip() |
151 | 152 | if len(code) < line_length: |
152 | 153 | return code |
153 | | - mode = Mode(line_length=line_length) |
154 | | - formatted = format_str(f"def {code}: pass", mode=mode) |
155 | | - # remove starting `def ` and trailing `: pass` |
156 | | - return formatted[4:-5].strip()[:-1] |
| 154 | + formatter = _get_black_formatter() |
| 155 | + return formatter(code, line_length) |
157 | 156 |
|
158 | 157 | def do_order_members(self, members: Sequence[Object | Alias], order: Order) -> Sequence[Object | Alias]: |
159 | 158 | """Order members given an ordering method. |
@@ -209,3 +208,20 @@ def repl(match): # noqa: WPS430 |
209 | 208 | if code: |
210 | 209 | text = f"<code>{text}</code>" |
211 | 210 | return Markup(text).format(**variables) |
| 211 | + |
| 212 | + |
| 213 | +@lru_cache(maxsize=1) |
| 214 | +def _get_black_formatter(): |
| 215 | + try: |
| 216 | + from black import Mode, format_str |
| 217 | + except ModuleNotFoundError: |
| 218 | + logger.warning("Formatting signatures requires Black to be installed.") |
| 219 | + return lambda text, _: text |
| 220 | + |
| 221 | + def formatter(code, line_length): # noqa: WPS430 |
| 222 | + mode = Mode(line_length=line_length) |
| 223 | + formatted = format_str(f"def {code}: pass", mode=mode) |
| 224 | + # remove starting `def ` and trailing `: pass` |
| 225 | + return formatted[4:-5].strip()[:-1] |
| 226 | + |
| 227 | + return formatter |
0 commit comments