mkdocstrings-python 1.18.2__py3-none-any.whl → 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. mkdocstrings_handlers/python/__init__.py +0 -4
  2. mkdocstrings_handlers/python/_internal/config.py +20 -48
  3. mkdocstrings_handlers/python/_internal/debug.py +1 -1
  4. mkdocstrings_handlers/python/_internal/handler.py +26 -45
  5. mkdocstrings_handlers/python/_internal/rendering.py +50 -113
  6. mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja +2 -4
  7. mkdocstrings_handlers/python/templates/material/_base/backlinks.html.jinja +49 -0
  8. mkdocstrings_handlers/python/templates/material/_base/class.html.jinja +58 -18
  9. mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html.jinja +4 -8
  10. mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html.jinja +1 -2
  11. mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html.jinja +1 -2
  12. mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html.jinja +1 -2
  13. mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html.jinja +1 -2
  14. mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html.jinja +4 -8
  15. mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html.jinja +7 -14
  16. mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html.jinja +4 -8
  17. mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html.jinja +5 -10
  18. mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html.jinja +5 -10
  19. mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html.jinja +1 -1
  20. mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html.jinja +9 -9
  21. mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html.jinja +4 -8
  22. mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html.jinja +5 -10
  23. mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja +15 -30
  24. mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja +3 -0
  25. mkdocstrings_handlers/python/templates/material/_base/function.html.jinja +6 -10
  26. mkdocstrings_handlers/python/templates/material/_base/language.html.jinja +3 -6
  27. mkdocstrings_handlers/python/templates/material/_base/module.html.jinja +4 -8
  28. mkdocstrings_handlers/python/templates/material/_base/signature.html.jinja +3 -6
  29. mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html.jinja +1 -2
  30. mkdocstrings_handlers/python/templates/material/_base/summary/classes.html.jinja +1 -2
  31. mkdocstrings_handlers/python/templates/material/_base/summary/functions.html.jinja +1 -2
  32. mkdocstrings_handlers/python/templates/material/_base/summary/modules.html.jinja +1 -2
  33. mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html.jinja +1 -2
  34. mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja +5 -10
  35. mkdocstrings_handlers/python/templates/material/_base/type_alias.html.jinja +3 -6
  36. mkdocstrings_handlers/python/templates/material/_base/type_parameters.html.jinja +2 -4
  37. mkdocstrings_handlers/python/templates/material/style.css +24 -0
  38. mkdocstrings_handlers/python/templates/readthedocs/_base/class.html +11 -0
  39. mkdocstrings_handlers/python/templates/readthedocs/_base/class.html.jinja +251 -0
  40. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html.jinja +2 -4
  41. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html.jinja +2 -4
  42. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html.jinja +3 -6
  43. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html.jinja +2 -4
  44. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html.jinja +2 -4
  45. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html.jinja +2 -4
  46. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html.jinja +2 -4
  47. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html.jinja +2 -4
  48. mkdocstrings_handlers/python/templates/readthedocs/_base/language.html.jinja +3 -6
  49. mkdocstrings_handlers/python/templates/{material → readthedocs}/class.html +0 -1
  50. mkdocstrings_handlers/python/templates/readthedocs/class.html.jinja +1 -0
  51. mkdocstrings_python-2.0.0.dist-info/METADATA +179 -0
  52. mkdocstrings_python-2.0.0.dist-info/RECORD +121 -0
  53. {mkdocstrings_python-1.18.2.dist-info → mkdocstrings_python-2.0.0.dist-info}/WHEEL +1 -1
  54. mkdocstrings_handlers/python/config.py +0 -17
  55. mkdocstrings_handlers/python/handler.py +0 -17
  56. mkdocstrings_handlers/python/rendering.py +0 -17
  57. mkdocstrings_handlers/python/templates/material/_base/attribute.html +0 -10
  58. mkdocstrings_handlers/python/templates/material/_base/children.html +0 -10
  59. mkdocstrings_handlers/python/templates/material/_base/class.html +0 -10
  60. mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html +0 -10
  61. mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html +0 -10
  62. mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html +0 -10
  63. mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html +0 -10
  64. mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html +0 -10
  65. mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html +0 -10
  66. mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html +0 -10
  67. mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html +0 -10
  68. mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html +0 -10
  69. mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html +0 -10
  70. mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html +0 -10
  71. mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html +0 -10
  72. mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html +0 -10
  73. mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html +0 -10
  74. mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html +0 -10
  75. mkdocstrings_handlers/python/templates/material/_base/docstring.html +0 -10
  76. mkdocstrings_handlers/python/templates/material/_base/expression.html +0 -10
  77. mkdocstrings_handlers/python/templates/material/_base/function.html +0 -10
  78. mkdocstrings_handlers/python/templates/material/_base/labels.html +0 -10
  79. mkdocstrings_handlers/python/templates/material/_base/language.html +0 -10
  80. mkdocstrings_handlers/python/templates/material/_base/languages/en.html +0 -10
  81. mkdocstrings_handlers/python/templates/material/_base/languages/ja.html +0 -10
  82. mkdocstrings_handlers/python/templates/material/_base/languages/zh.html +0 -10
  83. mkdocstrings_handlers/python/templates/material/_base/module.html +0 -10
  84. mkdocstrings_handlers/python/templates/material/_base/signature.html +0 -10
  85. mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html +0 -10
  86. mkdocstrings_handlers/python/templates/material/_base/summary/classes.html +0 -10
  87. mkdocstrings_handlers/python/templates/material/_base/summary/functions.html +0 -10
  88. mkdocstrings_handlers/python/templates/material/_base/summary/modules.html +0 -10
  89. mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html +0 -10
  90. mkdocstrings_handlers/python/templates/material/_base/summary.html +0 -10
  91. mkdocstrings_handlers/python/templates/material/_base/type_alias.html +0 -10
  92. mkdocstrings_handlers/python/templates/material/_base/type_parameters.html +0 -10
  93. mkdocstrings_handlers/python/templates/material/attribute.html +0 -2
  94. mkdocstrings_handlers/python/templates/material/children.html +0 -2
  95. mkdocstrings_handlers/python/templates/material/docstring/admonition.html +0 -2
  96. mkdocstrings_handlers/python/templates/material/docstring/attributes.html +0 -2
  97. mkdocstrings_handlers/python/templates/material/docstring/classes.html +0 -2
  98. mkdocstrings_handlers/python/templates/material/docstring/examples.html +0 -2
  99. mkdocstrings_handlers/python/templates/material/docstring/functions.html +0 -2
  100. mkdocstrings_handlers/python/templates/material/docstring/modules.html +0 -2
  101. mkdocstrings_handlers/python/templates/material/docstring/other_parameters.html +0 -2
  102. mkdocstrings_handlers/python/templates/material/docstring/parameters.html +0 -2
  103. mkdocstrings_handlers/python/templates/material/docstring/raises.html +0 -2
  104. mkdocstrings_handlers/python/templates/material/docstring/receives.html +0 -2
  105. mkdocstrings_handlers/python/templates/material/docstring/returns.html +0 -2
  106. mkdocstrings_handlers/python/templates/material/docstring/warns.html +0 -2
  107. mkdocstrings_handlers/python/templates/material/docstring/yields.html +0 -2
  108. mkdocstrings_handlers/python/templates/material/docstring.html +0 -2
  109. mkdocstrings_handlers/python/templates/material/expression.html +0 -2
  110. mkdocstrings_handlers/python/templates/material/function.html +0 -2
  111. mkdocstrings_handlers/python/templates/material/labels.html +0 -2
  112. mkdocstrings_handlers/python/templates/material/language.html +0 -2
  113. mkdocstrings_handlers/python/templates/material/languages/en.html +0 -2
  114. mkdocstrings_handlers/python/templates/material/languages/ja.html +0 -2
  115. mkdocstrings_handlers/python/templates/material/languages/zh.html +0 -2
  116. mkdocstrings_handlers/python/templates/material/module.html +0 -2
  117. mkdocstrings_handlers/python/templates/material/signature.html +0 -2
  118. mkdocstrings_handlers/python/templates/material/summary/attributes.html +0 -2
  119. mkdocstrings_handlers/python/templates/material/summary/classes.html +0 -2
  120. mkdocstrings_handlers/python/templates/material/summary/functions.html +0 -2
  121. mkdocstrings_handlers/python/templates/material/summary/modules.html +0 -2
  122. mkdocstrings_handlers/python/templates/material/summary.html +0 -2
  123. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html +0 -10
  124. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html +0 -10
  125. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html +0 -10
  126. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html +0 -10
  127. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html +0 -10
  128. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html +0 -10
  129. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html +0 -10
  130. mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html +0 -10
  131. mkdocstrings_handlers/python/templates/readthedocs/_base/language.html +0 -10
  132. mkdocstrings_handlers/python/templates/readthedocs/_base/languages/en.html +0 -10
  133. mkdocstrings_handlers/python/templates/readthedocs/_base/languages/ja.html +0 -10
  134. mkdocstrings_handlers/python/templates/readthedocs/_base/languages/zh.html +0 -10
  135. mkdocstrings_handlers/python/templates/readthedocs/docstring/attributes.html +0 -2
  136. mkdocstrings_handlers/python/templates/readthedocs/docstring/other_parameters.html +0 -2
  137. mkdocstrings_handlers/python/templates/readthedocs/docstring/parameters.html +0 -2
  138. mkdocstrings_handlers/python/templates/readthedocs/docstring/raises.html +0 -2
  139. mkdocstrings_handlers/python/templates/readthedocs/docstring/receives.html +0 -2
  140. mkdocstrings_handlers/python/templates/readthedocs/docstring/returns.html +0 -2
  141. mkdocstrings_handlers/python/templates/readthedocs/docstring/warns.html +0 -2
  142. mkdocstrings_handlers/python/templates/readthedocs/docstring/yields.html +0 -2
  143. mkdocstrings_handlers/python/templates/readthedocs/language.html +0 -2
  144. mkdocstrings_handlers/python/templates/readthedocs/languages/en.html +0 -2
  145. mkdocstrings_handlers/python/templates/readthedocs/languages/ja.html +0 -2
  146. mkdocstrings_handlers/python/templates/readthedocs/languages/zh.html +0 -2
  147. mkdocstrings_python-1.18.2.dist-info/METADATA +0 -117
  148. mkdocstrings_python-1.18.2.dist-info/RECORD +0 -211
  149. {mkdocstrings_python-1.18.2.dist-info → mkdocstrings_python-2.0.0.dist-info}/entry_points.txt +0 -0
  150. {mkdocstrings_python-1.18.2.dist-info → mkdocstrings_python-2.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -24,14 +24,12 @@ from mkdocstrings_handlers.python._internal.rendering import (
24
24
  do_as_modules_section,
25
25
  do_as_type_aliases_section,
26
26
  do_backlink_tree,
27
- do_crossref,
28
27
  do_filter_objects,
29
28
  do_format_attribute,
30
29
  do_format_code,
31
30
  do_format_signature,
32
31
  do_format_type_alias,
33
32
  do_get_template,
34
- do_multi_crossref,
35
33
  do_order_members,
36
34
  do_split_path,
37
35
  do_stash_crossref,
@@ -59,14 +57,12 @@ __all__ = [
59
57
  "do_as_modules_section",
60
58
  "do_as_type_aliases_section",
61
59
  "do_backlink_tree",
62
- "do_crossref",
63
60
  "do_filter_objects",
64
61
  "do_format_attribute",
65
62
  "do_format_code",
66
63
  "do_format_signature",
67
64
  "do_format_type_alias",
68
65
  "do_get_template",
69
- "do_multi_crossref",
70
66
  "do_order_members",
71
67
  "do_split_path",
72
68
  "do_stash_crossref",
@@ -39,18 +39,6 @@ try:
39
39
  if getattr(pydantic, "__version__", "1.").startswith("1."):
40
40
  raise ImportError # noqa: TRY301
41
41
 
42
- # YORE: EOL 3.9: Remove block.
43
- if sys.version_info < (3, 10):
44
- try:
45
- import eval_type_backport # noqa: F401
46
- except ImportError:
47
- _logger.debug(
48
- "Pydantic needs the `eval-type-backport` package to be installed "
49
- "for modern type syntax to work on Python 3.9. "
50
- "Deactivating Pydantic validation for Python handler options.",
51
- )
52
- raise
53
-
54
42
  from inspect import cleandoc
55
43
 
56
44
  from pydantic import Field as BaseField
@@ -87,14 +75,7 @@ if TYPE_CHECKING:
87
75
  from collections.abc import MutableMapping
88
76
 
89
77
 
90
- # YORE: EOL 3.9: Remove block.
91
- _dataclass_options = {"frozen": True}
92
- if sys.version_info >= (3, 10):
93
- _dataclass_options["kw_only"] = True
94
-
95
-
96
- # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
97
- @dataclass(**_dataclass_options) # type: ignore[call-overload]
78
+ @dataclass(frozen=True, kw_only=True)
98
79
  class GoogleStyleOptions:
99
80
  """Google style docstring options."""
100
81
 
@@ -205,8 +186,7 @@ class GoogleStyleOptions:
205
186
  ] = True
206
187
 
207
188
 
208
- # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
209
- @dataclass(**_dataclass_options) # type: ignore[call-overload]
189
+ @dataclass(frozen=True, kw_only=True)
210
190
  class NumpyStyleOptions:
211
191
  """Numpy style docstring options."""
212
192
 
@@ -256,8 +236,7 @@ class NumpyStyleOptions:
256
236
  ] = True
257
237
 
258
238
 
259
- # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
260
- @dataclass(**_dataclass_options) # type: ignore[call-overload]
239
+ @dataclass(frozen=True, kw_only=True)
261
240
  class SphinxStyleOptions:
262
241
  """Sphinx style docstring options."""
263
242
 
@@ -289,8 +268,7 @@ class SphinxStyleOptions:
289
268
  ] = True
290
269
 
291
270
 
292
- # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
293
- @dataclass(**_dataclass_options) # type: ignore[call-overload]
271
+ @dataclass(frozen=True, kw_only=True)
294
272
  class PerStyleOptions:
295
273
  """Per style options."""
296
274
 
@@ -333,8 +311,7 @@ class PerStyleOptions:
333
311
  return cls(**data)
334
312
 
335
313
 
336
- # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
337
- @dataclass(**_dataclass_options) # type: ignore[call-overload]
314
+ @dataclass(frozen=True, kw_only=True)
338
315
  class AutoStyleOptions:
339
316
  """Auto style docstring options."""
340
317
 
@@ -382,8 +359,7 @@ class AutoStyleOptions:
382
359
  return cls(**data)
383
360
 
384
361
 
385
- # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
386
- @dataclass(**_dataclass_options) # type: ignore[call-overload]
362
+ @dataclass(frozen=True, kw_only=True)
387
363
  class SummaryOption:
388
364
  """Summary option."""
389
365
 
@@ -433,8 +409,7 @@ class SummaryOption:
433
409
  ] = False
434
410
 
435
411
 
436
- # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
437
- @dataclass(**_dataclass_options) # type: ignore[call-overload]
412
+ @dataclass(frozen=True, kw_only=True)
438
413
  class PythonInputOptions:
439
414
  """Accepted input options."""
440
415
 
@@ -519,9 +494,6 @@ class PythonInputOptions:
519
494
 
520
495
  **Filtering methods**
521
496
 
522
- [:octicons-heart-fill-24:{ .pulse } Sponsors only](../insiders/index.md){ .insiders } &mdash;
523
- [:octicons-tag-24: Insiders 1.11.0](../insiders/changelog.md#1.11.0)
524
-
525
497
  The `public` method will include only public objects:
526
498
  those added to `__all__` or not starting with an underscore (except for special methods/attributes).
527
499
  """,
@@ -560,6 +532,14 @@ class PythonInputOptions:
560
532
  ),
561
533
  ] = 2
562
534
 
535
+ inheritance_diagram_direction: Annotated[
536
+ Literal["TB", "TD", "BT", "RL", "LR"],
537
+ _Field(
538
+ group="docstrings",
539
+ description="The direction of the Mermaid chart presenting the inheritance diagram of a class.",
540
+ ),
541
+ ] = "TD"
542
+
563
543
  inherited_members: Annotated[
564
544
  bool | list[str],
565
545
  _Field(
@@ -1062,8 +1042,7 @@ class PythonInputOptions:
1062
1042
  return cls(**cls.coerce(**data))
1063
1043
 
1064
1044
 
1065
- # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
1066
- @dataclass(**_dataclass_options) # type: ignore[call-overload]
1045
+ @dataclass(frozen=True, kw_only=True)
1067
1046
  class PythonOptions(PythonInputOptions): # type: ignore[override,unused-ignore]
1068
1047
  """Final options passed as template context."""
1069
1048
 
@@ -1080,11 +1059,7 @@ class PythonOptions(PythonInputOptions): # type: ignore[override,unused-ignore]
1080
1059
  @classmethod
1081
1060
  def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
1082
1061
  """Create an instance from a dictionary."""
1083
- if "filters" in data:
1084
- # Non-insiders: transform back to default filters.
1085
- # Next: `if "filters" in data and not isinstance(data["filters"], str):`.
1086
- if data["filters"] == "public":
1087
- data["filters"] = _DEFAULT_FILTERS
1062
+ if "filters" in data and not isinstance(data["filters"], str):
1088
1063
  # Filters are `None` or a sequence of strings (tests use tuples).
1089
1064
  data["filters"] = [
1090
1065
  (re.compile(filtr.removeprefix("!")), filtr.startswith("!")) for filtr in data["filters"] or ()
@@ -1092,8 +1067,7 @@ class PythonOptions(PythonInputOptions): # type: ignore[override,unused-ignore]
1092
1067
  return super().coerce(**data)
1093
1068
 
1094
1069
 
1095
- # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
1096
- @dataclass(**_dataclass_options) # type: ignore[call-overload]
1070
+ @dataclass(frozen=True, kw_only=True)
1097
1071
  class Inventory:
1098
1072
  """An inventory."""
1099
1073
 
@@ -1126,8 +1100,7 @@ class Inventory:
1126
1100
  return {"base_url": self.base_url, "domains": self.domains}
1127
1101
 
1128
1102
 
1129
- # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
1130
- @dataclass(**_dataclass_options) # type: ignore[call-overload]
1103
+ @dataclass(frozen=True, kw_only=True)
1131
1104
  class PythonInputConfig:
1132
1105
  """Python handler configuration."""
1133
1106
 
@@ -1169,8 +1142,7 @@ class PythonInputConfig:
1169
1142
  return cls(**cls.coerce(**data))
1170
1143
 
1171
1144
 
1172
- # YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
1173
- @dataclass(**_dataclass_options) # type: ignore[call-overload]
1145
+ @dataclass(frozen=True, kw_only=True)
1174
1146
  class PythonConfig(PythonInputConfig): # type: ignore[override,unused-ignore]
1175
1147
  """Python handler configuration."""
1176
1148
 
@@ -85,7 +85,7 @@ def _get_debug_info() -> _Environment:
85
85
  interpreter_version=py_version,
86
86
  interpreter_path=sys.executable,
87
87
  platform=platform.platform(),
88
- variables=[_Variable(var, val) for var in variables if (val := os.getenv(var))],
88
+ variables=[_Variable(var, val) for var in variables if (val := os.getenv(var))], # ty: ignore[invalid-argument-type]
89
89
  packages=[_Package(pkg, _get_version(pkg)) for pkg in packages],
90
90
  )
91
91
 
@@ -10,7 +10,6 @@ from contextlib import suppress
10
10
  from dataclasses import asdict
11
11
  from pathlib import Path
12
12
  from typing import TYPE_CHECKING, Any, BinaryIO, ClassVar
13
- from warnings import warn
14
13
 
15
14
  from griffe import (
16
15
  AliasResolutionError,
@@ -22,15 +21,17 @@ from griffe import (
22
21
  patch_loggers,
23
22
  )
24
23
  from mkdocs.exceptions import PluginError
24
+ from mkdocs_autorefs import BacklinkCrumb
25
25
  from mkdocstrings import BaseHandler, CollectionError, CollectorItem, HandlerOptions, Inventory, get_logger
26
26
 
27
27
  from mkdocstrings_handlers.python._internal import rendering
28
28
  from mkdocstrings_handlers.python._internal.config import PythonConfig, PythonOptions
29
29
 
30
30
  if TYPE_CHECKING:
31
- from collections.abc import Iterator, Mapping, MutableMapping, Sequence
31
+ from collections.abc import Iterable, Iterator, Mapping, MutableMapping, Sequence
32
32
 
33
33
  from mkdocs.config.defaults import MkDocsConfig
34
+ from mkdocs_autorefs import Backlink
34
35
 
35
36
 
36
37
  # YORE: EOL 3.10: Replace block with line 2.
@@ -54,17 +55,6 @@ _logger = get_logger(__name__)
54
55
  patch_loggers(get_logger)
55
56
 
56
57
 
57
- # YORE: Bump 2: Remove block.
58
- def _warn_extra_options(names: Sequence[str]) -> None:
59
- warn(
60
- "Passing extra options directly under `options` is deprecated. "
61
- "Instead, pass them under `options.extra`, and update your templates. "
62
- f"Current extra (unrecognized) options: {', '.join(sorted(names))}",
63
- DeprecationWarning,
64
- stacklevel=3,
65
- )
66
-
67
-
68
58
  class PythonHandler(BaseHandler):
69
59
  """The Python handler class."""
70
60
 
@@ -95,18 +85,9 @@ class PythonHandler(BaseHandler):
95
85
  self.base_dir = base_dir
96
86
  """The base directory of the project."""
97
87
 
98
- # YORE: Bump 2: Remove block.
99
- global_extra, global_options = PythonOptions._extract_extra(config.options)
100
- if global_extra:
101
- _warn_extra_options(global_extra.keys()) # type: ignore[arg-type]
102
- self._global_extra = global_extra
103
- self.global_options = global_options
88
+ self.global_options = config.options
104
89
  """The global configuration options (in `mkdocs.yml`)."""
105
90
 
106
- # YORE: Bump 2: Replace `# ` with `` within block.
107
- # self.global_options = config.options
108
- # """The global configuration options (in `mkdocs.yml`)."""
109
-
110
91
  # Warn if user overrides base templates.
111
92
  if self.custom_templates:
112
93
  for theme_dir in base_dir.joinpath(self.custom_templates, "python").iterdir():
@@ -186,25 +167,13 @@ class PythonHandler(BaseHandler):
186
167
  Returns:
187
168
  The combined options.
188
169
  """
189
- # YORE: Bump 2: Remove block.
190
- local_extra, local_options = PythonOptions._extract_extra(local_options) # type: ignore[arg-type]
191
- if local_extra:
192
- _warn_extra_options(local_extra.keys()) # type: ignore[arg-type]
193
- unknown_extra = self._global_extra | local_extra
194
-
195
170
  extra = {**self.global_options.get("extra", {}), **local_options.get("extra", {})}
196
171
  options = {**self.global_options, **local_options, "extra": extra}
197
172
  try:
198
- # YORE: Bump 2: Replace `opts =` with `return` within line.
199
- opts = PythonOptions.from_data(**options)
173
+ return PythonOptions.from_data(**options)
200
174
  except Exception as error:
201
175
  raise PluginError(f"Invalid options: {error}") from error
202
176
 
203
- # YORE: Bump 2: Remove block.
204
- for key, value in unknown_extra.items():
205
- object.__setattr__(opts, key, value)
206
- return opts
207
-
208
177
  def collect(self, identifier: str, options: PythonOptions) -> CollectorItem:
209
178
  """Collect the documentation for the given identifier.
210
179
 
@@ -289,7 +258,7 @@ class PythonHandler(BaseHandler):
289
258
  Returns:
290
259
  The rendered data (HTML).
291
260
  """
292
- template_name = rendering.do_get_template(self.env, data)
261
+ template_name = rendering.do_get_template(data)
293
262
  template = self.env.get_template(template_name)
294
263
 
295
264
  return template.render(
@@ -301,11 +270,28 @@ class PythonHandler(BaseHandler):
301
270
  # than as an item in a dictionary.
302
271
  "heading_level": options.heading_level,
303
272
  "root": True,
304
- # YORE: Bump 2: Regex-replace ` or .+` with ` or "en",` within line.
305
- "locale": locale or self.config.locale,
273
+ "locale": locale or "en",
306
274
  },
307
275
  )
308
276
 
277
+ def render_backlinks(self, backlinks: Mapping[str, Iterable[Backlink]], *, locale: str | None = None) -> str: # noqa: ARG002
278
+ """Render the backlinks.
279
+
280
+ Parameters:
281
+ backlinks: The backlinks to render.
282
+
283
+ Returns:
284
+ The rendered backlinks (HTML).
285
+ """
286
+ template = self.env.get_template("backlinks.html.jinja")
287
+ verbose_type = {key: key.capitalize().replace("-by", " by") for key in backlinks.keys()} # noqa: SIM118
288
+ return template.render(
289
+ backlinks=backlinks,
290
+ config=self.get_options({}),
291
+ verbose_type=verbose_type,
292
+ default_crumb=BacklinkCrumb(title="", url=""),
293
+ )
294
+
309
295
  def update_env(self, config: Any) -> None: # noqa: ARG002
310
296
  """Update the Jinja environment with custom filters and tests.
311
297
 
@@ -316,8 +302,6 @@ class PythonHandler(BaseHandler):
316
302
  self.env.lstrip_blocks = True
317
303
  self.env.keep_trailing_newline = False
318
304
  self.env.filters["split_path"] = rendering.do_split_path
319
- self.env.filters["crossref"] = rendering.do_crossref
320
- self.env.filters["multi_crossref"] = rendering.do_multi_crossref
321
305
  self.env.filters["order_members"] = rendering.do_order_members
322
306
  self.env.filters["format_code"] = rendering.do_format_code
323
307
  self.env.filters["format_signature"] = rendering.do_format_signature
@@ -414,10 +398,7 @@ def get_handler(
414
398
  # We therefore increase the limit here, once, before Griffe is used to collect or render stuff.
415
399
  sys.setrecursionlimit(max(sys.getrecursionlimit(), 2000))
416
400
 
417
- base_dir = Path(tool_config.config_file_path or "./mkdocs.yml").parent
418
- if "inventories" not in handler_config and "import" in handler_config:
419
- warn("The 'import' key is renamed 'inventories' for the Python handler", FutureWarning, stacklevel=1)
420
- handler_config["inventories"] = handler_config.pop("import", [])
401
+ base_dir = Path(getattr(tool_config, "config_file_path", None) or "./mkdocs.yml").parent
421
402
  return PythonHandler(
422
403
  config=PythonConfig.from_data(**handler_config),
423
404
  base_dir=base_dir,
@@ -7,13 +7,11 @@ import re
7
7
  import string
8
8
  import subprocess
9
9
  import sys
10
- import warnings
11
10
  from collections import defaultdict
12
11
  from contextlib import suppress
13
12
  from dataclasses import replace
14
13
  from functools import lru_cache
15
- from pathlib import Path
16
- from re import Match, Pattern
14
+ from re import Pattern
17
15
  from typing import TYPE_CHECKING, Any, Callable, ClassVar, Literal, TypeVar
18
16
 
19
17
  from griffe import (
@@ -33,7 +31,7 @@ from griffe import (
33
31
  Object,
34
32
  TypeAlias,
35
33
  )
36
- from jinja2 import TemplateNotFound, pass_context, pass_environment
34
+ from jinja2 import pass_context
37
35
  from markupsafe import Markup
38
36
  from mkdocs_autorefs import AutorefsHookInterface, Backlink, BacklinkCrumb
39
37
  from mkdocstrings import get_logger
@@ -42,7 +40,6 @@ if TYPE_CHECKING:
42
40
  from collections.abc import Iterable, Iterator, Sequence
43
41
 
44
42
  from griffe import Attribute, Class, Function, Module
45
- from jinja2 import Environment
46
43
  from jinja2.runtime import Context
47
44
  from mkdocstrings import CollectorItem
48
45
 
@@ -62,8 +59,15 @@ def _sort_key_source(item: CollectorItem) -> float:
62
59
  return item.lineno if item.lineno is not None else float("inf")
63
60
 
64
61
 
65
- def _sort__all__(item: CollectorItem) -> float: # noqa: ARG001
66
- raise ValueError("Not implemented in public version of mkdocstrings-python")
62
+ def _sort__all__(item: CollectorItem) -> float:
63
+ if item.parent.exports is not None:
64
+ try:
65
+ return item.parent.exports.index(item.name)
66
+ except ValueError:
67
+ # If the item is not in `__all__`, it will go to the end of the list.
68
+ return float("inf")
69
+ # No exports declared, refuse to sort (try other methods or return members as they are).
70
+ raise ValueError(f"Parent object {item.parent.path} doesn't declare exports")
67
71
 
68
72
 
69
73
  Order = Literal["__all__", "alphabetical", "source"]
@@ -163,10 +167,8 @@ def do_format_signature(
163
167
  The same code, formatted.
164
168
  """
165
169
  env = context.environment
166
- # YORE: Bump 2: Replace `do_get_template(env, "type_parameters")` with `"type_parameters.html.jinja"` within line.
167
- type_params_template = env.get_template(do_get_template(env, "type_parameters"))
168
- # YORE: Bump 2: Replace `do_get_template(env, "signature")` with `"signature.html.jinja"` within line.
169
- signature_template = env.get_template(do_get_template(env, "signature"))
170
+ type_params_template = env.get_template("type_parameters.html.jinja")
171
+ signature_template = env.get_template("signature.html.jinja")
170
172
 
171
173
  if annotations is None:
172
174
  new_context = context.parent
@@ -230,8 +232,7 @@ def do_format_attribute(
230
232
  The same code, formatted.
231
233
  """
232
234
  env = context.environment
233
- # YORE: Bump 2: Replace `do_get_template(env, "expression")` with `"expression.html.jinja"` within line.
234
- template = env.get_template(do_get_template(env, "expression"))
235
+ template = env.get_template("expression.html.jinja")
235
236
  annotations = context.parent["config"].show_signature_annotations
236
237
 
237
238
  signature = str(attribute_path).strip()
@@ -288,10 +289,8 @@ def do_format_type_alias(
288
289
  The same code, formatted.
289
290
  """
290
291
  env = context.environment
291
- # YORE: Bump 2: Replace `do_get_template(env, "type_parameters")` with `"type_parameters.html.jinja"` within line.
292
- type_params_template = env.get_template(do_get_template(env, "type_parameters"))
293
- # YORE: Bump 2: Replace `do_get_template(env, "expression")` with `"expression.html.jinja"` within line.
294
- expr_template = env.get_template(do_get_template(env, "expression"))
292
+ type_params_template = env.get_template("type_parameters.html.jinja")
293
+ expr_template = env.get_template("expression.html.jinja")
295
294
 
296
295
  signature = str(type_alias_path).strip()
297
296
  signature += type_params_template.render(context.parent, obj=type_alias, signature=True)
@@ -357,76 +356,6 @@ def do_order_members(
357
356
  return members
358
357
 
359
358
 
360
- # YORE: Bump 2: Remove block.
361
- @lru_cache
362
- def _warn_crossref() -> None:
363
- warnings.warn(
364
- "The `crossref` filter is deprecated and will be removed in a future version",
365
- DeprecationWarning,
366
- stacklevel=1,
367
- )
368
-
369
-
370
- # YORE: Bump 2: Remove block.
371
- def do_crossref(path: str, *, brief: bool = True) -> Markup:
372
- """Deprecated. Filter to create cross-references.
373
-
374
- Parameters:
375
- path: The path to link to.
376
- brief: Show only the last part of the path, add full path as hover.
377
-
378
- Returns:
379
- Markup text.
380
- """
381
- _warn_crossref()
382
- full_path = path
383
- if brief:
384
- path = full_path.split(".")[-1]
385
- return Markup("<autoref identifier={full_path} optional hover>{path}</autoref>").format(
386
- full_path=full_path,
387
- path=path,
388
- )
389
-
390
-
391
- # YORE: Bump 2: Remove block.
392
- @lru_cache
393
- def _warn_multi_crossref() -> None:
394
- warnings.warn(
395
- "The `multi_crossref` filter is deprecated and will be removed in a future version",
396
- DeprecationWarning,
397
- stacklevel=1,
398
- )
399
-
400
-
401
- # YORE: Bump 2: Remove block.
402
- def do_multi_crossref(text: str, *, code: bool = True) -> Markup:
403
- """Deprecated. Filter to create cross-references.
404
-
405
- Parameters:
406
- text: The text to scan.
407
- code: Whether to wrap the result in a code tag.
408
-
409
- Returns:
410
- Markup text.
411
- """
412
- _warn_multi_crossref()
413
- group_number = 0
414
- variables = {}
415
-
416
- def repl(match: Match) -> str:
417
- nonlocal group_number
418
- group_number += 1
419
- path = match.group()
420
- path_var = f"path{group_number}"
421
- variables[path_var] = path
422
- return f"<autoref identifier={{{path_var}}} optional hover>{{{path_var}}}</autoref>"
423
-
424
- text = re.sub(r"([\w.]+)", repl, text)
425
- if code:
426
- text = f"<code>{text}</code>"
427
- return Markup(text).format(**variables) # noqa: S704
428
-
429
-
430
359
  _split_path_re = re.compile(r"([.(]?)([\w]+)(\))?")
431
360
  _splitable_re = re.compile(r"[().]")
432
361
 
@@ -641,39 +570,20 @@ def _get_black_formatter() -> Callable[[str, int], str] | None:
641
570
  return formatter
642
571
 
643
572
 
644
- # YORE: Bump 2: Remove line.
645
- @pass_environment
646
- # YORE: Bump 2: Replace `env: Environment, ` with `` within line.
647
- # YORE: Bump 2: Replace `str | ` with `` within line.
648
- def do_get_template(env: Environment, obj: str | Object) -> str:
573
+ def do_get_template(obj: Object | Alias) -> str:
649
574
  """Get the template name used to render an object.
650
575
 
651
576
  Parameters:
652
- env: The Jinja environment, passed automatically.
653
- obj: A Griffe object, or a template name.
577
+ obj: A Griffe object.
654
578
 
655
579
  Returns:
656
580
  A template name.
657
581
  """
658
- name = obj
659
- if isinstance(obj, (Alias, Object)):
660
- extra_data = getattr(obj, "extra", {}).get("mkdocstrings", {})
661
- if name := extra_data.get("template", ""):
662
- return name
663
- name = obj.kind.value.replace(" ", "_")
664
- # YORE: Bump 2: Replace block with `return f"{name}.html.jinja"`.
665
- try:
666
- template = env.get_template(f"{name}.html")
667
- except TemplateNotFound:
668
- return f"{name}.html.jinja"
669
- our_template = Path(template.filename).is_relative_to(Path(__file__).parent.parent) # type: ignore[arg-type]
670
- if our_template:
671
- return f"{name}.html.jinja"
672
- _logger.warning(
673
- f"DeprecationWarning: Overriding '{name}.html' is deprecated, override '{name}.html.jinja' instead. ",
674
- once=True,
675
- )
676
- return f"{name}.html"
582
+ extra_data = getattr(obj, "extra", {}).get("mkdocstrings", {})
583
+ if name := extra_data.get("template", ""):
584
+ return name
585
+ name = obj.kind.value.replace(" ", "_")
586
+ return f"{name}.html.jinja"
677
587
 
678
588
 
679
589
  @pass_context
@@ -856,6 +766,33 @@ class AutorefsHook(AutorefsHookInterface):
856
766
  Returns:
857
767
  The expanded identifier.
858
768
  """
769
+ # Handle leading dots in the identifier:
770
+ # - `.name` is a reference to the current object's `name` member.
771
+ # - `..name` is a reference to the parent object's `name` member.
772
+ # - etc.
773
+ # TODO: We should update the protocol to allow modifying the title too.
774
+ # In this case it would likely be better to strip dots from the title,
775
+ # when it's not explicitly specified.
776
+ if self.config.relative_crossrefs and identifier.startswith("."): # type: ignore[attr-defined]
777
+ identifier = identifier[1:]
778
+ obj = self.current_object
779
+ while identifier and identifier[0] == ".":
780
+ identifier = identifier[1:]
781
+ obj = obj.parent # type: ignore[assignment]
782
+ identifier = f"{obj.path}.{identifier}" if identifier else obj.path
783
+
784
+ # We resolve the identifier to its full path.
785
+ # For this we take out the first name, resolve it, and then append the rest.
786
+ if self.config.scoped_crossrefs: # type: ignore[attr-defined]
787
+ if "." in identifier:
788
+ identifier, remaining = identifier.split(".", 1)
789
+ else:
790
+ remaining = ""
791
+ with suppress(Exception):
792
+ identifier = self.current_object.resolve(identifier)
793
+ if remaining:
794
+ identifier = f"{identifier}.{remaining}"
795
+
859
796
  return identifier
860
797
 
861
798
  def get_context(self) -> AutorefsHookInterface.Context:
@@ -67,8 +67,7 @@ Context:
67
67
  This block renders the labels for the attribute.
68
68
  -#}
69
69
  {% with labels = attribute.labels %}
70
- {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
71
- {% include "labels"|get_template with context %}
70
+ {% include "labels.html.jinja" with context %}
72
71
  {% endwith %}
73
72
  {% endblock labels %}
74
73
 
@@ -115,8 +114,7 @@ Context:
115
114
  This block renders the docstring for the attribute.
116
115
  -#}
117
116
  {% with docstring_sections = attribute.docstring.parsed %}
118
- {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
119
- {% include "docstring"|get_template with context %}
117
+ {% include "docstring.html.jinja" with context %}
120
118
  {% endwith %}
121
119
  {% endblock docstring %}
122
120
 
@@ -15,3 +15,52 @@ Context:
15
15
  This block can be used to log debug messages, deprecation messages, warnings, etc.
16
16
  -#}
17
17
  {% endblock logs %}
18
+
19
+ {% macro render_crumb(crumb, last=false) %}
20
+ <span class="doc doc-backlink-crumb{{ " last" if last else "" }}">
21
+ {% if crumb.url and crumb.title %}
22
+ <a href="{{ crumb.url }}">{{ crumb.title | safe }}</a>
23
+ {% elif crumb.title %}
24
+ <span>{{ crumb.title | safe }}</span>
25
+ {% endif %}
26
+ </span>
27
+ {% endmacro %}
28
+
29
+ {% macro render_tree(tree) %}
30
+ <ul class="doc doc-backlink-list">
31
+ {% for node, child in tree | dictsort %}
32
+ <li class="doc doc-backlink">
33
+ {% for crumb in node %}
34
+ {{ render_crumb(crumb, last=loop.last and not child) }}
35
+ {% endfor %}
36
+ {% if child %}
37
+ {{ render_tree(child) }}
38
+ {% endif %}
39
+ </li>
40
+ {% endfor %}
41
+ </ul>
42
+ {% endmacro %}
43
+
44
+ {% if config.backlinks %}
45
+ <div class="doc doc-backlinks">
46
+ {% if config.backlinks == "tree" %}
47
+ {% for backlink_type, backlink_list in backlinks | dictsort %}
48
+ <b class="doc doc-backlink-type">{{ verbose_type[backlink_type] }}:</b>
49
+ {{ render_tree(backlink_list|backlink_tree) }}
50
+ {% endfor %}
51
+ {% elif config.backlinks == "flat" %}
52
+ {% for backlink_type, backlink_list in backlinks | dictsort %}
53
+ <b class="doc doc-backlink-type">{{ verbose_type[backlink_type] }}:</b>
54
+ <ul class="doc doc-backlink-list">
55
+ {% for backlink in backlink_list | sort(attribute="crumbs") %}
56
+ <li class="doc doc-backlink">
57
+ {% for crumb in backlink.crumbs %}
58
+ {{ render_crumb(crumb, last=loop.last) }}
59
+ {% endfor %}
60
+ </li>
61
+ {% endfor %}
62
+ </ul>
63
+ {% endfor %}
64
+ {% endif %}
65
+ </div>
66
+ {% endif %}