Coverage for src/mkdocstrings_handlers/python/_internal/config.py: 77.99%
230 statements
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-14 23:22 +0200
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-14 23:22 +0200
1# Configuration and options dataclasses.
3from __future__ import annotations
5import re
6import sys
7from dataclasses import field, fields
8from typing import TYPE_CHECKING, Annotated, Any, Literal
10from mkdocstrings import get_logger
12from mkdocstrings_handlers.python._internal.rendering import Order # noqa: TC001
14# YORE: EOL 3.10: Replace block with line 2.
15if sys.version_info >= (3, 11):
16 from typing import Self
17else:
18 from typing_extensions import Self
21_logger = get_logger(__name__)
23_DEFAULT_FILTERS = ["!^_[^_]"]
25try:
26 # When Pydantic is available, use it to validate options (done automatically).
27 # Users can therefore opt into validation by installing Pydantic in development/CI.
28 # When building the docs to deploy them, Pydantic is not required anymore.
30 # When building our own docs, Pydantic is always installed (see `docs` group in `pyproject.toml`)
31 # to allow automatic generation of a JSON Schema. The JSON Schema is then referenced by mkdocstrings,
32 # which is itself referenced by mkdocs-material's schema system. For example in VSCode:
33 #
34 # "yaml.schemas": {
35 # "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml"
36 # }
37 import pydantic
39 if getattr(pydantic, "__version__", "1.").startswith("1."): 39 ↛ 40line 39 didn't jump to line 40 because the condition on line 39 was never true
40 raise ImportError # noqa: TRY301
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
54 from inspect import cleandoc
56 from pydantic import Field as BaseField
57 from pydantic.dataclasses import dataclass
59 _base_url = "https://mkdocstrings.github.io/python/usage"
61 def _Field( # noqa: N802
62 *args: Any,
63 description: str,
64 group: Literal["general", "headings", "members", "docstrings", "signatures"] | None = None,
65 parent: str | None = None,
66 **kwargs: Any,
67 ) -> None:
68 def _add_markdown_description(schema: dict[str, Any]) -> None:
69 url = f"{_base_url}/{f'configuration/{group}/' if group else ''}#{parent or schema['title']}"
70 schema["markdownDescription"] = f"[DOCUMENTATION]({url})\n\n{schema['description']}"
72 return BaseField(
73 *args,
74 description=cleandoc(description),
75 field_title_generator=lambda name, _: name,
76 json_schema_extra=_add_markdown_description,
77 **kwargs,
78 )
79except ImportError:
80 from dataclasses import dataclass # type: ignore[no-redef]
82 def _Field(*args: Any, **kwargs: Any) -> None: # type: ignore[misc] # noqa: N802
83 pass
86if TYPE_CHECKING:
87 from collections.abc import MutableMapping
90# YORE: EOL 3.9: Remove block.
91_dataclass_options = {"frozen": True}
92if sys.version_info >= (3, 10):
93 _dataclass_options["kw_only"] = True
96# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
97@dataclass(**_dataclass_options) # type: ignore[call-overload]
98class GoogleStyleOptions:
99 """Google style docstring options."""
101 ignore_init_summary: Annotated[
102 bool,
103 _Field(
104 group="docstrings",
105 parent="docstring_options",
106 description="Whether to ignore the summary in `__init__` methods' docstrings.",
107 ),
108 ] = False
110 returns_multiple_items: Annotated[
111 bool,
112 _Field(
113 group="docstrings",
114 parent="docstring_options",
115 description="""Whether to parse multiple items in `Yields` and `Returns` sections.
117 When true, each item's continuation lines must be indented.
118 When false (single item), no further indentation is required.
119 """,
120 ),
121 ] = True
123 returns_named_value: Annotated[
124 bool,
125 _Field(
126 group="docstrings",
127 parent="docstring_options",
128 description="""Whether to parse `Yields` and `Returns` section items as name and description, rather than type and description.
130 When true, type must be wrapped in parentheses: `(int): Description.`. Names are optional: `name (int): Description.`.
131 When false, parentheses are optional but the items cannot be named: `int: Description`.
132 """,
133 ),
134 ] = True
136 returns_type_in_property_summary: Annotated[
137 bool,
138 _Field(
139 group="docstrings",
140 parent="docstring_options",
141 description="Whether to parse the return type of properties at the beginning of their summary: `str: Summary of the property`.",
142 ),
143 ] = False
145 receives_multiple_items: Annotated[
146 bool,
147 _Field(
148 group="docstrings",
149 parent="docstring_options",
150 description="""Whether to parse multiple items in `Receives` sections.
152 When true, each item's continuation lines must be indented.
153 When false (single item), no further indentation is required.
154 """,
155 ),
156 ] = True
158 receives_named_value: Annotated[
159 bool,
160 _Field(
161 group="docstrings",
162 parent="docstring_options",
163 description="""Whether to parse `Receives` section items as name and description, rather than type and description.
165 When true, type must be wrapped in parentheses: `(int): Description.`. Names are optional: `name (int): Description.`.
166 When false, parentheses are optional but the items cannot be named: `int: Description`.
167 """,
168 ),
169 ] = True
171 trim_doctest_flags: Annotated[
172 bool,
173 _Field(
174 group="docstrings",
175 parent="docstring_options",
176 description="Whether to remove doctest flags from Python example blocks.",
177 ),
178 ] = True
180 warn_unknown_params: Annotated[
181 bool,
182 _Field(
183 group="docstrings",
184 parent="docstring_options",
185 description="Warn about documented parameters not appearing in the signature.",
186 ),
187 ] = True
189 warn_missing_types: Annotated[
190 bool,
191 _Field(
192 group="docstrings",
193 parent="docstring_options",
194 description="Warn about missing type/annotation for parameters, return values, etc.",
195 ),
196 ] = True
198 warnings: Annotated[
199 bool,
200 _Field(
201 group="docstrings",
202 parent="docstring_options",
203 description="Generally enable/disable warnings when parsing docstrings.",
204 ),
205 ] = True
208# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
209@dataclass(**_dataclass_options) # type: ignore[call-overload]
210class NumpyStyleOptions:
211 """Numpy style docstring options."""
213 ignore_init_summary: Annotated[
214 bool,
215 _Field(
216 group="docstrings",
217 parent="docstring_options",
218 description="Whether to ignore the summary in `__init__` methods' docstrings.",
219 ),
220 ] = False
222 trim_doctest_flags: Annotated[
223 bool,
224 _Field(
225 group="docstrings",
226 parent="docstring_options",
227 description="Whether to remove doctest flags from Python example blocks.",
228 ),
229 ] = True
231 warn_unknown_params: Annotated[
232 bool,
233 _Field(
234 group="docstrings",
235 parent="docstring_options",
236 description="Warn about documented parameters not appearing in the signature.",
237 ),
238 ] = True
240 warn_missing_types: Annotated[
241 bool,
242 _Field(
243 group="docstrings",
244 parent="docstring_options",
245 description="Warn about missing type/annotation for parameters, return values, etc.",
246 ),
247 ] = True
249 warnings: Annotated[
250 bool,
251 _Field(
252 group="docstrings",
253 parent="docstring_options",
254 description="Generally enable/disable warnings when parsing docstrings.",
255 ),
256 ] = True
259# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
260@dataclass(**_dataclass_options) # type: ignore[call-overload]
261class SphinxStyleOptions:
262 """Sphinx style docstring options."""
264 warn_unknown_params: Annotated[
265 bool,
266 _Field(
267 group="docstrings",
268 parent="docstring_options",
269 description="Warn about documented parameters not appearing in the signature.",
270 ),
271 ] = True
273 warn_missing_types: Annotated[
274 bool,
275 _Field(
276 group="docstrings",
277 parent="docstring_options",
278 description="Warn about missing type/annotation for return values.",
279 ),
280 ] = True
282 warnings: Annotated[
283 bool,
284 _Field(
285 group="docstrings",
286 parent="docstring_options",
287 description="Generally enable/disable warnings when parsing docstrings.",
288 ),
289 ] = True
292# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
293@dataclass(**_dataclass_options) # type: ignore[call-overload]
294class PerStyleOptions:
295 """Per style options."""
297 google: Annotated[
298 GoogleStyleOptions,
299 _Field(
300 group="docstrings",
301 parent="docstring_options",
302 description="Google-style options.",
303 ),
304 ] = field(default_factory=GoogleStyleOptions)
306 numpy: Annotated[
307 NumpyStyleOptions,
308 _Field(
309 group="docstrings",
310 parent="docstring_options",
311 description="Numpydoc-style options.",
312 ),
313 ] = field(default_factory=NumpyStyleOptions)
315 sphinx: Annotated[
316 SphinxStyleOptions,
317 _Field(
318 group="docstrings",
319 parent="docstring_options",
320 description="Sphinx-style options.",
321 ),
322 ] = field(default_factory=SphinxStyleOptions)
324 @classmethod
325 def from_data(cls, **data: Any) -> Self:
326 """Create an instance from a dictionary."""
327 if "google" in data:
328 data["google"] = GoogleStyleOptions(**data["google"])
329 if "numpy" in data:
330 data["numpy"] = NumpyStyleOptions(**data["numpy"])
331 if "sphinx" in data:
332 data["sphinx"] = SphinxStyleOptions(**data["sphinx"])
333 return cls(**data)
336# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
337@dataclass(**_dataclass_options) # type: ignore[call-overload]
338class AutoStyleOptions:
339 """Auto style docstring options."""
341 method: Annotated[
342 Literal["heuristics", "max_sections"],
343 _Field(
344 group="docstrings",
345 parent="docstring_options",
346 description="The method to use to determine the docstring style.",
347 ),
348 ] = "heuristics"
350 style_order: Annotated[
351 list[str],
352 _Field(
353 group="docstrings",
354 parent="docstring_options",
355 description="The order of the docstring styles to try.",
356 ),
357 ] = field(default_factory=lambda: ["sphinx", "google", "numpy"])
359 default: Annotated[
360 str | None,
361 _Field(
362 group="docstrings",
363 parent="docstring_options",
364 description="The default docstring style to use if no other style is detected.",
365 ),
366 ] = None
368 per_style_options: Annotated[
369 PerStyleOptions,
370 _Field(
371 group="docstrings",
372 parent="docstring_options",
373 description="Per-style options.",
374 ),
375 ] = field(default_factory=PerStyleOptions)
377 @classmethod
378 def from_data(cls, **data: Any) -> Self:
379 """Create an instance from a dictionary."""
380 if "per_style_options" in data:
381 data["per_style_options"] = PerStyleOptions.from_data(**data["per_style_options"])
382 return cls(**data)
385# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
386@dataclass(**_dataclass_options) # type: ignore[call-overload]
387class SummaryOption:
388 """Summary option."""
390 attributes: Annotated[
391 bool,
392 _Field(
393 group="members",
394 parent="summary",
395 description="Whether to render summaries of attributes.",
396 ),
397 ] = False
399 functions: Annotated[
400 bool,
401 _Field(
402 group="members",
403 parent="summary",
404 description="Whether to render summaries of functions (methods).",
405 ),
406 ] = False
408 classes: Annotated[
409 bool,
410 _Field(
411 group="members",
412 parent="summary",
413 description="Whether to render summaries of classes.",
414 ),
415 ] = False
417 modules: Annotated[
418 bool,
419 _Field(
420 group="members",
421 parent="summary",
422 description="Whether to render summaries of modules.",
423 ),
424 ] = False
427# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
428@dataclass(**_dataclass_options) # type: ignore[call-overload]
429class PythonInputOptions:
430 """Accepted input options."""
432 allow_inspection: Annotated[
433 bool,
434 _Field(
435 group="general",
436 description="Whether to allow inspecting modules when visiting them is not possible.",
437 ),
438 ] = True
440 force_inspection: Annotated[
441 bool,
442 _Field(
443 group="general",
444 description="Whether to force using dynamic analysis when loading data.",
445 ),
446 ] = False
448 annotations_path: Annotated[
449 Literal["brief", "source", "full"],
450 _Field(
451 group="signatures",
452 description="The verbosity for annotations path: `brief` (recommended), `source` (as written in the source), or `full`.",
453 ),
454 ] = "brief"
456 backlinks: Annotated[
457 Literal["flat", "tree", False],
458 _Field(
459 group="general",
460 description="Whether to render backlinks, and how.",
461 ),
462 ] = False
464 docstring_options: Annotated[
465 GoogleStyleOptions | NumpyStyleOptions | SphinxStyleOptions | AutoStyleOptions | None,
466 _Field(
467 group="docstrings",
468 description="""The options for the docstring parser.
470 See [docstring parsers](https://mkdocstrings.github.io/griffe/reference/docstrings/) and their options in Griffe docs.
471 """,
472 ),
473 ] = None
475 docstring_section_style: Annotated[
476 Literal["table", "list", "spacy"],
477 _Field(
478 group="docstrings",
479 description="The style used to render docstring sections.",
480 ),
481 ] = "table"
483 docstring_style: Annotated[
484 Literal["auto", "google", "numpy", "sphinx"] | None,
485 _Field(
486 group="docstrings",
487 description="The docstring style to use: `auto`, `google`, `numpy`, `sphinx`, or `None`.",
488 ),
489 ] = "google"
491 extensions: Annotated[
492 list[str | dict[str, Any]],
493 _Field(
494 group="general",
495 description="A list of Griffe extensions to load.",
496 ),
497 ] = field(default_factory=list)
499 filters: Annotated[
500 list[str] | Literal["public"],
501 _Field(
502 group="members",
503 description="""A list of filters, or `"public"`.
505 **List of filters**
507 A filter starting with `!` will exclude matching objects instead of including them.
508 The `members` option takes precedence over `filters` (filters will still be applied recursively
509 to lower members in the hierarchy).
511 **Filtering methods**
513 [:octicons-heart-fill-24:{ .pulse } Sponsors only](../insiders/index.md){ .insiders } —
514 [:octicons-tag-24: Insiders 1.11.0](../insiders/changelog.md#1.11.0)
516 The `public` method will include only public objects:
517 those added to `__all__` or not starting with an underscore (except for special methods/attributes).
518 """,
519 ),
520 ] = field(default_factory=lambda: _DEFAULT_FILTERS.copy())
522 find_stubs_package: Annotated[
523 bool,
524 _Field(
525 group="general",
526 description="Whether to load stubs package (package-stubs) when extracting docstrings.",
527 ),
528 ] = False
530 group_by_category: Annotated[
531 bool,
532 _Field(
533 group="members",
534 description="Group the object's children by categories: attributes, classes, functions, and modules.",
535 ),
536 ] = True
538 heading: Annotated[
539 str,
540 _Field(
541 group="headings",
542 description="A custom string to override the autogenerated heading of the root object.",
543 ),
544 ] = ""
546 heading_level: Annotated[
547 int,
548 _Field(
549 group="headings",
550 description="The initial heading level to use.",
551 ),
552 ] = 2
554 inherited_members: Annotated[
555 bool | list[str],
556 _Field(
557 group="members",
558 description="""A boolean, or an explicit list of inherited members to render.
560 If true, select all inherited members, which can then be filtered with `members`.
561 If false or empty list, do not select any inherited member.
562 """,
563 ),
564 ] = False
566 line_length: Annotated[
567 int,
568 _Field(
569 group="signatures",
570 description="Maximum line length when formatting code/signatures.",
571 ),
572 ] = 60
574 members: Annotated[
575 list[str] | bool | None,
576 _Field(
577 group="members",
578 description="""A boolean, or an explicit list of members to render.
580 If true, select all members without further filtering.
581 If false or empty list, do not render members.
582 If none, select all members and apply further filtering with filters and docstrings.
583 """,
584 ),
585 ] = None
587 members_order: Annotated[
588 Order | list[Order],
589 _Field(
590 group="members",
591 description="""The members ordering to use.
593 - `__all__`: order members according to `__all__` module attributes, if declared;
594 - `alphabetical`: order members alphabetically;
595 - `source`: order members as they appear in the source file.
597 Since `__all__` is a module-only attribute, it can't be used to sort class members,
598 therefore the `members_order` option accepts a list of ordering methods,
599 indicating ordering preferences.
600 """,
601 ),
602 ] = "alphabetical"
604 merge_init_into_class: Annotated[
605 bool,
606 _Field(
607 group="docstrings",
608 description="Whether to merge the `__init__` method into the class' signature and docstring.",
609 ),
610 ] = False
612 modernize_annotations: Annotated[
613 bool,
614 _Field(
615 group="signatures",
616 description="Whether to modernize annotations, for example `Optional[str]` into `str | None`.",
617 ),
618 ] = False
620 overloads_only: Annotated[
621 bool,
622 _Field(
623 group="signatures",
624 description="Whether to hide the implementation signature if the overloads are shown.",
625 ),
626 ] = False
628 parameter_headings: Annotated[
629 bool,
630 _Field(
631 group="headings",
632 description="Whether to render headings for parameters (therefore showing parameters in the ToC).",
633 ),
634 ] = False
636 preload_modules: Annotated[
637 list[str],
638 _Field(
639 group="general",
640 description="""Pre-load modules that are not specified directly in autodoc instructions (`::: identifier`).
642 It is useful when you want to render documentation for a particular member of an object,
643 and this member is imported from another package than its parent.
645 For an imported member to be rendered, you need to add it to the `__all__` attribute
646 of the importing module.
648 The modules must be listed as an array of strings.
649 """,
650 ),
651 ] = field(default_factory=list)
653 relative_crossrefs: Annotated[
654 bool,
655 _Field(
656 group="docstrings",
657 description="Whether to enable the relative crossref syntax.",
658 ),
659 ] = False
661 scoped_crossrefs: Annotated[
662 bool,
663 _Field(
664 group="docstrings",
665 description="Whether to enable the scoped crossref ability.",
666 ),
667 ] = False
669 show_overloads: Annotated[
670 bool,
671 _Field(
672 group="signatures",
673 description="Show the overloads of a function or method.",
674 ),
675 ] = True
677 separate_signature: Annotated[
678 bool,
679 _Field(
680 group="signatures",
681 description="""Whether to put the whole signature in a code block below the heading.
683 If Black or Ruff are installed, the signature is also formatted using them.
684 """,
685 ),
686 ] = False
688 show_attribute_values: Annotated[
689 bool,
690 _Field(
691 group="signatures",
692 description="Show initial values of attributes in classes.",
693 ),
694 ] = True
696 show_bases: Annotated[
697 bool,
698 _Field(
699 group="general",
700 description="Show the base classes of a class.",
701 ),
702 ] = True
704 show_category_heading: Annotated[
705 bool,
706 _Field(
707 group="headings",
708 description="When grouped by categories, show a heading for each category.",
709 ),
710 ] = False
712 show_docstring_attributes: Annotated[
713 bool,
714 _Field(
715 group="docstrings",
716 description="Whether to display the 'Attributes' section in the object's docstring.",
717 ),
718 ] = True
720 show_docstring_classes: Annotated[
721 bool,
722 _Field(
723 group="docstrings",
724 description="Whether to display the 'Classes' section in the object's docstring.",
725 ),
726 ] = True
728 show_docstring_description: Annotated[
729 bool,
730 _Field(
731 group="docstrings",
732 description="Whether to display the textual block (including admonitions) in the object's docstring.",
733 ),
734 ] = True
736 show_docstring_examples: Annotated[
737 bool,
738 _Field(
739 group="docstrings",
740 description="Whether to display the 'Examples' section in the object's docstring.",
741 ),
742 ] = True
744 show_docstring_functions: Annotated[
745 bool,
746 _Field(
747 group="docstrings",
748 description="Whether to display the 'Functions' or 'Methods' sections in the object's docstring.",
749 ),
750 ] = True
752 show_docstring_modules: Annotated[
753 bool,
754 _Field(
755 group="docstrings",
756 description="Whether to display the 'Modules' section in the object's docstring.",
757 ),
758 ] = True
760 show_docstring_other_parameters: Annotated[
761 bool,
762 _Field(
763 group="docstrings",
764 description="Whether to display the 'Other Parameters' section in the object's docstring.",
765 ),
766 ] = True
768 show_docstring_parameters: Annotated[
769 bool,
770 _Field(
771 group="docstrings",
772 description="Whether to display the 'Parameters' section in the object's docstring.",
773 ),
774 ] = True
776 show_docstring_raises: Annotated[
777 bool,
778 _Field(
779 group="docstrings",
780 description="Whether to display the 'Raises' section in the object's docstring.",
781 ),
782 ] = True
784 show_docstring_receives: Annotated[
785 bool,
786 _Field(
787 group="docstrings",
788 description="Whether to display the 'Receives' section in the object's docstring.",
789 ),
790 ] = True
792 show_docstring_returns: Annotated[
793 bool,
794 _Field(
795 group="docstrings",
796 description="Whether to display the 'Returns' section in the object's docstring.",
797 ),
798 ] = True
800 show_docstring_warns: Annotated[
801 bool,
802 _Field(
803 group="docstrings",
804 description="Whether to display the 'Warns' section in the object's docstring.",
805 ),
806 ] = True
808 show_docstring_yields: Annotated[
809 bool,
810 _Field(
811 group="docstrings",
812 description="Whether to display the 'Yields' section in the object's docstring.",
813 ),
814 ] = True
816 show_if_no_docstring: Annotated[
817 bool,
818 _Field(
819 group="docstrings",
820 description="Show the object heading even if it has no docstring or children with docstrings.",
821 ),
822 ] = False
824 show_inheritance_diagram: Annotated[
825 bool,
826 _Field(
827 group="docstrings",
828 description="Show the inheritance diagram of a class using Mermaid.",
829 ),
830 ] = False
832 show_labels: Annotated[
833 bool,
834 _Field(
835 group="docstrings",
836 description="Whether to show labels of the members.",
837 ),
838 ] = True
840 show_object_full_path: Annotated[
841 bool,
842 _Field(
843 group="docstrings",
844 description="Show the full Python path of every object.",
845 ),
846 ] = False
848 show_root_full_path: Annotated[
849 bool,
850 _Field(
851 group="docstrings",
852 description="Show the full Python path for the root object heading.",
853 ),
854 ] = True
856 show_root_heading: Annotated[
857 bool,
858 _Field(
859 group="headings",
860 description="""Show the heading of the object at the root of the documentation tree.
862 The root object is the object referenced by the identifier after `:::`.
863 """,
864 ),
865 ] = False
867 show_root_members_full_path: Annotated[
868 bool,
869 _Field(
870 group="headings",
871 description="Show the full Python path of the root members.",
872 ),
873 ] = False
875 show_root_toc_entry: Annotated[
876 bool,
877 _Field(
878 group="headings",
879 description="If the root heading is not shown, at least add a ToC entry for it.",
880 ),
881 ] = True
883 show_signature_annotations: Annotated[
884 bool,
885 _Field(
886 group="signatures",
887 description="Show the type annotations in methods and functions signatures.",
888 ),
889 ] = False
891 show_signature: Annotated[
892 bool,
893 _Field(
894 group="signatures",
895 description="Show methods and functions signatures.",
896 ),
897 ] = True
899 show_source: Annotated[
900 bool,
901 _Field(
902 group="general",
903 description="Show the source code of this object.",
904 ),
905 ] = True
907 show_submodules: Annotated[
908 bool,
909 _Field(
910 group="members",
911 description="When rendering a module, show its submodules recursively.",
912 ),
913 ] = False
915 show_symbol_type_heading: Annotated[
916 bool,
917 _Field(
918 group="headings",
919 description="Show the symbol type in headings (e.g. mod, class, meth, func and attr).",
920 ),
921 ] = False
923 show_symbol_type_toc: Annotated[
924 bool,
925 _Field(
926 group="headings",
927 description="Show the symbol type in the Table of Contents (e.g. mod, class, methd, func and attr).",
928 ),
929 ] = False
931 skip_local_inventory: Annotated[
932 bool,
933 _Field(
934 group="general",
935 description="Whether to prevent objects from being registered in the local objects inventory.",
936 ),
937 ] = False
939 signature_crossrefs: Annotated[
940 bool,
941 _Field(
942 group="signatures",
943 description="Whether to render cross-references for type annotations in signatures.",
944 ),
945 ] = False
947 summary: Annotated[
948 bool | SummaryOption,
949 _Field(
950 group="members",
951 description="Whether to render summaries of modules, classes, functions (methods) and attributes.",
952 ),
953 ] = field(default_factory=SummaryOption)
955 toc_label: Annotated[
956 str,
957 _Field(
958 group="headings",
959 description="A custom string to override the autogenerated toc label of the root object.",
960 ),
961 ] = ""
963 unwrap_annotated: Annotated[
964 bool,
965 _Field(
966 group="signatures",
967 description="Whether to unwrap `Annotated` types to show only the type without the annotations.",
968 ),
969 ] = False
971 extra: Annotated[
972 dict[str, Any],
973 _Field(
974 group="general",
975 description="Extra options.",
976 ),
977 ] = field(default_factory=dict)
979 @classmethod
980 def _extract_extra(cls, data: dict[str, Any]) -> tuple[dict[str, Any], dict[str, Any]]:
981 field_names = {field.name for field in fields(cls)}
982 copy = data.copy()
983 return {name: copy.pop(name) for name in data if name not in field_names}, copy
985 @classmethod
986 def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
987 """Coerce data."""
988 if "docstring_options" in data: 988 ↛ 989line 988 didn't jump to line 989 because the condition on line 988 was never true
989 docstring_style = data.get("docstring_style", "google")
990 docstring_options = data["docstring_options"]
991 if docstring_options is not None:
992 if docstring_style == "auto":
993 docstring_options = AutoStyleOptions.from_data(**docstring_options)
994 elif docstring_style == "google":
995 docstring_options = GoogleStyleOptions(**docstring_options)
996 elif docstring_style == "numpy":
997 docstring_options = NumpyStyleOptions(**docstring_options)
998 elif docstring_style == "sphinx":
999 docstring_options = SphinxStyleOptions(**docstring_options)
1000 data["docstring_options"] = docstring_options
1001 if "summary" in data:
1002 summary = data["summary"]
1003 if summary is True: 1003 ↛ 1004line 1003 didn't jump to line 1004 because the condition on line 1003 was never true
1004 summary = SummaryOption(attributes=True, functions=True, classes=True, modules=True)
1005 elif summary is False: 1005 ↛ 1006line 1005 didn't jump to line 1006 because the condition on line 1005 was never true
1006 summary = SummaryOption(attributes=False, functions=False, classes=False, modules=False)
1007 else:
1008 summary = SummaryOption(**summary)
1009 data["summary"] = summary
1010 return data
1012 @classmethod
1013 def from_data(cls, **data: Any) -> Self:
1014 """Create an instance from a dictionary."""
1015 return cls(**cls.coerce(**data))
1018# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
1019@dataclass(**_dataclass_options) # type: ignore[call-overload]
1020class PythonOptions(PythonInputOptions): # type: ignore[override,unused-ignore]
1021 """Final options passed as template context."""
1023 filters: list[tuple[re.Pattern, bool]] | Literal["public"] = field( # type: ignore[assignment]
1024 default_factory=lambda: [
1025 (re.compile(filtr.removeprefix("!")), filtr.startswith("!")) for filtr in _DEFAULT_FILTERS
1026 ],
1027 )
1028 """A list of filters, or `"public"`."""
1030 summary: SummaryOption = field(default_factory=SummaryOption)
1031 """Whether to render summaries of modules, classes, functions (methods) and attributes."""
1033 @classmethod
1034 def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
1035 """Create an instance from a dictionary."""
1036 if "filters" in data and not isinstance(data["filters"], str):
1037 # Filters are `None` or a sequence of strings (tests use tuples).
1038 data["filters"] = [
1039 (re.compile(filtr.removeprefix("!")), filtr.startswith("!")) for filtr in data["filters"] or ()
1040 ]
1041 return super().coerce(**data)
1044# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
1045@dataclass(**_dataclass_options) # type: ignore[call-overload]
1046class Inventory:
1047 """An inventory."""
1049 url: Annotated[
1050 str,
1051 _Field(
1052 parent="inventories",
1053 description="The URL of the inventory.",
1054 ),
1055 ]
1057 base_url: Annotated[
1058 str | None,
1059 _Field(
1060 parent="inventories",
1061 description="The base URL of the inventory.",
1062 ),
1063 ] = None
1065 domains: Annotated[
1066 list[str],
1067 _Field(
1068 parent="inventories",
1069 description="The domains to load from the inventory.",
1070 ),
1071 ] = field(default_factory=lambda: ["py"])
1073 @property
1074 def _config(self) -> dict[str, Any]:
1075 return {"base_url": self.base_url, "domains": self.domains}
1078# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
1079@dataclass(**_dataclass_options) # type: ignore[call-overload]
1080class PythonInputConfig:
1081 """Python handler configuration."""
1083 inventories: Annotated[
1084 list[str | Inventory],
1085 _Field(description="The inventories to load."),
1086 ] = field(default_factory=list)
1088 paths: Annotated[
1089 list[str],
1090 _Field(description="The paths in which to search for Python packages."),
1091 ] = field(default_factory=lambda: ["."])
1093 load_external_modules: Annotated[
1094 bool | None,
1095 _Field(description="Whether to always load external modules/packages."),
1096 ] = None
1098 options: Annotated[
1099 PythonInputOptions,
1100 _Field(description="Configuration options for collecting and rendering objects."),
1101 ] = field(default_factory=PythonInputOptions)
1103 locale: Annotated[
1104 str | None,
1105 _Field(
1106 description="Deprecated. Use mkdocstrings' own `locale` setting instead. The locale to use when translating template strings.",
1107 ),
1108 ] = None
1110 @classmethod
1111 def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
1112 """Coerce data."""
1113 return data
1115 @classmethod
1116 def from_data(cls, **data: Any) -> Self:
1117 """Create an instance from a dictionary."""
1118 return cls(**cls.coerce(**data))
1121# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
1122@dataclass(**_dataclass_options) # type: ignore[call-overload]
1123class PythonConfig(PythonInputConfig): # type: ignore[override,unused-ignore]
1124 """Python handler configuration."""
1126 inventories: Annotated[
1127 list[Inventory],
1128 _Field(description="The object inventories to load."),
1129 ] = field(default_factory=list) # type: ignore[assignment]
1131 options: Annotated[
1132 dict[str, Any],
1133 _Field(description="Configuration options for collecting and rendering objects."),
1134 ] = field(default_factory=dict) # type: ignore[assignment]
1136 @classmethod
1137 def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
1138 """Coerce data."""
1139 if "inventories" in data: 1139 ↛ 1140line 1139 didn't jump to line 1140 because the condition on line 1139 was never true
1140 data["inventories"] = [
1141 Inventory(url=inv) if isinstance(inv, str) else Inventory(**inv) for inv in data["inventories"]
1142 ]
1143 return data