list [str ] | None
:material-equal: `["!^_[^_]"]`{ title="default value" }**
+- **:octicons-package-24: Type list [str ] | Literal ["public"] | None
:material-equal: `["!^_[^_]"]`{ title="default value" }**
-A list of filters applied to filter objects based on their name.
+A list of filters, or `"public"`.
+
+**Filtering methods**
+
+[](){#option-filters-public}
+
+[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } —
+[:octicons-tag-24: Insiders 1.11.0](../../insiders/changelog.md#1.11.0)
+
+The `public` filtering method will include only public objects: those added to the `__all__` attribute of modules, or not starting with a single underscore. Special methods and attributes ("dunder" methods/attributes, starting and ending with two underscores), like `__init__`, `__call__`, `__mult__`, etc., are always considered public.
+
+**List of filters**
Filters are regular expressions. These regular expressions are evaluated by Python
and so must match the syntax supported by the [`re`][] module.
@@ -379,13 +397,13 @@ plugins:
python:
options:
filters:
- - "!^_"
+ - "!^_[^_]"
```
```md title="or in docs/some_page.md (local configuration)"
::: package.module
options:
- filters: []
+ filters: public
```
```python title="package/module.py"
diff --git a/docs/usage/customization.md b/docs/usage/customization.md
index 9e13da66..8239c2e9 100644
--- a/docs/usage/customization.md
+++ b/docs/usage/customization.md
@@ -283,7 +283,7 @@ for filepath in sorted(path for path in Path(basedir).rglob("*") if "_base" not
)
```
-See them [in the repository](https://github.com/mkdocstrings/python/tree/master/src/mkdocstrings_handlers/python/templates/).
+See them [in the repository](https://github.com/mkdocstrings/python/tree/main/src/mkdocstrings_handlers/python/templates/).
See the general *mkdocstrings* documentation to learn how to override them: https://mkdocstrings.github.io/theming/#templates.
Each one of these templates extends a base version in `theme/_base`. Example:
@@ -439,4 +439,4 @@ div.doc-contents:not(.first) {
padding-left: 25px;
border-left: .05rem solid rgba(200, 200, 200, 0.2);
}
-```
\ No newline at end of file
+```
diff --git a/docs/usage/index.md b/docs/usage/index.md
index 84110936..b2a00955 100644
--- a/docs/usage/index.md
+++ b/docs/usage/index.md
@@ -87,8 +87,8 @@ plugins:
- mkdocstrings:
handlers:
python:
- import:
- - https://docs.python-requests.org/en/master/objects.inv
+ inventories:
+ - https://docs.python.org/3/objects.inv
```
When loading an inventory, you enable automatic cross-references
diff --git a/duties.py b/duties.py
index 9e516ce5..18282747 100644
--- a/duties.py
+++ b/duties.py
@@ -3,11 +3,13 @@
from __future__ import annotations
import os
+import re
import sys
from contextlib import contextmanager
+from functools import wraps
from importlib.metadata import version as pkgversion
from pathlib import Path
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, Any, Callable
from duty import duty, tools
@@ -26,15 +28,30 @@
MULTIRUN = os.environ.get("MULTIRUN", "0") == "1"
-def pyprefix(title: str) -> str: # noqa: D103
+def pyprefix(title: str) -> str:
if MULTIRUN:
prefix = f"(python{sys.version_info.major}.{sys.version_info.minor})"
return f"{prefix:14}{title}"
return title
+def not_from_insiders(func: Callable) -> Callable:
+ @wraps(func)
+ def wrapper(ctx: Context, *args: Any, **kwargs: Any) -> None:
+ origin = ctx.run("git config --get remote.origin.url", silent=True)
+ if "pawamoy-insiders/griffe" in origin:
+ ctx.run(
+ lambda: False,
+ title="Not running this task from insiders repository (do that from public repo instead!)",
+ )
+ return
+ func(ctx, *args, **kwargs)
+
+ return wrapper
+
+
@contextmanager
-def material_insiders() -> Iterator[bool]: # noqa: D103
+def material_insiders() -> Iterator[bool]:
if "+insiders" in pkgversion("mkdocs-material"):
os.environ["MATERIAL_INSIDERS"] = "true"
try:
@@ -45,6 +62,12 @@ def material_insiders() -> Iterator[bool]: # noqa: D103
yield False
+def _get_changelog_version() -> str:
+ changelog_version_re = re.compile(r"^## \[(\d+\.\d+\.\d+)\].*$")
+ with Path(__file__).parent.joinpath("CHANGELOG.md").open("r", encoding="utf8") as file:
+ return next(filter(bool, map(changelog_version_re.match, file))).group(1) # type: ignore[union-attr]
+
+
@duty
def changelog(ctx: Context, bump: str = "") -> None:
"""Update the changelog in-place with latest commits.
@@ -53,6 +76,7 @@ def changelog(ctx: Context, bump: str = "") -> None:
bump: Bump option passed to git-changelog.
"""
ctx.run(tools.git_changelog(bump=bump or None), title="Updating changelog")
+ ctx.run(tools.yore.check(bump=bump or _get_changelog_version()), title="Checking legacy code")
@duty(pre=["check-quality", "check-types", "check-docs", "check-api"])
@@ -85,6 +109,7 @@ def check_docs(ctx: Context) -> None:
def check_types(ctx: Context) -> None:
"""Check that the code is correctly typed."""
os.environ["MYPYPATH"] = "src"
+ os.environ["FORCE_COLOR"] = "1"
ctx.run(
tools.mypy(*PY_SRC_LIST, config_file="config/mypy.ini"),
title=pyprefix("Type-checking"),
@@ -176,6 +201,7 @@ def build(ctx: Context) -> None:
@duty
+@not_from_insiders
def publish(ctx: Context) -> None:
"""Publish source and wheel distributions to PyPI."""
if not Path("dist").exists():
@@ -189,18 +215,13 @@ def publish(ctx: Context) -> None:
@duty(post=["build", "publish", "docs-deploy"])
+@not_from_insiders
def release(ctx: Context, version: str = "") -> None:
"""Release a new Python package.
Parameters:
version: The new version number to use.
"""
- origin = ctx.run("git config --get remote.origin.url", silent=True)
- if "pawamoy-insiders/mkdocstrings-python" in origin:
- ctx.run(
- lambda: False,
- title="Not releasing from insiders repository (do that from public repo instead!)",
- )
if not (version := (version or input("> Version to release: ")).strip()):
ctx.run("false", title="A version must be provided")
ctx.run("git add pyproject.toml CHANGELOG.md", title="Staging files", pty=PTY)
diff --git a/mkdocs.yml b/mkdocs.yml
index ae518a4c..0199ea9a 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -37,9 +37,7 @@ nav:
- Advanced:
- Customization: usage/customization.md
- Extensions: usage/extensions.md
-# defer to gen-files + literate-nav
-- API reference:
- - mkdocstrings-python: reference/
+- API reference: reference/api.md
- Development:
- Contributing: contributing.md
- Code of Conduct: code_of_conduct.md
@@ -63,7 +61,8 @@ theme:
- content.code.copy
- content.tooltips
- navigation.footer
- - navigation.indexes
+ - navigation.instant.preview
+ - navigation.path
- navigation.sections
- navigation.tabs
- navigation.tabs.sticky
@@ -140,20 +139,16 @@ markdown_extensions:
permalink: "¤"
plugins:
-- autorefs
- search
+- autorefs
- markdown-exec
-- gen-files:
- scripts:
- - scripts/gen_ref_nav.py
-- literate-nav:
- nav_file: SUMMARY.md
+- section-index
# - coverage
- mkdocstrings:
handlers:
python:
paths: [src, docs/snippets]
- import:
+ inventories:
- https://docs.python.org/3/objects.inv
- https://mkdocstrings.github.io/objects.inv
- https://mkdocstrings.github.io/autorefs/objects.inv
@@ -164,11 +159,11 @@ plugins:
docstring_options:
ignore_init_summary: true
docstring_section_style: list
- extensions:
- - scripts/griffe_extensions.py
- filters: ["!^_"]
+ extensions: [scripts/griffe_extensions.py]
+ filters: public
heading_level: 1
inherited_members: true
+ line_length: 88
merge_init_into_class: true
parameter_headings: true
preload_modules: [mkdocstrings]
@@ -186,12 +181,27 @@ plugins:
signature_crossrefs: true
summary: true
unwrap_annotated: true
+- llmstxt:
+ full_output: llms-full.txt
+ sections:
+ Usage:
+ - index.md
+ API:
+ - reference/api.md
- git-revision-date-localized:
enabled: !ENV [DEPLOY, false]
enable_creation_date: true
type: timeago
- minify:
minify_html: !ENV [DEPLOY, false]
+- redirects:
+ redirect_maps:
+ reference/mkdocstrings_handlers/python/index.md: reference/api.md
+ reference/mkdocstrings_handlers/python/config.md: reference/api.md#mkdocstrings_handlers.python.config
+ reference/mkdocstrings_handlers/python/debug.md: reference/api.md#mkdocstrings_handlers.python.debug
+ reference/mkdocstrings_handlers/python/handler.md: reference/api.md#mkdocstrings_handlers.python.handler
+ reference/mkdocstrings_handlers/python/rendering.md: reference/api.md#mkdocstrings_handlers.python.rendering
+
- group:
enabled: !ENV [MATERIAL_INSIDERS, false]
plugins:
diff --git a/pyproject.toml b/pyproject.toml
index cb429367..d93cb20c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -6,7 +6,8 @@ build-backend = "pdm.backend"
name = "mkdocstrings-python"
description = "A Python handler for mkdocstrings."
authors = [{name = "Timothée Mazzucotelli", email = "dev@pawamoy.fr"}]
-license = {text = "ISC"}
+license = "ISC"
+license-files = ["LICENSE"]
readme = "README.md"
requires-python = ">=3.9"
keywords = []
@@ -32,7 +33,7 @@ classifiers = [
dependencies = [
"mkdocstrings>=0.28.3",
"mkdocs-autorefs>=1.4",
- "griffe>=0.49",
+ "griffe>=1.6.2",
"typing-extensions>=4.0; python_version < '3.11'",
]
@@ -56,7 +57,7 @@ includes = ["src/mkdocstrings_handlers"]
editable-backend = "editables"
# Include as much as possible in the source distribution, to help redistributors.
-excludes = ["**/.pytest_cache"]
+excludes = ["**/.pytest_cache", "**/.mypy_cache"]
source-includes = [
"config",
"docs",
@@ -78,14 +79,15 @@ data = [
]
[dependency-groups]
-dev = [
- # maintenance
+maintain = [
"build>=1.2",
"git-changelog>=2.5",
"twine>=5.1",
-
- # ci
- "duty>=1.4",
+ "yore>=0.3.3",
+]
+ci = [
+ "black>=25.1",
+ "duty>=1.6",
"ruff>=0.4",
"pytest>=8.2",
"pytest-cov>=5.0",
@@ -96,19 +98,20 @@ dev = [
"mypy>=1.10",
"types-markdown>=3.6",
"types-pyyaml>=6.0",
-
- # docs
- "black>=24.4",
+]
+ docs = [
"markdown-callouts>=0.4",
"markdown-exec>=1.8",
"mkdocs>=1.6",
"mkdocs-coverage>=1.0",
- "mkdocs-gen-files>=0.5",
"mkdocs-git-revision-date-localized-plugin>=1.2",
- "mkdocs-literate-nav>=0.6",
+ "mkdocs-llmstxt>=0.2",
"mkdocs-material>=9.5",
- "pydantic>=2.10",
"mkdocs-minify-plugin>=0.8",
+ "mkdocs-redirects>=1.2",
+ "mkdocs-section-index>=0.3",
+ "mkdocstrings>=0.29",
+ "pydantic>=2.10",
# YORE: EOL 3.10: Remove line.
"tomli>=2.0; python_version < '3.11'",
]
@@ -116,3 +119,6 @@ dev = [
[tool.inline-snapshot]
storage-dir = "tests/snapshots"
format-command = "ruff format --config config/ruff.toml --stdin-filename {filename}"
+
+[tool.uv]
+default-groups = ["maintain", "ci", "docs"]
diff --git a/scripts/gen_credits.py b/scripts/gen_credits.py
index 85240535..6a81e239 100644
--- a/scripts/gen_credits.py
+++ b/scripts/gen_credits.py
@@ -1,4 +1,4 @@
-"""Script to generate the project's credits."""
+# Script to generate the project's credits.
from __future__ import annotations
@@ -27,7 +27,7 @@
pyproject = tomllib.load(pyproject_file)
project = pyproject["project"]
project_name = project["name"]
-devdeps = [dep for dep in pyproject["dependency-groups"]["dev"] if not dep.startswith("-e")]
+devdeps = [dep for group in pyproject["dependency-groups"].values() for dep in group if not dep.startswith("-e")]
PackageMetadata = dict[str, Union[str, Iterable[str]]]
Metadata = dict[str, PackageMetadata]
diff --git a/scripts/gen_ref_nav.py b/scripts/gen_ref_nav.py
deleted file mode 100644
index 6939e864..00000000
--- a/scripts/gen_ref_nav.py
+++ /dev/null
@@ -1,37 +0,0 @@
-"""Generate the code reference pages and navigation."""
-
-from pathlib import Path
-
-import mkdocs_gen_files
-
-nav = mkdocs_gen_files.Nav()
-mod_symbol = '
'
-
-root = Path(__file__).parent.parent
-src = root / "src"
-
-for path in sorted(src.rglob("*.py")):
- module_path = path.relative_to(src).with_suffix("")
- doc_path = path.relative_to(src).with_suffix(".md")
- full_doc_path = Path("reference", doc_path)
-
- parts = tuple(module_path.parts)
-
- if parts[-1] == "__init__":
- parts = parts[:-1]
- doc_path = doc_path.with_name("index.md")
- full_doc_path = full_doc_path.with_name("index.md")
- elif parts[-1].startswith("_"):
- continue
-
- nav_parts = [f"{mod_symbol} {part}" for part in parts]
- nav[tuple(nav_parts)] = doc_path.as_posix()
-
- with mkdocs_gen_files.open(full_doc_path, "w") as fd:
- ident = ".".join(parts)
- fd.write(f"---\ntitle: {ident}\n---\n\n::: {ident}")
-
- mkdocs_gen_files.set_edit_path(full_doc_path, ".." / path.relative_to(root))
-
-with mkdocs_gen_files.open("reference/SUMMARY.md", "w") as nav_file:
- nav_file.writelines(nav.build_literate_nav())
diff --git a/scripts/get_version.py b/scripts/get_version.py
index f4a30a8c..6734e5b6 100644
--- a/scripts/get_version.py
+++ b/scripts/get_version.py
@@ -1,4 +1,4 @@
-"""Get current project version from Git tags or changelog."""
+# Get current project version from Git tags or changelog.
import re
from contextlib import suppress
@@ -13,7 +13,6 @@
def get_version() -> str:
- """Get current project version from Git tags or changelog."""
scm_version = get_version_from_scm(_root) or _default_scm_version
if scm_version.version <= Version("0.1"): # Missing Git tags?
with suppress(OSError, StopIteration): # noqa: SIM117
diff --git a/scripts/griffe_extensions.py b/scripts/griffe_extensions.py
index 7d283054..eb50f5f2 100644
--- a/scripts/griffe_extensions.py
+++ b/scripts/griffe_extensions.py
@@ -1,4 +1,4 @@
-"""Custom extensions for Griffe."""
+# Custom extensions for Griffe.
from __future__ import annotations
@@ -7,7 +7,7 @@
import griffe
-logger = griffe.get_logger("griffe_extensions")
+_logger = griffe.get_logger("griffe_extensions")
class CustomFields(griffe.Extension):
@@ -28,14 +28,14 @@ def on_attribute_instance(
except AttributeError:
return
- if field.canonical_path == "mkdocstrings_handlers.python.config.Field":
+ if field.canonical_path == "mkdocstrings_handlers.python._internal.config._Field":
description = next(
attr.value
for attr in field.arguments
if isinstance(attr, griffe.ExprKeyword) and attr.name == "description"
)
if not isinstance(description, str):
- logger.warning(f"Field description of {attr.path} is not a static string")
+ _logger.warning(f"Field description of {attr.path} is not a static string")
description = str(description)
attr.docstring = griffe.Docstring(
diff --git a/scripts/insiders.py b/scripts/insiders.py
index a7da99bc..4cd438d4 100644
--- a/scripts/insiders.py
+++ b/scripts/insiders.py
@@ -1,4 +1,4 @@
-"""Functions related to Insiders funding goals."""
+# Functions related to Insiders funding goals.
from __future__ import annotations
@@ -23,7 +23,7 @@
logger = logging.getLogger(f"mkdocs.logs.{__name__}")
-def human_readable_amount(amount: int) -> str: # noqa: D103
+def human_readable_amount(amount: int) -> str:
str_amount = str(amount)
if len(str_amount) >= 4: # noqa: PLR2004
return f"{str_amount[: len(str_amount) - 3]},{str_amount[-3:]}"
@@ -32,16 +32,12 @@ def human_readable_amount(amount: int) -> str: # noqa: D103
@dataclass
class Project:
- """Class representing an Insiders project."""
-
name: str
url: str
@dataclass
class Feature:
- """Class representing an Insiders feature."""
-
name: str
ref: str | None
since: date | None
@@ -68,8 +64,6 @@ def render(self, rel_base: str = "..", *, badge: bool = False) -> None: # noqa:
@dataclass
class Goal:
- """Class representing an Insiders goal."""
-
name: str
amount: int
features: list[Feature]
@@ -94,16 +88,6 @@ def render(self, rel_base: str = "..") -> None: # noqa: D102
def load_goals(data: str, funding: int = 0, project: Project | None = None) -> dict[int, Goal]:
- """Load goals from JSON data.
-
- Parameters:
- data: The JSON data.
- funding: The current total funding, per month.
- origin: The origin of the data (URL).
-
- Returns:
- A dictionaries of goals, keys being their target monthly amount.
- """
goals_data = yaml.safe_load(data)["goals"]
return {
amount: Goal(
@@ -151,15 +135,6 @@ def _load_goals(source: str | tuple[str, str, str], funding: int = 0) -> dict[in
def funding_goals(source: str | list[str | tuple[str, str, str]], funding: int = 0) -> dict[int, Goal]:
- """Load funding goals from a given data source.
-
- Parameters:
- source: The data source (local file path or URL).
- funding: The current total funding, per month.
-
- Returns:
- A dictionaries of goals, keys being their target monthly amount.
- """
if isinstance(source, str):
return _load_goals_from_disk(source, funding)
goals = {}
@@ -174,18 +149,10 @@ def funding_goals(source: str | list[str | tuple[str, str, str]], funding: int =
def feature_list(goals: Iterable[Goal]) -> list[Feature]:
- """Extract feature list from funding goals.
-
- Parameters:
- goals: A list of funding goals.
-
- Returns:
- A list of features.
- """
return list(chain.from_iterable(goal.features for goal in goals))
-def load_json(url: str) -> str | list | dict: # noqa: D103
+def load_json(url: str) -> str | list | dict:
with urlopen(url) as response: # noqa: S310
return json.loads(response.read().decode())
@@ -201,6 +168,6 @@ def load_json(url: str) -> str | list | dict: # noqa: D103
ongoing_goals = [goal for goal in goals.values() if not goal.complete]
unreleased_features = sorted(
(ft for ft in feature_list(ongoing_goals) if ft.since),
- key=lambda ft: cast(date, ft.since),
+ key=lambda ft: cast("date", ft.since),
reverse=True,
)
diff --git a/scripts/make.py b/scripts/make.py
index a3b9e751..5a7fb4c2 100755
--- a/scripts/make.py
+++ b/scripts/make.py
@@ -1,6 +1,4 @@
#!/usr/bin/env python3
-"""Management commands."""
-
from __future__ import annotations
import os
diff --git a/scripts/mkdocs_hooks.py b/scripts/mkdocs_hooks.py
index 805055e0..739f93b3 100644
--- a/scripts/mkdocs_hooks.py
+++ b/scripts/mkdocs_hooks.py
@@ -1,4 +1,4 @@
-"""Generate a JSON schema of the Python handler configuration."""
+# Generate a JSON schema of the Python handler configuration.
import json
from dataclasses import dataclass, fields
@@ -8,7 +8,7 @@
from mkdocs.config.defaults import MkDocsConfig
from mkdocs.plugins import get_plugin_logger
-from mkdocstrings_handlers.python.config import PythonInputConfig, PythonInputOptions
+from mkdocstrings_handlers.python import PythonInputConfig, PythonInputOptions
# TODO: Update when Pydantic supports Python 3.14 (sources and duties as well).
try:
@@ -17,13 +17,13 @@
TypeAdapter = None # type: ignore[assignment,misc]
-logger = get_plugin_logger(__name__)
+_logger = get_plugin_logger(__name__)
def on_post_build(config: MkDocsConfig, **kwargs: Any) -> None: # noqa: ARG001
"""Write `schema.json` to the site directory."""
if TypeAdapter is None:
- logger.info("Pydantic is not installed, skipping JSON schema generation")
+ _logger.info("Pydantic is not installed, skipping JSON schema generation")
return
@dataclass
@@ -35,12 +35,12 @@ class PythonHandlerSchema:
schema["$schema"] = "https://json-schema.org/draft-07/schema"
with open(join(config.site_dir, "schema.json"), "w") as file:
json.dump(schema, file, indent=2)
- logger.debug("Generated JSON schema")
+ _logger.debug("Generated JSON schema")
autorefs = config["plugins"]["autorefs"]
for field in fields(PythonInputConfig):
if f"setting-{field.name}" not in autorefs._primary_url_map:
- logger.warning(f"Handler setting `{field.name}` is not documented")
+ _logger.warning(f"Handler setting `{field.name}` is not documented")
for field in fields(PythonInputOptions):
if f"option-{field.name}" not in autorefs._primary_url_map:
- logger.warning(f"Configuration option `{field.name}` is not documented")
+ _logger.warning(f"Configuration option `{field.name}` is not documented")
diff --git a/src/mkdocstrings_handlers/python/__init__.py b/src/mkdocstrings_handlers/python/__init__.py
index 0432a90d..faa9b9f4 100644
--- a/src/mkdocstrings_handlers/python/__init__.py
+++ b/src/mkdocstrings_handlers/python/__init__.py
@@ -1,5 +1,70 @@
"""Python handler for mkdocstrings."""
-from mkdocstrings_handlers.python.handler import get_handler
+from mkdocstrings_handlers.python._internal.config import (
+ AutoStyleOptions,
+ GoogleStyleOptions,
+ Inventory,
+ NumpyStyleOptions,
+ PerStyleOptions,
+ PythonConfig,
+ PythonInputConfig,
+ PythonInputOptions,
+ PythonOptions,
+ SphinxStyleOptions,
+ SummaryOption,
+)
+from mkdocstrings_handlers.python._internal.handler import PythonHandler, get_handler
+from mkdocstrings_handlers.python._internal.rendering import (
+ AutorefsHook,
+ Order,
+ Tree,
+ do_as_attributes_section,
+ do_as_classes_section,
+ do_as_functions_section,
+ do_as_modules_section,
+ do_backlink_tree,
+ do_crossref,
+ do_filter_objects,
+ do_format_attribute,
+ do_format_code,
+ do_format_signature,
+ do_get_template,
+ do_multi_crossref,
+ do_order_members,
+ do_split_path,
+ do_stash_crossref,
+)
-__all__ = ["get_handler"]
+__all__ = [
+ "AutoStyleOptions",
+ "AutorefsHook",
+ "GoogleStyleOptions",
+ "Inventory",
+ "NumpyStyleOptions",
+ "Order",
+ "PerStyleOptions",
+ "PythonConfig",
+ "PythonHandler",
+ "PythonInputConfig",
+ "PythonInputOptions",
+ "PythonOptions",
+ "SphinxStyleOptions",
+ "SummaryOption",
+ "Tree",
+ "do_as_attributes_section",
+ "do_as_classes_section",
+ "do_as_functions_section",
+ "do_as_modules_section",
+ "do_backlink_tree",
+ "do_crossref",
+ "do_filter_objects",
+ "do_format_attribute",
+ "do_format_code",
+ "do_format_signature",
+ "do_get_template",
+ "do_multi_crossref",
+ "do_order_members",
+ "do_split_path",
+ "do_stash_crossref",
+ "get_handler",
+]
diff --git a/src/mkdocstrings_handlers/python/_internal/__init__.py b/src/mkdocstrings_handlers/python/_internal/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/src/mkdocstrings_handlers/python/_internal/config.py b/src/mkdocstrings_handlers/python/_internal/config.py
new file mode 100644
index 00000000..210f8fe2
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/_internal/config.py
@@ -0,0 +1,1058 @@
+# Configuration and options dataclasses.
+
+from __future__ import annotations
+
+import re
+import sys
+from dataclasses import field, fields
+from typing import TYPE_CHECKING, Annotated, Any, Literal
+
+from mkdocstrings import get_logger
+
+from mkdocstrings_handlers.python._internal.rendering import Order # noqa: TC001
+
+# YORE: EOL 3.10: Replace block with line 2.
+if sys.version_info >= (3, 11):
+ from typing import Self
+else:
+ from typing_extensions import Self
+
+
+_logger = get_logger(__name__)
+
+_DEFAULT_FILTERS = ["!^_[^_]"]
+
+try:
+ # When Pydantic is available, use it to validate options (done automatically).
+ # Users can therefore opt into validation by installing Pydantic in development/CI.
+ # When building the docs to deploy them, Pydantic is not required anymore.
+
+ # When building our own docs, Pydantic is always installed (see `docs` group in `pyproject.toml`)
+ # to allow automatic generation of a JSON Schema. The JSON Schema is then referenced by mkdocstrings,
+ # which is itself referenced by mkdocs-material's schema system. For example in VSCode:
+ #
+ # "yaml.schemas": {
+ # "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml"
+ # }
+ import pydantic
+
+ if getattr(pydantic, "__version__", "1.").startswith("1."):
+ raise ImportError # noqa: TRY301
+
+ # YORE: EOL 3.9: Remove block.
+ if sys.version_info < (3, 10):
+ try:
+ import eval_type_backport # noqa: F401
+ except ImportError:
+ _logger.debug(
+ "Pydantic needs the `eval-type-backport` package to be installed "
+ "for modern type syntax to work on Python 3.9. "
+ "Deactivating Pydantic validation for Python handler options.",
+ )
+ raise
+
+ from inspect import cleandoc
+
+ from pydantic import Field as BaseField
+ from pydantic.dataclasses import dataclass
+
+ _base_url = "https://mkdocstrings.github.io/python/usage"
+
+ def _Field( # noqa: N802
+ *args: Any,
+ description: str,
+ group: Literal["general", "headings", "members", "docstrings", "signatures"] | None = None,
+ parent: str | None = None,
+ **kwargs: Any,
+ ) -> None:
+ def _add_markdown_description(schema: dict[str, Any]) -> None:
+ url = f"{_base_url}/{f'configuration/{group}/' if group else ''}#{parent or schema['title']}"
+ schema["markdownDescription"] = f"[DOCUMENTATION]({url})\n\n{schema['description']}"
+
+ return BaseField(
+ *args,
+ description=cleandoc(description),
+ field_title_generator=lambda name, _: name,
+ json_schema_extra=_add_markdown_description,
+ **kwargs,
+ )
+except ImportError:
+ from dataclasses import dataclass # type: ignore[no-redef]
+
+ def _Field(*args: Any, **kwargs: Any) -> None: # type: ignore[misc] # noqa: N802
+ pass
+
+
+if TYPE_CHECKING:
+ from collections.abc import MutableMapping
+
+
+# YORE: EOL 3.9: Remove block.
+_dataclass_options = {"frozen": True}
+if sys.version_info >= (3, 10):
+ _dataclass_options["kw_only"] = True
+
+
+# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
+@dataclass(**_dataclass_options) # type: ignore[call-overload]
+class GoogleStyleOptions:
+ """Google style docstring options."""
+
+ ignore_init_summary: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Whether to ignore the summary in `__init__` methods' docstrings.",
+ ),
+ ] = False
+
+ returns_multiple_items: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="""Whether to parse multiple items in `Yields` and `Returns` sections.
+
+ When true, each item's continuation lines must be indented.
+ When false (single item), no further indentation is required.
+ """,
+ ),
+ ] = True
+
+ returns_named_value: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="""Whether to parse `Yields` and `Returns` section items as name and description, rather than type and description.
+
+ When true, type must be wrapped in parentheses: `(int): Description.`. Names are optional: `name (int): Description.`.
+ When false, parentheses are optional but the items cannot be named: `int: Description`.
+ """,
+ ),
+ ] = True
+
+ returns_type_in_property_summary: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Whether to parse the return type of properties at the beginning of their summary: `str: Summary of the property`.",
+ ),
+ ] = False
+
+ receives_multiple_items: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="""Whether to parse multiple items in `Receives` sections.
+
+ When true, each item's continuation lines must be indented.
+ When false (single item), no further indentation is required.
+ """,
+ ),
+ ] = True
+
+ receives_named_value: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="""Whether to parse `Receives` section items as name and description, rather than type and description.
+
+ When true, type must be wrapped in parentheses: `(int): Description.`. Names are optional: `name (int): Description.`.
+ When false, parentheses are optional but the items cannot be named: `int: Description`.
+ """,
+ ),
+ ] = True
+
+ trim_doctest_flags: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Whether to remove doctest flags from Python example blocks.",
+ ),
+ ] = True
+
+ warn_unknown_params: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Warn about documented parameters not appearing in the signature.",
+ ),
+ ] = True
+
+
+# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
+@dataclass(**_dataclass_options) # type: ignore[call-overload]
+class NumpyStyleOptions:
+ """Numpy style docstring options."""
+
+ ignore_init_summary: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Whether to ignore the summary in `__init__` methods' docstrings.",
+ ),
+ ] = False
+
+ trim_doctest_flags: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Whether to remove doctest flags from Python example blocks.",
+ ),
+ ] = True
+
+ warn_unknown_params: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Warn about documented parameters not appearing in the signature.",
+ ),
+ ] = True
+
+
+# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
+@dataclass(**_dataclass_options) # type: ignore[call-overload]
+class SphinxStyleOptions:
+ """Sphinx style docstring options."""
+
+
+# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
+@dataclass(**_dataclass_options) # type: ignore[call-overload]
+class PerStyleOptions:
+ """Per style options."""
+
+ google: Annotated[
+ GoogleStyleOptions,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Google-style options.",
+ ),
+ ] = field(default_factory=GoogleStyleOptions)
+
+ numpy: Annotated[
+ NumpyStyleOptions,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Numpydoc-style options.",
+ ),
+ ] = field(default_factory=NumpyStyleOptions)
+
+ sphinx: Annotated[
+ SphinxStyleOptions,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Sphinx-style options.",
+ ),
+ ] = field(default_factory=SphinxStyleOptions)
+
+ @classmethod
+ def from_data(cls, **data: Any) -> Self:
+ """Create an instance from a dictionary."""
+ if "google" in data:
+ data["google"] = GoogleStyleOptions(**data["google"])
+ if "numpy" in data:
+ data["numpy"] = NumpyStyleOptions(**data["numpy"])
+ if "sphinx" in data:
+ data["sphinx"] = SphinxStyleOptions(**data["sphinx"])
+ return cls(**data)
+
+
+# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
+@dataclass(**_dataclass_options) # type: ignore[call-overload]
+class AutoStyleOptions:
+ """Auto style docstring options."""
+
+ method: Annotated[
+ Literal["heuristics", "max_sections"],
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="The method to use to determine the docstring style.",
+ ),
+ ] = "heuristics"
+
+ style_order: Annotated[
+ list[str],
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="The order of the docstring styles to try.",
+ ),
+ ] = field(default_factory=lambda: ["sphinx", "google", "numpy"])
+
+ default: Annotated[
+ str | None,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="The default docstring style to use if no other style is detected.",
+ ),
+ ] = None
+
+ per_style_options: Annotated[
+ PerStyleOptions,
+ _Field(
+ group="docstrings",
+ parent="docstring_options",
+ description="Per-style options.",
+ ),
+ ] = field(default_factory=PerStyleOptions)
+
+ @classmethod
+ def from_data(cls, **data: Any) -> Self:
+ """Create an instance from a dictionary."""
+ if "per_style_options" in data:
+ data["per_style_options"] = PerStyleOptions.from_data(**data["per_style_options"])
+ return cls(**data)
+
+
+# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
+@dataclass(**_dataclass_options) # type: ignore[call-overload]
+class SummaryOption:
+ """Summary option."""
+
+ attributes: Annotated[
+ bool,
+ _Field(
+ group="members",
+ parent="summary",
+ description="Whether to render summaries of attributes.",
+ ),
+ ] = False
+
+ functions: Annotated[
+ bool,
+ _Field(
+ group="members",
+ parent="summary",
+ description="Whether to render summaries of functions (methods).",
+ ),
+ ] = False
+
+ classes: Annotated[
+ bool,
+ _Field(
+ group="members",
+ parent="summary",
+ description="Whether to render summaries of classes.",
+ ),
+ ] = False
+
+ modules: Annotated[
+ bool,
+ _Field(
+ group="members",
+ parent="summary",
+ description="Whether to render summaries of modules.",
+ ),
+ ] = False
+
+
+# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
+@dataclass(**_dataclass_options) # type: ignore[call-overload]
+class PythonInputOptions:
+ """Accepted input options."""
+
+ allow_inspection: Annotated[
+ bool,
+ _Field(
+ group="general",
+ description="Whether to allow inspecting modules when visiting them is not possible.",
+ ),
+ ] = True
+
+ force_inspection: Annotated[
+ bool,
+ _Field(
+ group="general",
+ description="Whether to force using dynamic analysis when loading data.",
+ ),
+ ] = False
+
+ annotations_path: Annotated[
+ Literal["brief", "source", "full"],
+ _Field(
+ group="signatures",
+ description="The verbosity for annotations path: `brief` (recommended), `source` (as written in the source), or `full`.",
+ ),
+ ] = "brief"
+
+ backlinks: Annotated[
+ Literal["flat", "tree", False],
+ _Field(
+ group="general",
+ description="Whether to render backlinks, and how.",
+ ),
+ ] = False
+
+ docstring_options: Annotated[
+ GoogleStyleOptions | NumpyStyleOptions | SphinxStyleOptions | AutoStyleOptions | None,
+ _Field(
+ group="docstrings",
+ description="""The options for the docstring parser.
+
+ See [docstring parsers](https://mkdocstrings.github.io/griffe/reference/docstrings/) and their options in Griffe docs.
+ """,
+ ),
+ ] = None
+
+ docstring_section_style: Annotated[
+ Literal["table", "list", "spacy"],
+ _Field(
+ group="docstrings",
+ description="The style used to render docstring sections.",
+ ),
+ ] = "table"
+
+ docstring_style: Annotated[
+ Literal["auto", "google", "numpy", "sphinx"] | None,
+ _Field(
+ group="docstrings",
+ description="The docstring style to use: `auto`, `google`, `numpy`, `sphinx`, or `None`.",
+ ),
+ ] = "google"
+
+ extensions: Annotated[
+ list[str | dict[str, Any]],
+ _Field(
+ group="general",
+ description="A list of Griffe extensions to load.",
+ ),
+ ] = field(default_factory=list)
+
+ filters: Annotated[
+ list[str] | Literal["public"],
+ _Field(
+ group="members",
+ description="""A list of filters, or `"public"`.
+
+ **List of filters**
+
+ A filter starting with `!` will exclude matching objects instead of including them.
+ The `members` option takes precedence over `filters` (filters will still be applied recursively
+ to lower members in the hierarchy).
+
+ **Filtering methods**
+
+ [:octicons-heart-fill-24:{ .pulse } Sponsors only](../insiders/index.md){ .insiders } —
+ [:octicons-tag-24: Insiders 1.11.0](../insiders/changelog.md#1.11.0)
+
+ The `public` method will include only public objects:
+ those added to `__all__` or not starting with an underscore (except for special methods/attributes).
+ """,
+ ),
+ ] = field(default_factory=lambda: _DEFAULT_FILTERS.copy())
+
+ find_stubs_package: Annotated[
+ bool,
+ _Field(
+ group="general",
+ description="Whether to load stubs package (package-stubs) when extracting docstrings.",
+ ),
+ ] = False
+
+ group_by_category: Annotated[
+ bool,
+ _Field(
+ group="members",
+ description="Group the object's children by categories: attributes, classes, functions, and modules.",
+ ),
+ ] = True
+
+ heading: Annotated[
+ str,
+ _Field(
+ group="headings",
+ description="A custom string to override the autogenerated heading of the root object.",
+ ),
+ ] = ""
+
+ heading_level: Annotated[
+ int,
+ _Field(
+ group="headings",
+ description="The initial heading level to use.",
+ ),
+ ] = 2
+
+ inherited_members: Annotated[
+ bool | list[str],
+ _Field(
+ group="members",
+ description="""A boolean, or an explicit list of inherited members to render.
+
+ If true, select all inherited members, which can then be filtered with `members`.
+ If false or empty list, do not select any inherited member.
+ """,
+ ),
+ ] = False
+
+ line_length: Annotated[
+ int,
+ _Field(
+ group="signatures",
+ description="Maximum line length when formatting code/signatures.",
+ ),
+ ] = 60
+
+ members: Annotated[
+ list[str] | bool | None,
+ _Field(
+ group="members",
+ description="""A boolean, or an explicit list of members to render.
+
+ If true, select all members without further filtering.
+ If false or empty list, do not render members.
+ If none, select all members and apply further filtering with filters and docstrings.
+ """,
+ ),
+ ] = None
+
+ members_order: Annotated[
+ Order | list[Order],
+ _Field(
+ group="members",
+ description="""The members ordering to use.
+
+ - `__all__`: order members according to `__all__` module attributes, if declared;
+ - `alphabetical`: order members alphabetically;
+ - `source`: order members as they appear in the source file.
+
+ Since `__all__` is a module-only attribute, it can't be used to sort class members,
+ therefore the `members_order` option accepts a list of ordering methods,
+ indicating ordering preferences.
+ """,
+ ),
+ ] = "alphabetical"
+
+ merge_init_into_class: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to merge the `__init__` method into the class' signature and docstring.",
+ ),
+ ] = False
+
+ modernize_annotations: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Whether to modernize annotations, for example `Optional[str]` into `str | None`.",
+ ),
+ ] = False
+
+ parameter_headings: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="Whether to render headings for parameters (therefore showing parameters in the ToC).",
+ ),
+ ] = False
+
+ preload_modules: Annotated[
+ list[str],
+ _Field(
+ group="general",
+ description="""Pre-load modules that are not specified directly in autodoc instructions (`::: identifier`).
+
+ It is useful when you want to render documentation for a particular member of an object,
+ and this member is imported from another package than its parent.
+
+ For an imported member to be rendered, you need to add it to the `__all__` attribute
+ of the importing module.
+
+ The modules must be listed as an array of strings.
+ """,
+ ),
+ ] = field(default_factory=list)
+
+ relative_crossrefs: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to enable the relative crossref syntax.",
+ ),
+ ] = False
+
+ scoped_crossrefs: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to enable the scoped crossref ability.",
+ ),
+ ] = False
+
+ show_overloads: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Show the overloads of a function or method.",
+ ),
+ ] = True
+
+ separate_signature: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="""Whether to put the whole signature in a code block below the heading.
+
+ If Black or Ruff are installed, the signature is also formatted using them.
+ """,
+ ),
+ ] = False
+
+ show_bases: Annotated[
+ bool,
+ _Field(
+ group="general",
+ description="Show the base classes of a class.",
+ ),
+ ] = True
+
+ show_category_heading: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="When grouped by categories, show a heading for each category.",
+ ),
+ ] = False
+
+ show_docstring_attributes: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Attributes' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_classes: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Classes' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_description: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the textual block (including admonitions) in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_examples: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Examples' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_functions: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Functions' or 'Methods' sections in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_modules: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Modules' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_other_parameters: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Other Parameters' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_parameters: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Parameters' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_raises: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Raises' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_receives: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Receives' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_returns: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Returns' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_warns: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Warns' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_docstring_yields: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to display the 'Yields' section in the object's docstring.",
+ ),
+ ] = True
+
+ show_if_no_docstring: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Show the object heading even if it has no docstring or children with docstrings.",
+ ),
+ ] = False
+
+ show_inheritance_diagram: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Show the inheritance diagram of a class using Mermaid.",
+ ),
+ ] = False
+
+ show_labels: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Whether to show labels of the members.",
+ ),
+ ] = True
+
+ show_object_full_path: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Show the full Python path of every object.",
+ ),
+ ] = False
+
+ show_root_full_path: Annotated[
+ bool,
+ _Field(
+ group="docstrings",
+ description="Show the full Python path for the root object heading.",
+ ),
+ ] = True
+
+ show_root_heading: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="""Show the heading of the object at the root of the documentation tree.
+
+ The root object is the object referenced by the identifier after `:::`.
+ """,
+ ),
+ ] = False
+
+ show_root_members_full_path: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="Show the full Python path of the root members.",
+ ),
+ ] = False
+
+ show_root_toc_entry: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="If the root heading is not shown, at least add a ToC entry for it.",
+ ),
+ ] = True
+
+ show_signature_annotations: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Show the type annotations in methods and functions signatures.",
+ ),
+ ] = False
+
+ show_signature: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Show methods and functions signatures.",
+ ),
+ ] = True
+
+ show_source: Annotated[
+ bool,
+ _Field(
+ group="general",
+ description="Show the source code of this object.",
+ ),
+ ] = True
+
+ show_submodules: Annotated[
+ bool,
+ _Field(
+ group="members",
+ description="When rendering a module, show its submodules recursively.",
+ ),
+ ] = False
+
+ show_symbol_type_heading: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="Show the symbol type in headings (e.g. mod, class, meth, func and attr).",
+ ),
+ ] = False
+
+ show_symbol_type_toc: Annotated[
+ bool,
+ _Field(
+ group="headings",
+ description="Show the symbol type in the Table of Contents (e.g. mod, class, methd, func and attr).",
+ ),
+ ] = False
+
+ signature_crossrefs: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Whether to render cross-references for type annotations in signatures.",
+ ),
+ ] = False
+
+ summary: Annotated[
+ bool | SummaryOption,
+ _Field(
+ group="members",
+ description="Whether to render summaries of modules, classes, functions (methods) and attributes.",
+ ),
+ ] = field(default_factory=SummaryOption)
+
+ toc_label: Annotated[
+ str,
+ _Field(
+ group="headings",
+ description="A custom string to override the autogenerated toc label of the root object.",
+ ),
+ ] = ""
+
+ unwrap_annotated: Annotated[
+ bool,
+ _Field(
+ group="signatures",
+ description="Whether to unwrap `Annotated` types to show only the type without the annotations.",
+ ),
+ ] = False
+
+ extra: Annotated[
+ dict[str, Any],
+ _Field(
+ group="general",
+ description="Extra options.",
+ ),
+ ] = field(default_factory=dict)
+
+ @classmethod
+ def _extract_extra(cls, data: dict[str, Any]) -> tuple[dict[str, Any], dict[str, Any]]:
+ field_names = {field.name for field in fields(cls)}
+ copy = data.copy()
+ return {name: copy.pop(name) for name in data if name not in field_names}, copy
+
+ @classmethod
+ def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
+ """Coerce data."""
+ if "docstring_options" in data:
+ docstring_style = data.get("docstring_style", "google")
+ docstring_options = data["docstring_options"]
+ if docstring_options is not None:
+ if docstring_style == "auto":
+ docstring_options = AutoStyleOptions.from_data(**docstring_options)
+ elif docstring_style == "google":
+ docstring_options = GoogleStyleOptions(**docstring_options)
+ elif docstring_style == "numpy":
+ docstring_options = NumpyStyleOptions(**docstring_options)
+ elif docstring_style == "sphinx":
+ docstring_options = SphinxStyleOptions(**docstring_options)
+ data["docstring_options"] = docstring_options
+ if "summary" in data:
+ summary = data["summary"]
+ if summary is True:
+ summary = SummaryOption(attributes=True, functions=True, classes=True, modules=True)
+ elif summary is False:
+ summary = SummaryOption(attributes=False, functions=False, classes=False, modules=False)
+ else:
+ summary = SummaryOption(**summary)
+ data["summary"] = summary
+ return data
+
+ @classmethod
+ def from_data(cls, **data: Any) -> Self:
+ """Create an instance from a dictionary."""
+ return cls(**cls.coerce(**data))
+
+
+# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
+@dataclass(**_dataclass_options) # type: ignore[call-overload]
+class PythonOptions(PythonInputOptions): # type: ignore[override,unused-ignore]
+ """Final options passed as template context."""
+
+ filters: list[tuple[re.Pattern, bool]] | Literal["public"] = field( # type: ignore[assignment]
+ default_factory=lambda: [
+ (re.compile(filtr.removeprefix("!")), filtr.startswith("!")) for filtr in _DEFAULT_FILTERS
+ ],
+ )
+ """A list of filters, or `"public"`."""
+
+ summary: SummaryOption = field(default_factory=SummaryOption)
+ """Whether to render summaries of modules, classes, functions (methods) and attributes."""
+
+ @classmethod
+ def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
+ """Create an instance from a dictionary."""
+ if "filters" in data:
+ # Non-insiders: transform back to default filters.
+ # Next: `if "filters" in data and not isinstance(data["filters"], str):`.
+ if data["filters"] == "public":
+ data["filters"] = _DEFAULT_FILTERS
+ # Filters are `None` or a sequence of strings (tests use tuples).
+ data["filters"] = [
+ (re.compile(filtr.removeprefix("!")), filtr.startswith("!")) for filtr in data["filters"] or ()
+ ]
+ return super().coerce(**data)
+
+
+# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
+@dataclass(**_dataclass_options) # type: ignore[call-overload]
+class Inventory:
+ """An inventory."""
+
+ url: Annotated[
+ str,
+ _Field(
+ parent="inventories",
+ description="The URL of the inventory.",
+ ),
+ ]
+
+ base_url: Annotated[
+ str | None,
+ _Field(
+ parent="inventories",
+ description="The base URL of the inventory.",
+ ),
+ ] = None
+
+ domains: Annotated[
+ list[str],
+ _Field(
+ parent="inventories",
+ description="The domains to load from the inventory.",
+ ),
+ ] = field(default_factory=lambda: ["py"])
+
+ @property
+ def _config(self) -> dict[str, Any]:
+ return {"base_url": self.base_url, "domains": self.domains}
+
+
+# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
+@dataclass(**_dataclass_options) # type: ignore[call-overload]
+class PythonInputConfig:
+ """Python handler configuration."""
+
+ inventories: Annotated[
+ list[str | Inventory],
+ _Field(description="The inventories to load."),
+ ] = field(default_factory=list)
+
+ paths: Annotated[
+ list[str],
+ _Field(description="The paths in which to search for Python packages."),
+ ] = field(default_factory=lambda: ["."])
+
+ load_external_modules: Annotated[
+ bool | None,
+ _Field(description="Whether to always load external modules/packages."),
+ ] = None
+
+ options: Annotated[
+ PythonInputOptions,
+ _Field(description="Configuration options for collecting and rendering objects."),
+ ] = field(default_factory=PythonInputOptions)
+
+ locale: Annotated[
+ str | None,
+ _Field(description="The locale to use when translating template strings."),
+ ] = None
+
+ @classmethod
+ def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
+ """Coerce data."""
+ return data
+
+ @classmethod
+ def from_data(cls, **data: Any) -> Self:
+ """Create an instance from a dictionary."""
+ return cls(**cls.coerce(**data))
+
+
+# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
+@dataclass(**_dataclass_options) # type: ignore[call-overload]
+class PythonConfig(PythonInputConfig): # type: ignore[override,unused-ignore]
+ """Python handler configuration."""
+
+ inventories: Annotated[
+ list[Inventory],
+ _Field(description="The object inventories to load."),
+ ] = field(default_factory=list) # type: ignore[assignment]
+
+ options: Annotated[
+ dict[str, Any],
+ _Field(description="Configuration options for collecting and rendering objects."),
+ ] = field(default_factory=dict) # type: ignore[assignment]
+
+ @classmethod
+ def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
+ """Coerce data."""
+ if "inventories" in data:
+ data["inventories"] = [
+ Inventory(url=inv) if isinstance(inv, str) else Inventory(**inv) for inv in data["inventories"]
+ ]
+ return data
diff --git a/src/mkdocstrings_handlers/python/debug.py b/src/mkdocstrings_handlers/python/_internal/debug.py
similarity index 80%
rename from src/mkdocstrings_handlers/python/debug.py
rename to src/mkdocstrings_handlers/python/_internal/debug.py
index e44f2be5..5fff669f 100644
--- a/src/mkdocstrings_handlers/python/debug.py
+++ b/src/mkdocstrings_handlers/python/_internal/debug.py
@@ -1,5 +1,3 @@
-"""Debugging utilities."""
-
from __future__ import annotations
import os
@@ -10,7 +8,7 @@
@dataclass
-class Variable:
+class _Variable:
"""Dataclass describing an environment variable."""
name: str
@@ -20,7 +18,7 @@ class Variable:
@dataclass
-class Package:
+class _Package:
"""Dataclass describing a Python package."""
name: str
@@ -30,7 +28,7 @@ class Package:
@dataclass
-class Environment:
+class _Environment:
"""Dataclass to store environment information."""
interpreter_name: str
@@ -41,9 +39,9 @@ class Environment:
"""Path to Python executable."""
platform: str
"""Operating System."""
- packages: list[Package]
+ packages: list[_Package]
"""Installed packages."""
- variables: list[Variable]
+ variables: list[_Variable]
"""Environment variables."""
@@ -58,7 +56,7 @@ def _interpreter_name_version() -> tuple[str, str]:
return "", "0.0.0"
-def get_version(dist: str = "mkdocstrings-python") -> str:
+def _get_version(dist: str = "mkdocstrings-python") -> str:
"""Get version of the given distribution.
Parameters:
@@ -73,28 +71,28 @@ def get_version(dist: str = "mkdocstrings-python") -> str:
return "0.0.0"
-def get_debug_info() -> Environment:
+def _get_debug_info() -> _Environment:
"""Get debug/environment information.
Returns:
Environment information.
"""
py_name, py_version = _interpreter_name_version()
- packages = ["mkdocs", "mkdocstrings", "mkdocstrings-python", "griffe"]
+ packages = ["mkdocstrings-python"]
variables = ["PYTHONPATH", *[var for var in os.environ if var.startswith("MKDOCSTRINGS_PYTHON")]]
- return Environment(
+ return _Environment(
interpreter_name=py_name,
interpreter_version=py_version,
interpreter_path=sys.executable,
platform=platform.platform(),
- variables=[Variable(var, val) for var in variables if (val := os.getenv(var))],
- packages=[Package(pkg, get_version(pkg)) for pkg in packages],
+ variables=[_Variable(var, val) for var in variables if (val := os.getenv(var))],
+ packages=[_Package(pkg, _get_version(pkg)) for pkg in packages],
)
-def print_debug_info() -> None:
+def _print_debug_info() -> None:
"""Print debug/environment information."""
- info = get_debug_info()
+ info = _get_debug_info()
print(f"- __System__: {info.platform}")
print(f"- __Python__: {info.interpreter_name} {info.interpreter_version} ({info.interpreter_path})")
print("- __Environment variables__:")
@@ -106,4 +104,4 @@ def print_debug_info() -> None:
if __name__ == "__main__":
- print_debug_info()
+ _print_debug_info()
diff --git a/src/mkdocstrings_handlers/python/_internal/handler.py b/src/mkdocstrings_handlers/python/_internal/handler.py
new file mode 100644
index 00000000..158d7ddc
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/_internal/handler.py
@@ -0,0 +1,416 @@
+# This module implements a handler for the Python language.
+
+from __future__ import annotations
+
+import glob
+import os
+import posixpath
+import sys
+from contextlib import suppress
+from dataclasses import asdict
+from pathlib import Path
+from typing import TYPE_CHECKING, Any, BinaryIO, ClassVar
+from warnings import warn
+
+from griffe import (
+ AliasResolutionError,
+ GriffeLoader,
+ LinesCollection,
+ ModulesCollection,
+ Parser,
+ load_extensions,
+ patch_loggers,
+)
+from mkdocs.exceptions import PluginError
+from mkdocstrings import BaseHandler, CollectionError, CollectorItem, HandlerOptions, Inventory, get_logger
+
+from mkdocstrings_handlers.python._internal import rendering
+from mkdocstrings_handlers.python._internal.config import PythonConfig, PythonOptions
+
+if TYPE_CHECKING:
+ from collections.abc import Iterator, Mapping, MutableMapping, Sequence
+
+ from mkdocs.config.defaults import MkDocsConfig
+
+
+# YORE: EOL 3.10: Replace block with line 2.
+if sys.version_info >= (3, 11):
+ from contextlib import chdir
+else:
+ from contextlib import contextmanager
+
+ @contextmanager
+ def chdir(path: str) -> Iterator[None]:
+ old_wd = os.getcwd()
+ os.chdir(path)
+ try:
+ yield
+ finally:
+ os.chdir(old_wd)
+
+
+_logger = get_logger(__name__)
+
+patch_loggers(get_logger)
+
+
+# YORE: Bump 2: Remove block.
+def _warn_extra_options(names: Sequence[str]) -> None:
+ warn(
+ "Passing extra options directly under `options` is deprecated. "
+ "Instead, pass them under `options.extra`, and update your templates. "
+ f"Current extra (unrecognized) options: {', '.join(sorted(names))}",
+ DeprecationWarning,
+ stacklevel=3,
+ )
+
+
+class PythonHandler(BaseHandler):
+ """The Python handler class."""
+
+ name: ClassVar[str] = "python"
+ """The handler's name."""
+
+ domain: ClassVar[str] = "py"
+ """The cross-documentation domain/language for this handler."""
+
+ enable_inventory: ClassVar[bool] = True
+ """Whether this handler is interested in enabling the creation of the `objects.inv` Sphinx inventory file."""
+
+ fallback_theme: ClassVar[str] = "material"
+ """The fallback theme."""
+
+ def __init__(self, config: PythonConfig, base_dir: Path, **kwargs: Any) -> None:
+ """Initialize the handler.
+
+ Parameters:
+ config: The handler configuration.
+ base_dir: The base directory of the project.
+ **kwargs: Arguments passed to the parent constructor.
+ """
+ super().__init__(**kwargs)
+
+ self.config = config
+ """The handler configuration."""
+ self.base_dir = base_dir
+ """The base directory of the project."""
+
+ # YORE: Bump 2: Remove block.
+ global_extra, global_options = PythonOptions._extract_extra(config.options)
+ if global_extra:
+ _warn_extra_options(global_extra.keys()) # type: ignore[arg-type]
+ self._global_extra = global_extra
+ self.global_options = global_options
+ """The global configuration options (in `mkdocs.yml`)."""
+
+ # YORE: Bump 2: Replace `# ` with `` within block.
+ # self.global_options = config.options
+ # """The global configuration options (in `mkdocs.yml`)."""
+
+ # Warn if user overrides base templates.
+ if self.custom_templates:
+ for theme_dir in base_dir.joinpath(self.custom_templates, "python").iterdir():
+ if theme_dir.joinpath("_base").is_dir():
+ _logger.warning(
+ f"Overriding base template '{theme_dir.name}/_base/.html.jinja' is not supported, "
+ f"override '{theme_dir.name}/.html.jinja' instead",
+ )
+
+ paths = config.paths or []
+
+ # Expand paths with glob patterns.
+ with chdir(str(base_dir)):
+ resolved_globs = [glob.glob(path) for path in paths]
+ paths = [path for glob_list in resolved_globs for path in glob_list]
+
+ # By default, add the base directory to the search paths.
+ if not paths:
+ paths.append(str(base_dir))
+
+ # Initialize search paths from `sys.path`, eliminating empty paths.
+ search_paths = [path for path in sys.path if path]
+
+ for path in reversed(paths):
+ # If it's not absolute, make path relative to the config file path, then make it absolute.
+ if not os.path.isabs(path):
+ path = os.path.abspath(base_dir / path) # noqa: PLW2901
+ # Remove pre-listed paths.
+ if path in search_paths:
+ search_paths.remove(path)
+ # Give precedence to user-provided paths.
+ search_paths.insert(0, path)
+
+ self._paths = search_paths
+ self._modules_collection: ModulesCollection = ModulesCollection()
+ self._lines_collection: LinesCollection = LinesCollection()
+
+ def get_inventory_urls(self) -> list[tuple[str, dict[str, Any]]]:
+ """Return the URLs of the inventory files to download."""
+ return [(inv.url, inv._config) for inv in self.config.inventories]
+
+ @staticmethod
+ def load_inventory(
+ in_file: BinaryIO,
+ url: str,
+ base_url: str | None = None,
+ domains: list[str] | None = None,
+ **kwargs: Any, # noqa: ARG004
+ ) -> Iterator[tuple[str, str]]:
+ """Yield items and their URLs from an inventory file streamed from `in_file`.
+
+ This implements mkdocstrings' `load_inventory` "protocol" (see [`mkdocstrings.plugin`][]).
+
+ Arguments:
+ in_file: The binary file-like object to read the inventory from.
+ url: The URL that this file is being streamed from (used to guess `base_url`).
+ base_url: The URL that this inventory's sub-paths are relative to.
+ domains: A list of domain strings to filter the inventory by, when not passed, "py" will be used.
+ **kwargs: Ignore additional arguments passed from the config.
+
+ Yields:
+ Tuples of (item identifier, item URL).
+ """
+ domains = domains or ["py"]
+ if base_url is None:
+ base_url = posixpath.dirname(url)
+
+ for item in Inventory.parse_sphinx(in_file, domain_filter=domains).values():
+ yield item.name, posixpath.join(base_url, item.uri)
+
+ def get_options(self, local_options: Mapping[str, Any]) -> HandlerOptions:
+ """Get combined default, global and local options.
+
+ Arguments:
+ local_options: The local options.
+
+ Returns:
+ The combined options.
+ """
+ # YORE: Bump 2: Remove block.
+ local_extra, local_options = PythonOptions._extract_extra(local_options) # type: ignore[arg-type]
+ if local_extra:
+ _warn_extra_options(local_extra.keys()) # type: ignore[arg-type]
+ unknown_extra = self._global_extra | local_extra
+
+ extra = {**self.global_options.get("extra", {}), **local_options.get("extra", {})}
+ options = {**self.global_options, **local_options, "extra": extra}
+ try:
+ # YORE: Bump 2: Replace `opts =` with `return` within line.
+ opts = PythonOptions.from_data(**options)
+ except Exception as error:
+ raise PluginError(f"Invalid options: {error}") from error
+
+ # YORE: Bump 2: Remove block.
+ for key, value in unknown_extra.items():
+ object.__setattr__(opts, key, value)
+ return opts
+
+ def collect(self, identifier: str, options: PythonOptions) -> CollectorItem:
+ """Collect the documentation for the given identifier.
+
+ Parameters:
+ identifier: The identifier of the object to collect.
+ options: The options to use for the collection.
+
+ Returns:
+ The collected item.
+ """
+ module_name = identifier.split(".", 1)[0]
+ unknown_module = module_name not in self._modules_collection
+ reapply = True
+ if options == {}:
+ if unknown_module:
+ raise CollectionError("Not loading additional modules during fallback")
+ options = self.get_options({})
+ reapply = False
+
+ parser_name = options.docstring_style
+ parser = parser_name and Parser(parser_name)
+ parser_options = options.docstring_options and asdict(options.docstring_options)
+
+ if unknown_module:
+ extensions = self.normalize_extension_paths(options.extensions)
+ loader = GriffeLoader(
+ extensions=load_extensions(*extensions),
+ search_paths=self._paths,
+ docstring_parser=parser,
+ docstring_options=parser_options, # type: ignore[arg-type]
+ modules_collection=self._modules_collection,
+ lines_collection=self._lines_collection,
+ allow_inspection=options.allow_inspection,
+ force_inspection=options.force_inspection,
+ )
+ try:
+ for pre_loaded_module in options.preload_modules:
+ if pre_loaded_module not in self._modules_collection:
+ loader.load(
+ pre_loaded_module,
+ try_relative_path=False,
+ find_stubs_package=options.find_stubs_package,
+ )
+ loader.load(
+ module_name,
+ try_relative_path=False,
+ find_stubs_package=options.find_stubs_package,
+ )
+ except ImportError as error:
+ raise CollectionError(str(error)) from error
+ unresolved, iterations = loader.resolve_aliases(
+ implicit=False,
+ external=self.config.load_external_modules,
+ )
+ if unresolved:
+ _logger.debug(f"{len(unresolved)} aliases were still unresolved after {iterations} iterations")
+ _logger.debug(f"Unresolved aliases: {', '.join(sorted(unresolved))}")
+
+ try:
+ doc_object = self._modules_collection[identifier]
+ except KeyError as error:
+ raise CollectionError(f"{identifier} could not be found") from error
+ except AliasResolutionError as error:
+ raise CollectionError(str(error)) from error
+
+ if not unknown_module and reapply:
+ with suppress(AliasResolutionError):
+ if doc_object.docstring is not None:
+ doc_object.docstring.parser = parser
+ doc_object.docstring.parser_options = parser_options or {}
+
+ return doc_object
+
+ def render(self, data: CollectorItem, options: PythonOptions) -> str:
+ """Render the collected data.
+
+ Parameters:
+ data: The collected data.
+ options: The options to use for rendering.
+
+ Returns:
+ The rendered data (HTML).
+ """
+ template_name = rendering.do_get_template(self.env, data)
+ template = self.env.get_template(template_name)
+
+ return template.render(
+ **{
+ "config": options,
+ data.kind.value: data,
+ # Heading level is a "state" variable, that will change at each step
+ # of the rendering recursion. Therefore, it's easier to use it as a plain value
+ # than as an item in a dictionary.
+ "heading_level": options.heading_level,
+ "root": True,
+ "locale": self.config.locale,
+ },
+ )
+
+ def update_env(self, config: Any) -> None: # noqa: ARG002
+ """Update the Jinja environment with custom filters and tests.
+
+ Parameters:
+ config: The SSG configuration.
+ """
+ self.env.trim_blocks = True
+ self.env.lstrip_blocks = True
+ self.env.keep_trailing_newline = False
+ self.env.filters["split_path"] = rendering.do_split_path
+ self.env.filters["crossref"] = rendering.do_crossref
+ self.env.filters["multi_crossref"] = rendering.do_multi_crossref
+ self.env.filters["order_members"] = rendering.do_order_members
+ self.env.filters["format_code"] = rendering.do_format_code
+ self.env.filters["format_signature"] = rendering.do_format_signature
+ self.env.filters["format_attribute"] = rendering.do_format_attribute
+ self.env.filters["filter_objects"] = rendering.do_filter_objects
+ self.env.filters["stash_crossref"] = rendering.do_stash_crossref
+ self.env.filters["get_template"] = rendering.do_get_template
+ self.env.filters["as_attributes_section"] = rendering.do_as_attributes_section
+ self.env.filters["as_functions_section"] = rendering.do_as_functions_section
+ self.env.filters["as_classes_section"] = rendering.do_as_classes_section
+ self.env.filters["as_modules_section"] = rendering.do_as_modules_section
+ self.env.filters["backlink_tree"] = rendering.do_backlink_tree
+ self.env.globals["AutorefsHook"] = rendering.AutorefsHook
+ self.env.tests["existing_template"] = lambda template_name: template_name in self.env.list_templates()
+
+ def get_aliases(self, identifier: str) -> tuple[str, ...]:
+ """Get the aliases for the given identifier.
+
+ Parameters:
+ identifier: The identifier to get the aliases for.
+
+ Returns:
+ The aliases.
+ """
+ if "(" in identifier:
+ identifier, parameter = identifier.split("(", 1)
+ parameter.removesuffix(")")
+ else:
+ parameter = ""
+ try:
+ data = self._modules_collection[identifier]
+ except (KeyError, AliasResolutionError):
+ return ()
+ aliases = [data.path]
+ try:
+ for alias in [data.canonical_path, *data.aliases]:
+ if alias not in aliases:
+ aliases.append(alias)
+ except AliasResolutionError:
+ pass
+ if parameter:
+ return tuple(f"{alias}({parameter})" for alias in aliases)
+ return tuple(aliases)
+
+ def normalize_extension_paths(self, extensions: Sequence) -> list[str | dict[str, Any]]:
+ """Resolve extension paths relative to config file.
+
+ Parameters:
+ extensions: The extensions (configuration) to normalize.
+
+ Returns:
+ The normalized extensions.
+ """
+ normalized: list[str | dict[str, Any]] = []
+
+ for ext in extensions:
+ if isinstance(ext, dict):
+ pth, options = next(iter(ext.items()))
+ pth = str(pth)
+ else:
+ pth = str(ext)
+ options = None
+
+ if pth.endswith(".py") or ".py:" in pth or "/" in pth or "\\" in pth:
+ # This is a system path. Normalize it, make it absolute relative to config file path.
+ pth = os.path.abspath(self.base_dir / pth)
+
+ if options is not None:
+ normalized.append({pth: options})
+ else:
+ normalized.append(pth)
+
+ return normalized
+
+
+def get_handler(
+ handler_config: MutableMapping[str, Any],
+ tool_config: MkDocsConfig,
+ **kwargs: Any,
+) -> PythonHandler:
+ """Return an instance of `PythonHandler`.
+
+ Parameters:
+ handler_config: The handler configuration.
+ tool_config: The tool (SSG) configuration.
+
+ Returns:
+ An instance of `PythonHandler`.
+ """
+ base_dir = Path(tool_config.config_file_path or "./mkdocs.yml").parent
+ if "inventories" not in handler_config and "import" in handler_config:
+ warn("The 'import' key is renamed 'inventories' for the Python handler", FutureWarning, stacklevel=1)
+ handler_config["inventories"] = handler_config.pop("import", [])
+ return PythonHandler(
+ config=PythonConfig.from_data(**handler_config),
+ base_dir=base_dir,
+ **kwargs,
+ )
diff --git a/src/mkdocstrings_handlers/python/_internal/rendering.py b/src/mkdocstrings_handlers/python/_internal/rendering.py
new file mode 100644
index 00000000..897b6572
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/_internal/rendering.py
@@ -0,0 +1,834 @@
+# This module implements rendering utilities.
+
+from __future__ import annotations
+
+import random
+import re
+import string
+import subprocess
+import sys
+import warnings
+from collections import defaultdict
+from contextlib import suppress
+from dataclasses import replace
+from functools import lru_cache
+from pathlib import Path
+from re import Match, Pattern
+from typing import TYPE_CHECKING, Any, Callable, ClassVar, Literal, TypeVar
+
+from griffe import (
+ Alias,
+ AliasResolutionError,
+ CyclicAliasError,
+ DocstringAttribute,
+ DocstringClass,
+ DocstringFunction,
+ DocstringModule,
+ DocstringSectionAttributes,
+ DocstringSectionClasses,
+ DocstringSectionFunctions,
+ DocstringSectionModules,
+ Object,
+)
+from jinja2 import TemplateNotFound, pass_context, pass_environment
+from markupsafe import Markup
+from mkdocs_autorefs import AutorefsHookInterface, Backlink, BacklinkCrumb
+from mkdocstrings import get_logger
+
+if TYPE_CHECKING:
+ from collections.abc import Iterable, Iterator, Sequence
+
+ from griffe import Attribute, Class, Function, Module
+ from jinja2 import Environment
+ from jinja2.runtime import Context
+ from mkdocstrings import CollectorItem
+
+_logger = get_logger(__name__)
+
+
+def _sort_key_alphabetical(item: CollectorItem) -> str:
+ # `chr(sys.maxunicode)` is a string that contains the final unicode character,
+ # so if `name` isn't found on the object, the item will go to the end of the list.
+ return item.name or chr(sys.maxunicode)
+
+
+def _sort_key_source(item: CollectorItem) -> float:
+ # If `lineno` is none, the item will go to the end of the list.
+ if item.is_alias:
+ return item.alias_lineno if item.alias_lineno is not None else float("inf")
+ return item.lineno if item.lineno is not None else float("inf")
+
+
+def _sort__all__(item: CollectorItem) -> float: # noqa: ARG001
+ raise ValueError("Not implemented in public version of mkdocstrings-python")
+
+
+Order = Literal["__all__", "alphabetical", "source"]
+"""Ordering methods.
+
+- `__all__`: order members according to `__all__` module attributes, if declared;
+- `alphabetical`: order members alphabetically;
+- `source`: order members as they appear in the source file.
+"""
+
+_order_map: dict[str, Callable[[Object | Alias], str | float]] = {
+ "alphabetical": _sort_key_alphabetical,
+ "source": _sort_key_source,
+ "__all__": _sort__all__,
+}
+
+
+def do_format_code(code: str, line_length: int) -> str:
+ """Format code.
+
+ Parameters:
+ code: The code to format.
+ line_length: The line length.
+
+ Returns:
+ The same code, formatted.
+ """
+ code = code.strip()
+ if len(code) < line_length:
+ return code
+ formatter = _get_formatter()
+ return formatter(code, line_length)
+
+
+class _StashCrossRefFilter:
+ stash: ClassVar[dict[str, str]] = {}
+
+ @staticmethod
+ def _gen_key(length: int) -> str:
+ return "_" + "".join(random.choice(string.ascii_letters + string.digits) for _ in range(max(1, length - 1))) # noqa: S311
+
+ def _gen_stash_key(self, length: int) -> str:
+ key = self._gen_key(length)
+ while key in self.stash:
+ key = self._gen_key(length)
+ return key
+
+ def __call__(self, crossref: str, *, length: int) -> str:
+ key = self._gen_stash_key(length)
+ self.stash[key] = crossref
+ return key
+
+
+do_stash_crossref = _StashCrossRefFilter()
+"""Filter to stash cross-references (and restore them after formatting and highlighting)."""
+
+
+def _format_signature(name: Markup, signature: str, line_length: int) -> str:
+ name = str(name).strip() # type: ignore[assignment]
+ signature = signature.strip()
+ if len(name + signature) < line_length:
+ return name + signature
+
+ # Black cannot format names with dots, so we replace
+ # the whole name with a string of equal length
+ name_length = len(name)
+ formatter = _get_formatter()
+ formatable = f"def {'x' * name_length}{signature}: pass"
+ formatted = formatter(formatable, line_length)
+
+ # We put back the original name
+ # and remove starting `def ` and trailing `: pass`
+ return name + formatted[4:-5].strip()[name_length:-1]
+
+
+@pass_context
+def do_format_signature(
+ context: Context,
+ callable_path: Markup,
+ function: Function,
+ line_length: int,
+ *,
+ annotations: bool | None = None,
+ crossrefs: bool = False, # noqa: ARG001
+) -> str:
+ """Format a signature.
+
+ Parameters:
+ context: Jinja context, passed automatically.
+ callable_path: The path of the callable we render the signature of.
+ function: The function we render the signature of.
+ line_length: The line length.
+ annotations: Whether to show type annotations.
+ crossrefs: Whether to cross-reference types in the signature.
+
+ Returns:
+ The same code, formatted.
+ """
+ env = context.environment
+ # YORE: Bump 2: Replace `do_get_template(env, "signature")` with `"signature.html.jinja"` within line.
+ template = env.get_template(do_get_template(env, "signature"))
+
+ if annotations is None:
+ new_context = context.parent
+ else:
+ new_context = dict(context.parent)
+ new_context["config"] = replace(new_context["config"], show_signature_annotations=annotations)
+
+ signature = template.render(new_context, function=function, signature=True)
+ signature = _format_signature(callable_path, signature, line_length)
+ signature = str(
+ env.filters["highlight"](
+ Markup.escape(signature),
+ language="python",
+ inline=False,
+ classes=["doc-signature"],
+ linenums=False,
+ ),
+ )
+
+ # Since we highlight the signature without `def`,
+ # Pygments sees it as a function call and not a function definition.
+ # The result is that the function name is not parsed as such,
+ # but instead as a regular name: `n` CSS class instead of `nf`.
+ # When the function name is a known special name like `__exit__`,
+ # Pygments will set an `fm` (function -> magic) CSS class.
+ # To fix this, we replace the CSS class in the first span with `nf`,
+ # unless we already found an `nf` span.
+ if not re.search(r'', signature):
+ signature = re.sub(r'', '', signature, count=1)
+
+ if stash := env.filters["stash_crossref"].stash:
+ for key, value in stash.items():
+ signature = re.sub(rf"\b{key}\b", value, signature)
+ stash.clear()
+
+ return signature
+
+
+@pass_context
+def do_format_attribute(
+ context: Context,
+ attribute_path: Markup,
+ attribute: Attribute,
+ line_length: int,
+ *,
+ crossrefs: bool = False, # noqa: ARG001
+) -> str:
+ """Format an attribute.
+
+ Parameters:
+ context: Jinja context, passed automatically.
+ attribute_path: The path of the callable we render the signature of.
+ attribute: The attribute we render the signature of.
+ line_length: The line length.
+ crossrefs: Whether to cross-reference types in the signature.
+
+ Returns:
+ The same code, formatted.
+ """
+ env = context.environment
+ # YORE: Bump 2: Replace `do_get_template(env, "expression")` with `"expression.html.jinja"` within line.
+ template = env.get_template(do_get_template(env, "expression"))
+ annotations = context.parent["config"].show_signature_annotations
+
+ signature = str(attribute_path).strip()
+ if annotations and attribute.annotation:
+ annotation = template.render(
+ context.parent,
+ expression=attribute.annotation,
+ signature=True,
+ backlink_type="returned-by",
+ )
+ signature += f": {annotation}"
+ if attribute.value:
+ value = template.render(context.parent, expression=attribute.value, signature=True, backlink_type="used-by")
+ signature += f" = {value}"
+
+ signature = do_format_code(signature, line_length)
+ signature = str(
+ env.filters["highlight"](
+ Markup.escape(signature),
+ language="python",
+ inline=False,
+ classes=["doc-signature"],
+ linenums=False,
+ ),
+ )
+
+ if stash := env.filters["stash_crossref"].stash:
+ for key, value in stash.items():
+ signature = re.sub(rf"\b{key}\b", value, signature)
+ stash.clear()
+
+ return signature
+
+
+def do_order_members(
+ members: Sequence[Object | Alias],
+ order: Order | list[Order],
+ members_list: bool | list[str] | None,
+) -> Sequence[Object | Alias]:
+ """Order members given an ordering method.
+
+ Parameters:
+ members: The members to order.
+ order: The ordering method.
+ members_list: An optional member list (manual ordering).
+
+ Returns:
+ The same members, ordered.
+ """
+ if isinstance(members_list, list) and members_list:
+ sorted_members = []
+ members_dict = {member.name: member for member in members}
+ for name in members_list:
+ if name in members_dict:
+ sorted_members.append(members_dict[name])
+ return sorted_members
+ if isinstance(order, str):
+ order = [order]
+ for method in order:
+ with suppress(ValueError):
+ return sorted(members, key=_order_map[method])
+ return members
+
+
+# YORE: Bump 2: Remove block.
+@lru_cache
+def _warn_crossref() -> None:
+ warnings.warn(
+ "The `crossref` filter is deprecated and will be removed in a future version",
+ DeprecationWarning,
+ stacklevel=1,
+ )
+
+
+# YORE: Bump 2: Remove block.
+def do_crossref(path: str, *, brief: bool = True) -> Markup:
+ """Deprecated. Filter to create cross-references.
+
+ Parameters:
+ path: The path to link to.
+ brief: Show only the last part of the path, add full path as hover.
+
+ Returns:
+ Markup text.
+ """
+ _warn_crossref()
+ full_path = path
+ if brief:
+ path = full_path.split(".")[-1]
+ return Markup("{text}
"
+ return Markup(text).format(**variables) # noqa: S704
+
+
+_split_path_re = re.compile(r"([.(]?)([\w]+)(\))?")
+_splitable_re = re.compile(r"[().]")
+
+
+def do_split_path(path: str, full_path: str) -> Iterator[tuple[str, str, str, str]]:
+ """Split object paths for building cross-references.
+
+ Parameters:
+ path: The path to split.
+ full_path: The full path, used to compute correct paths for each part of the path.
+
+ Yields:
+ 4-tuples: prefix, word, full path, suffix.
+ """
+ # Path is a single word, yield full path directly.
+ if not _splitable_re.search(path):
+ yield ("", path, full_path, "")
+ return
+
+ current_path = ""
+ if path == full_path:
+ # Split full path and yield directly without storing data in a dict.
+ for match in _split_path_re.finditer(full_path):
+ prefix, word, suffix = match.groups()
+ current_path = f"{current_path}{prefix}{word}{suffix or ''}" if current_path else word
+ yield prefix or "", word, current_path, suffix or ""
+ return
+
+ # Split full path first to store tuples in a dict.
+ elements = {}
+ for match in _split_path_re.finditer(full_path):
+ prefix, word, suffix = match.groups()
+ current_path = f"{current_path}{prefix}{word}{suffix or ''}" if current_path else word
+ elements[word] = (prefix or "", word, current_path, suffix or "")
+
+ # Then split path and pick tuples from the dict.
+ first = True
+ for match in _split_path_re.finditer(path):
+ prefix, word, current_path, suffix = elements[match.group(2)]
+ yield "" if first else prefix, word, current_path, suffix
+ first = False
+
+
+def _keep_object(name: str, filters: Sequence[tuple[Pattern, bool]]) -> bool:
+ keep = None
+ rules = set()
+ for regex, exclude in filters:
+ rules.add(exclude)
+ if regex.search(name):
+ keep = not exclude
+ if keep is None:
+ # When we only include stuff, no match = reject.
+ # When we only exclude stuff, or include and exclude stuff, no match = keep.
+ return rules != {False}
+ return keep
+
+
+def _parents(obj: Alias) -> set[str]:
+ parent: Object | Alias = obj.parent # type: ignore[assignment]
+ parents = {obj.path, parent.path}
+ if parent.is_alias:
+ parents.add(parent.final_target.path) # type: ignore[union-attr]
+ while parent.parent:
+ parent = parent.parent
+ parents.add(parent.path)
+ if parent.is_alias:
+ parents.add(parent.final_target.path) # type: ignore[union-attr]
+ return parents
+
+
+def _remove_cycles(objects: list[Object | Alias]) -> Iterator[Object | Alias]:
+ suppress_errors = suppress(AliasResolutionError, CyclicAliasError)
+ for obj in objects:
+ if obj.is_alias:
+ with suppress_errors:
+ if obj.final_target.path in _parents(obj): # type: ignore[arg-type,union-attr]
+ continue
+ yield obj
+
+
+def do_filter_objects(
+ objects_dictionary: dict[str, Object | Alias],
+ *,
+ filters: Sequence[tuple[Pattern, bool]] | Literal["public"] | None = None,
+ members_list: bool | list[str] | None = None,
+ inherited_members: bool | list[str] = False,
+ keep_no_docstrings: bool = True,
+) -> list[Object | Alias]:
+ """Filter a dictionary of objects based on their docstrings.
+
+ Parameters:
+ objects_dictionary: The dictionary of objects.
+ filters: Filters to apply, based on members' names, or `"public"`.
+ Each element is a tuple: a pattern, and a boolean indicating whether
+ to reject the object if the pattern matches.
+ members_list: An optional, explicit list of members to keep.
+ When given and empty, return an empty list.
+ When given and not empty, ignore filters and docstrings presence/absence.
+ inherited_members: Whether to keep inherited members or exclude them.
+ keep_no_docstrings: Whether to keep objects with no/empty docstrings (recursive check).
+
+ Returns:
+ A list of objects.
+ """
+ inherited_members_specified = False
+ if inherited_members is True:
+ # Include all inherited members.
+ objects = list(objects_dictionary.values())
+ elif inherited_members is False:
+ # Include no inherited members.
+ objects = [obj for obj in objects_dictionary.values() if not obj.inherited]
+ else:
+ # Include specific inherited members.
+ inherited_members_specified = True
+ objects = [
+ obj for obj in objects_dictionary.values() if not obj.inherited or obj.name in set(inherited_members)
+ ]
+
+ if members_list is True:
+ # Return all pre-selected members.
+ return objects
+
+ if members_list is False or members_list == []:
+ # Return selected inherited members, if any.
+ return [obj for obj in objects if obj.inherited]
+
+ if members_list is not None:
+ # Return selected members (keeping any pre-selected inherited members).
+ return [
+ obj for obj in objects if obj.name in set(members_list) or (inherited_members_specified and obj.inherited)
+ ]
+
+ # Use filters and docstrings.
+ if filters == "public":
+ objects = [obj for obj in objects if obj.is_public]
+ elif filters:
+ objects = [
+ obj for obj in objects if _keep_object(obj.name, filters) or (inherited_members_specified and obj.inherited)
+ ]
+ if not keep_no_docstrings:
+ objects = [obj for obj in objects if obj.has_docstrings or (inherited_members_specified and obj.inherited)]
+
+ # Prevent infinite recursion.
+ if objects:
+ objects = list(_remove_cycles(objects))
+
+ return objects
+
+
+@lru_cache(maxsize=1)
+def _get_formatter() -> Callable[[str, int], str]:
+ for formatter_function in [
+ _get_black_formatter,
+ _get_ruff_formatter,
+ ]:
+ if (formatter := formatter_function()) is not None:
+ return formatter
+
+ _logger.info("Formatting signatures requires either Black or Ruff to be installed.")
+ return lambda text, _: text
+
+
+def _get_ruff_formatter() -> Callable[[str, int], str] | None:
+ try:
+ from ruff.__main__ import find_ruff_bin
+ except ImportError:
+ return None
+
+ try:
+ ruff_bin = find_ruff_bin()
+ except FileNotFoundError:
+ ruff_bin = "ruff"
+
+ def formatter(code: str, line_length: int) -> str:
+ try:
+ completed_process = subprocess.run( # noqa: S603
+ [
+ ruff_bin,
+ "format",
+ "--config",
+ f"line-length={line_length}",
+ "--stdin-filename",
+ "file.py",
+ "-",
+ ],
+ check=True,
+ capture_output=True,
+ text=True,
+ input=code,
+ )
+ except subprocess.CalledProcessError:
+ return code
+ else:
+ return completed_process.stdout
+
+ return formatter
+
+
+def _get_black_formatter() -> Callable[[str, int], str] | None:
+ try:
+ from black import InvalidInput, Mode, format_str
+ except ModuleNotFoundError:
+ return None
+
+ def formatter(code: str, line_length: int) -> str:
+ mode = Mode(line_length=line_length)
+ try:
+ return format_str(code, mode=mode)
+ except InvalidInput:
+ return code
+
+ return formatter
+
+
+# YORE: Bump 2: Remove line.
+@pass_environment
+# YORE: Bump 2: Replace `env: Environment, ` with `` within line.
+# YORE: Bump 2: Replace `str | ` with `` within line.
+def do_get_template(env: Environment, obj: str | Object) -> str:
+ """Get the template name used to render an object.
+
+ Parameters:
+ env: The Jinja environment, passed automatically.
+ obj: A Griffe object, or a template name.
+
+ Returns:
+ A template name.
+ """
+ name = obj
+ if isinstance(obj, (Alias, Object)):
+ extra_data = getattr(obj, "extra", {}).get("mkdocstrings", {})
+ if name := extra_data.get("template", ""):
+ return name
+ name = obj.kind.value
+ # YORE: Bump 2: Replace block with `return f"{name}.html.jinja"`.
+ try:
+ template = env.get_template(f"{name}.html")
+ except TemplateNotFound:
+ return f"{name}.html.jinja"
+ our_template = Path(template.filename).is_relative_to(Path(__file__).parent.parent) # type: ignore[arg-type]
+ if our_template:
+ return f"{name}.html.jinja"
+ _logger.warning(
+ f"DeprecationWarning: Overriding '{name}.html' is deprecated, override '{name}.html.jinja' instead. ",
+ once=True,
+ )
+ return f"{name}.html"
+
+
+@pass_context
+def do_as_attributes_section(
+ context: Context, # noqa: ARG001
+ attributes: Sequence[Attribute],
+ *,
+ check_public: bool = True,
+) -> DocstringSectionAttributes:
+ """Build an attributes section from a list of attributes.
+
+ Parameters:
+ attributes: The attributes to build the section from.
+ check_public: Whether to check if the attribute is public.
+
+ Returns:
+ An attributes docstring section.
+ """
+
+ def _parse_docstring_summary(attribute: Attribute) -> str:
+ if attribute.docstring is None:
+ return ""
+ line = attribute.docstring.value.split("\n", 1)[0]
+ if ":" in line and attribute.docstring.parser_options.get("returns_type_in_property_summary", False):
+ _, line = line.split(":", 1)
+ return line
+
+ return DocstringSectionAttributes(
+ [
+ DocstringAttribute(
+ name=attribute.name,
+ description=_parse_docstring_summary(attribute),
+ annotation=attribute.annotation,
+ value=attribute.value, # type: ignore[arg-type]
+ )
+ for attribute in attributes
+ if not check_public or attribute.is_public
+ ],
+ )
+
+
+@pass_context
+def do_as_functions_section(
+ context: Context,
+ functions: Sequence[Function],
+ *,
+ check_public: bool = True,
+) -> DocstringSectionFunctions:
+ """Build a functions section from a list of functions.
+
+ Parameters:
+ functions: The functions to build the section from.
+ check_public: Whether to check if the function is public.
+
+ Returns:
+ A functions docstring section.
+ """
+ keep_init_method = not context.parent["config"].merge_init_into_class
+ return DocstringSectionFunctions(
+ [
+ DocstringFunction(
+ name=function.name,
+ description=function.docstring.value.split("\n", 1)[0] if function.docstring else "",
+ )
+ for function in functions
+ if (not check_public or function.is_public) and (function.name != "__init__" or keep_init_method)
+ ],
+ )
+
+
+@pass_context
+def do_as_classes_section(
+ context: Context, # noqa: ARG001
+ classes: Sequence[Class],
+ *,
+ check_public: bool = True,
+) -> DocstringSectionClasses:
+ """Build a classes section from a list of classes.
+
+ Parameters:
+ classes: The classes to build the section from.
+ check_public: Whether to check if the class is public.
+
+ Returns:
+ A classes docstring section.
+ """
+ return DocstringSectionClasses(
+ [
+ DocstringClass(
+ name=cls.name,
+ description=cls.docstring.value.split("\n", 1)[0] if cls.docstring else "",
+ )
+ for cls in classes
+ if not check_public or cls.is_public
+ ],
+ )
+
+
+@pass_context
+def do_as_modules_section(
+ context: Context, # noqa: ARG001
+ modules: Sequence[Module],
+ *,
+ check_public: bool = True,
+) -> DocstringSectionModules:
+ """Build a modules section from a list of modules.
+
+ Parameters:
+ modules: The modules to build the section from.
+ check_public: Whether to check if the module is public.
+
+ Returns:
+ A modules docstring section.
+ """
+ return DocstringSectionModules(
+ [
+ DocstringModule(
+ name=module.name,
+ description=module.docstring.value.split("\n", 1)[0] if module.docstring else "",
+ )
+ for module in modules
+ if not check_public or module.is_public
+ ],
+ )
+
+
+class AutorefsHook(AutorefsHookInterface):
+ """Autorefs hook.
+
+ With this hook, we're able to add context to autorefs (cross-references),
+ such as originating file path and line number, to improve error reporting.
+ """
+
+ def __init__(self, current_object: Object | Alias, config: dict[str, Any]) -> None:
+ """Initialize the hook.
+
+ Parameters:
+ current_object: The object being rendered.
+ config: The configuration dictionary.
+ """
+ self.current_object = current_object
+ """The current object being rendered."""
+ self.config = config
+ """The configuration options."""
+
+ def expand_identifier(self, identifier: str) -> str:
+ """Expand an identifier.
+
+ Parameters:
+ identifier: The identifier to expand.
+
+ Returns:
+ The expanded identifier.
+ """
+ return identifier
+
+ def get_context(self) -> AutorefsHookInterface.Context:
+ """Get the context for the current object.
+
+ Returns:
+ The context.
+ """
+ role = {
+ "attribute": "data" if self.current_object.parent and self.current_object.parent.is_module else "attr",
+ "class": "class",
+ "function": "meth" if self.current_object.parent and self.current_object.parent.is_class else "func",
+ "module": "mod",
+ }.get(self.current_object.kind.value.lower(), "obj")
+ origin = self.current_object.path
+ try:
+ filepath = self.current_object.docstring.parent.filepath # type: ignore[union-attr]
+ lineno = self.current_object.docstring.lineno or 0 # type: ignore[union-attr]
+ except AttributeError:
+ filepath = self.current_object.filepath
+ lineno = 0
+
+ return AutorefsHookInterface.Context(
+ domain="py",
+ role=role,
+ origin=origin,
+ filepath=str(filepath),
+ lineno=lineno,
+ )
+
+
+_T = TypeVar("_T")
+_Tree = dict[_T, "_Tree"]
+_rtree = lambda: defaultdict(_rtree) # type: ignore[has-type,var-annotated] # noqa: E731
+
+Tree = dict[tuple[_T, ...], "Tree"]
+"""A tree type. Each node holds a tuple of items."""
+
+
+def _tree(data: Iterable[tuple[_T, ...]]) -> _Tree:
+ new_tree = _rtree()
+ for nav in data:
+ *path, leaf = nav
+ node = new_tree
+ for key in path:
+ node = node[key]
+ node[leaf] = _rtree()
+ return new_tree
+
+
+def _compact_tree(tree: _Tree) -> Tree:
+ new_tree = _rtree()
+ for key, value in tree.items():
+ child = _compact_tree(value)
+ if len(child) == 1:
+ child_key, child_value = next(iter(child.items()))
+ new_key = (key, *child_key)
+ new_tree[new_key] = child_value
+ else:
+ new_tree[(key,)] = child
+ return new_tree
+
+
+def do_backlink_tree(backlinks: list[Backlink]) -> Tree[BacklinkCrumb]:
+ """Build a tree of backlinks.
+
+ Parameters:
+ backlinks: The list of backlinks.
+
+ Returns:
+ A tree of backlinks.
+ """
+ return _compact_tree(_tree(backlink.crumbs for backlink in backlinks))
diff --git a/src/mkdocstrings_handlers/python/config.py b/src/mkdocstrings_handlers/python/config.py
index af2ac7f7..5edab089 100644
--- a/src/mkdocstrings_handlers/python/config.py
+++ b/src/mkdocstrings_handlers/python/config.py
@@ -1,1023 +1,17 @@
-"""Configuration and options dataclasses."""
+"""Deprecated. Import from `mkdocstrings_handlers.python` directly."""
-from __future__ import annotations
+# YORE: Bump 2: Remove file.
-import re
-import sys
-from dataclasses import field, fields
-from typing import TYPE_CHECKING, Annotated, Any, Literal
+import warnings
+from typing import Any
-from mkdocstrings import get_logger
+from mkdocstrings_handlers.python._internal import config
-# YORE: EOL 3.10: Replace block with line 2.
-if sys.version_info >= (3, 11):
- from typing import Self
-else:
- from typing_extensions import Self
-
-logger = get_logger(__name__)
-
-
-try:
- # When Pydantic is available, use it to validate options (done automatically).
- # Users can therefore opt into validation by installing Pydantic in development/CI.
- # When building the docs to deploy them, Pydantic is not required anymore.
-
- # When building our own docs, Pydantic is always installed (see `docs` group in `pyproject.toml`)
- # to allow automatic generation of a JSON Schema. The JSON Schema is then referenced by mkdocstrings,
- # which is itself referenced by mkdocs-material's schema system. For example in VSCode:
- #
- # "yaml.schemas": {
- # "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml"
- # }
- import pydantic
-
- if getattr(pydantic, "__version__", "1.").startswith("1."):
- raise ImportError # noqa: TRY301
-
- if sys.version_info < (3, 10):
- try:
- import eval_type_backport # noqa: F401
- except ImportError:
- logger.debug(
- "Pydantic needs the `eval-type-backport` package to be installed "
- "for modern type syntax to work on Python 3.9. "
- "Deactivating Pydantic validation for Python handler options.",
- )
- raise
-
- from inspect import cleandoc
-
- from pydantic import Field as BaseField
- from pydantic.dataclasses import dataclass
-
- _base_url = "https://mkdocstrings.github.io/python/usage"
-
- def Field( # noqa: N802, D103
- *args: Any,
- description: str,
- group: Literal["general", "headings", "members", "docstrings", "signatures"] | None = None,
- parent: str | None = None,
- **kwargs: Any,
- ) -> None:
- def _add_markdown_description(schema: dict[str, Any]) -> None:
- url = f"{_base_url}/{f'configuration/{group}/' if group else ''}#{parent or schema['title']}"
- schema["markdownDescription"] = f"[DOCUMENTATION]({url})\n\n{schema['description']}"
-
- return BaseField(
- *args,
- description=cleandoc(description),
- field_title_generator=lambda name, _: name,
- json_schema_extra=_add_markdown_description,
- **kwargs,
- )
-except ImportError:
- from dataclasses import dataclass # type: ignore[no-redef]
-
- def Field(*args: Any, **kwargs: Any) -> None: # type: ignore[misc] # noqa: D103, N802
- pass
-
-
-if TYPE_CHECKING:
- from collections.abc import MutableMapping
-
-
-# YORE: EOL 3.9: Remove block.
-_dataclass_options = {"frozen": True}
-if sys.version_info >= (3, 10):
- _dataclass_options["kw_only"] = True
-
-
-# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
-@dataclass(**_dataclass_options) # type: ignore[call-overload]
-class GoogleStyleOptions:
- """Google style docstring options."""
-
- ignore_init_summary: Annotated[
- bool,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="Whether to ignore the summary in `__init__` methods' docstrings.",
- ),
- ] = False
-
- returns_multiple_items: Annotated[
- bool,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="""Whether to parse multiple items in `Yields` and `Returns` sections.
-
- When true, each item's continuation lines must be indented.
- When false (single item), no further indentation is required.
- """,
- ),
- ] = True
-
- returns_named_value: Annotated[
- bool,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="""Whether to parse `Yields` and `Returns` section items as name and description, rather than type and description.
-
- When true, type must be wrapped in parentheses: `(int): Description.`. Names are optional: `name (int): Description.`.
- When false, parentheses are optional but the items cannot be named: `int: Description`.
- """,
- ),
- ] = True
-
- returns_type_in_property_summary: Annotated[
- bool,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="Whether to parse the return type of properties at the beginning of their summary: `str: Summary of the property`.",
- ),
- ] = False
-
- receives_multiple_items: Annotated[
- bool,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="""Whether to parse multiple items in `Receives` sections.
-
- When true, each item's continuation lines must be indented.
- When false (single item), no further indentation is required.
- """,
- ),
- ] = True
-
- receives_named_value: Annotated[
- bool,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="""Whether to parse `Receives` section items as name and description, rather than type and description.
-
- When true, type must be wrapped in parentheses: `(int): Description.`. Names are optional: `name (int): Description.`.
- When false, parentheses are optional but the items cannot be named: `int: Description`.
- """,
- ),
- ] = True
-
- trim_doctest_flags: Annotated[
- bool,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="Whether to remove doctest flags from Python example blocks.",
- ),
- ] = True
-
- warn_unknown_params: Annotated[
- bool,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="Warn about documented parameters not appearing in the signature.",
- ),
- ] = True
-
-
-# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
-@dataclass(**_dataclass_options) # type: ignore[call-overload]
-class NumpyStyleOptions:
- """Numpy style docstring options."""
-
- ignore_init_summary: Annotated[
- bool,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="Whether to ignore the summary in `__init__` methods' docstrings.",
- ),
- ] = False
-
- trim_doctest_flags: Annotated[
- bool,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="Whether to remove doctest flags from Python example blocks.",
- ),
- ] = True
-
- warn_unknown_params: Annotated[
- bool,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="Warn about documented parameters not appearing in the signature.",
- ),
- ] = True
-
-
-# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
-@dataclass(**_dataclass_options) # type: ignore[call-overload]
-class SphinxStyleOptions:
- """Sphinx style docstring options."""
-
-
-# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
-@dataclass(**_dataclass_options) # type: ignore[call-overload]
-class PerStyleOptions:
- """Per style options."""
-
- google: Annotated[
- GoogleStyleOptions,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="Google-style options.",
- ),
- ] = field(default_factory=GoogleStyleOptions)
-
- numpy: Annotated[
- NumpyStyleOptions,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="Numpydoc-style options.",
- ),
- ] = field(default_factory=NumpyStyleOptions)
-
- sphinx: Annotated[
- SphinxStyleOptions,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="Sphinx-style options.",
- ),
- ] = field(default_factory=SphinxStyleOptions)
-
- @classmethod
- def from_data(cls, **data: Any) -> Self:
- """Create an instance from a dictionary."""
- if "google" in data:
- data["google"] = GoogleStyleOptions(**data["google"])
- if "numpy" in data:
- data["numpy"] = NumpyStyleOptions(**data["numpy"])
- if "sphinx" in data:
- data["sphinx"] = SphinxStyleOptions(**data["sphinx"])
- return cls(**data)
-
-
-# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
-@dataclass(**_dataclass_options) # type: ignore[call-overload]
-class AutoStyleOptions:
- """Auto style docstring options."""
-
- method: Annotated[
- Literal["heuristics", "max_sections"],
- Field(
- group="docstrings",
- parent="docstring_options",
- description="The method to use to determine the docstring style.",
- ),
- ] = "heuristics"
-
- style_order: Annotated[
- list[str],
- Field(
- group="docstrings",
- parent="docstring_options",
- description="The order of the docstring styles to try.",
- ),
- ] = field(default_factory=lambda: ["sphinx", "google", "numpy"])
-
- default: Annotated[
- str | None,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="The default docstring style to use if no other style is detected.",
- ),
- ] = None
-
- per_style_options: Annotated[
- PerStyleOptions,
- Field(
- group="docstrings",
- parent="docstring_options",
- description="Per-style options.",
- ),
- ] = field(default_factory=PerStyleOptions)
-
- @classmethod
- def from_data(cls, **data: Any) -> Self:
- """Create an instance from a dictionary."""
- if "per_style_options" in data:
- data["per_style_options"] = PerStyleOptions.from_data(**data["per_style_options"])
- return cls(**data)
-
-
-# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
-@dataclass(**_dataclass_options) # type: ignore[call-overload]
-class SummaryOption:
- """Summary option."""
-
- attributes: Annotated[
- bool,
- Field(
- group="members",
- parent="summary",
- description="Whether to render summaries of attributes.",
- ),
- ] = False
-
- functions: Annotated[
- bool,
- Field(
- group="members",
- parent="summary",
- description="Whether to render summaries of functions (methods).",
- ),
- ] = False
-
- classes: Annotated[
- bool,
- Field(
- group="members",
- parent="summary",
- description="Whether to render summaries of classes.",
- ),
- ] = False
-
- modules: Annotated[
- bool,
- Field(
- group="members",
- parent="summary",
- description="Whether to render summaries of modules.",
- ),
- ] = False
-
-
-# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
-@dataclass(**_dataclass_options) # type: ignore[call-overload]
-class PythonInputOptions:
- """Accepted input options."""
-
- allow_inspection: Annotated[
- bool,
- Field(
- group="general",
- description="Whether to allow inspecting modules when visiting them is not possible.",
- ),
- ] = True
-
- force_inspection: Annotated[
- bool,
- Field(
- group="general",
- description="Whether to force using dynamic analysis when loading data.",
- ),
- ] = False
-
- annotations_path: Annotated[
- Literal["brief", "source", "full"],
- Field(
- group="signatures",
- description="The verbosity for annotations path: `brief` (recommended), `source` (as written in the source), or `full`.",
- ),
- ] = "brief"
-
- backlinks: Annotated[
- Literal["flat", "tree", False],
- Field(
- group="general",
- description="Whether to render backlinks, and how.",
- ),
- ] = False
-
- docstring_options: Annotated[
- GoogleStyleOptions | NumpyStyleOptions | SphinxStyleOptions | AutoStyleOptions | None,
- Field(
- group="docstrings",
- description="""The options for the docstring parser.
-
- See [docstring parsers](https://mkdocstrings.github.io/griffe/reference/docstrings/) and their options in Griffe docs.
- """,
- ),
- ] = None
-
- docstring_section_style: Annotated[
- Literal["table", "list", "spacy"],
- Field(
- group="docstrings",
- description="The style used to render docstring sections.",
- ),
- ] = "table"
-
- docstring_style: Annotated[
- Literal["auto", "google", "numpy", "sphinx"] | None,
- Field(
- group="docstrings",
- description="The docstring style to use: `auto`, `google`, `numpy`, `sphinx`, or `None`.",
- ),
- ] = "google"
-
- extensions: Annotated[
- list[str | dict[str, Any]],
- Field(
- group="general",
- description="A list of Griffe extensions to load.",
- ),
- ] = field(default_factory=list)
-
- filters: Annotated[
- list[str],
- Field(
- group="members",
- description="""A list of filters applied to filter objects based on their name.
-
- A filter starting with `!` will exclude matching objects instead of including them.
- The `members` option takes precedence over `filters` (filters will still be applied recursively
- to lower members in the hierarchy).
- """,
- ),
- ] = field(default_factory=lambda: ["!^_[^_]"])
-
- find_stubs_package: Annotated[
- bool,
- Field(
- group="general",
- description="Whether to load stubs package (package-stubs) when extracting docstrings.",
- ),
- ] = False
-
- group_by_category: Annotated[
- bool,
- Field(
- group="members",
- description="Group the object's children by categories: attributes, classes, functions, and modules.",
- ),
- ] = True
-
- heading: Annotated[
- str,
- Field(
- group="headings",
- description="A custom string to override the autogenerated heading of the root object.",
- ),
- ] = ""
-
- heading_level: Annotated[
- int,
- Field(
- group="headings",
- description="The initial heading level to use.",
- ),
- ] = 2
-
- inherited_members: Annotated[
- bool | list[str],
- Field(
- group="members",
- description="""A boolean, or an explicit list of inherited members to render.
-
- If true, select all inherited members, which can then be filtered with `members`.
- If false or empty list, do not select any inherited member.
- """,
- ),
- ] = False
-
- line_length: Annotated[
- int,
- Field(
- group="signatures",
- description="Maximum line length when formatting code/signatures.",
- ),
- ] = 60
-
- members: Annotated[
- list[str] | bool | None,
- Field(
- group="members",
- description="""A boolean, or an explicit list of members to render.
-
- If true, select all members without further filtering.
- If false or empty list, do not render members.
- If none, select all members and apply further filtering with filters and docstrings.
- """,
- ),
- ] = None
-
- members_order: Annotated[
- Literal["alphabetical", "source"],
- Field(
- group="members",
- description="""The members ordering to use.
-
- - `alphabetical`: order by the members names,
- - `source`: order members as they appear in the source file.
- """,
- ),
- ] = "alphabetical"
-
- merge_init_into_class: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to merge the `__init__` method into the class' signature and docstring.",
- ),
- ] = False
-
- modernize_annotations: Annotated[
- bool,
- Field(
- group="signatures",
- description="Whether to modernize annotations, for example `Optional[str]` into `str | None`.",
- ),
- ] = False
-
- parameter_headings: Annotated[
- bool,
- Field(
- group="headings",
- description="Whether to render headings for parameters (therefore showing parameters in the ToC).",
- ),
- ] = False
-
- preload_modules: Annotated[
- list[str],
- Field(
- group="general",
- description="""Pre-load modules that are not specified directly in autodoc instructions (`::: identifier`).
-
- It is useful when you want to render documentation for a particular member of an object,
- and this member is imported from another package than its parent.
-
- For an imported member to be rendered, you need to add it to the `__all__` attribute
- of the importing module.
-
- The modules must be listed as an array of strings.
- """,
- ),
- ] = field(default_factory=list)
-
- relative_crossrefs: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to enable the relative crossref syntax.",
- ),
- ] = False
-
- scoped_crossrefs: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to enable the scoped crossref ability.",
- ),
- ] = False
-
- show_overloads: Annotated[
- bool,
- Field(
- group="signatures",
- description="Show the overloads of a function or method.",
- ),
- ] = True
-
- separate_signature: Annotated[
- bool,
- Field(
- group="signatures",
- description="""Whether to put the whole signature in a code block below the heading.
-
- If Black or Ruff are installed, the signature is also formatted using them.
- """,
- ),
- ] = False
-
- show_bases: Annotated[
- bool,
- Field(
- group="general",
- description="Show the base classes of a class.",
- ),
- ] = True
-
- show_category_heading: Annotated[
- bool,
- Field(
- group="headings",
- description="When grouped by categories, show a heading for each category.",
- ),
- ] = False
-
- show_docstring_attributes: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to display the 'Attributes' section in the object's docstring.",
- ),
- ] = True
-
- show_docstring_classes: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to display the 'Classes' section in the object's docstring.",
- ),
- ] = True
-
- show_docstring_description: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to display the textual block (including admonitions) in the object's docstring.",
- ),
- ] = True
-
- show_docstring_examples: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to display the 'Examples' section in the object's docstring.",
- ),
- ] = True
-
- show_docstring_functions: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to display the 'Functions' or 'Methods' sections in the object's docstring.",
- ),
- ] = True
-
- show_docstring_modules: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to display the 'Modules' section in the object's docstring.",
- ),
- ] = True
-
- show_docstring_other_parameters: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to display the 'Other Parameters' section in the object's docstring.",
- ),
- ] = True
-
- show_docstring_parameters: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to display the 'Parameters' section in the object's docstring.",
- ),
- ] = True
-
- show_docstring_raises: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to display the 'Raises' section in the object's docstring.",
- ),
- ] = True
-
- show_docstring_receives: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to display the 'Receives' section in the object's docstring.",
- ),
- ] = True
-
- show_docstring_returns: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to display the 'Returns' section in the object's docstring.",
- ),
- ] = True
-
- show_docstring_warns: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to display the 'Warns' section in the object's docstring.",
- ),
- ] = True
-
- show_docstring_yields: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to display the 'Yields' section in the object's docstring.",
- ),
- ] = True
-
- show_if_no_docstring: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Show the object heading even if it has no docstring or children with docstrings.",
- ),
- ] = False
-
- show_inheritance_diagram: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Show the inheritance diagram of a class using Mermaid.",
- ),
- ] = False
-
- show_labels: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Whether to show labels of the members.",
- ),
- ] = True
-
- show_object_full_path: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Show the full Python path of every object.",
- ),
- ] = False
-
- show_root_full_path: Annotated[
- bool,
- Field(
- group="docstrings",
- description="Show the full Python path for the root object heading.",
- ),
- ] = True
-
- show_root_heading: Annotated[
- bool,
- Field(
- group="headings",
- description="""Show the heading of the object at the root of the documentation tree.
-
- The root object is the object referenced by the identifier after `:::`.
- """,
- ),
- ] = False
-
- show_root_members_full_path: Annotated[
- bool,
- Field(
- group="headings",
- description="Show the full Python path of the root members.",
- ),
- ] = False
-
- show_root_toc_entry: Annotated[
- bool,
- Field(
- group="headings",
- description="If the root heading is not shown, at least add a ToC entry for it.",
- ),
- ] = True
-
- show_signature_annotations: Annotated[
- bool,
- Field(
- group="signatures",
- description="Show the type annotations in methods and functions signatures.",
- ),
- ] = False
-
- show_signature: Annotated[
- bool,
- Field(
- group="signatures",
- description="Show methods and functions signatures.",
- ),
- ] = True
-
- show_source: Annotated[
- bool,
- Field(
- group="general",
- description="Show the source code of this object.",
- ),
- ] = True
-
- show_submodules: Annotated[
- bool,
- Field(
- group="members",
- description="When rendering a module, show its submodules recursively.",
- ),
- ] = False
-
- show_symbol_type_heading: Annotated[
- bool,
- Field(
- group="headings",
- description="Show the symbol type in headings (e.g. mod, class, meth, func and attr).",
- ),
- ] = False
-
- show_symbol_type_toc: Annotated[
- bool,
- Field(
- group="headings",
- description="Show the symbol type in the Table of Contents (e.g. mod, class, methd, func and attr).",
- ),
- ] = False
-
- signature_crossrefs: Annotated[
- bool,
- Field(
- group="signatures",
- description="Whether to render cross-references for type annotations in signatures.",
- ),
- ] = False
-
- summary: Annotated[
- bool | SummaryOption,
- Field(
- group="members",
- description="Whether to render summaries of modules, classes, functions (methods) and attributes.",
- ),
- ] = field(default_factory=SummaryOption)
-
- toc_label: Annotated[
- str,
- Field(
- group="headings",
- description="A custom string to override the autogenerated toc label of the root object.",
- ),
- ] = ""
-
- unwrap_annotated: Annotated[
- bool,
- Field(
- group="signatures",
- description="Whether to unwrap `Annotated` types to show only the type without the annotations.",
- ),
- ] = False
-
- extra: Annotated[
- dict[str, Any],
- Field(
- group="general",
- description="Extra options.",
- ),
- ] = field(default_factory=dict)
-
- @classmethod
- def _extract_extra(cls, data: dict[str, Any]) -> tuple[dict[str, Any], dict[str, Any]]:
- field_names = {field.name for field in fields(cls)}
- copy = data.copy()
- return {name: copy.pop(name) for name in data if name not in field_names}, copy
-
- @classmethod
- def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
- """Coerce data."""
- if "docstring_options" in data:
- docstring_style = data.get("docstring_style", "google")
- docstring_options = data["docstring_options"]
- if docstring_options is not None:
- if docstring_style == "auto":
- docstring_options = AutoStyleOptions.from_data(**docstring_options)
- elif docstring_style == "google":
- docstring_options = GoogleStyleOptions(**docstring_options)
- elif docstring_style == "numpy":
- docstring_options = NumpyStyleOptions(**docstring_options)
- elif docstring_style == "sphinx":
- docstring_options = SphinxStyleOptions(**docstring_options)
- data["docstring_options"] = docstring_options
- if "summary" in data:
- summary = data["summary"]
- if summary is True:
- summary = SummaryOption(attributes=True, functions=True, classes=True, modules=True)
- elif summary is False:
- summary = SummaryOption(attributes=False, functions=False, classes=False, modules=False)
- else:
- summary = SummaryOption(**summary)
- data["summary"] = summary
- return data
-
- @classmethod
- def from_data(cls, **data: Any) -> Self:
- """Create an instance from a dictionary."""
- return cls(**cls.coerce(**data))
-
-
-# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
-@dataclass(**_dataclass_options) # type: ignore[call-overload]
-class PythonOptions(PythonInputOptions): # type: ignore[override,unused-ignore]
- """Final options passed as template context."""
-
- filters: list[tuple[re.Pattern, bool]] = field(default_factory=list) # type: ignore[assignment]
- """A list of filters applied to filter objects based on their name."""
-
- summary: SummaryOption = field(default_factory=SummaryOption)
- """Whether to render summaries of modules, classes, functions (methods) and attributes."""
-
- @classmethod
- def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
- """Create an instance from a dictionary."""
- if "filters" in data:
- data["filters"] = [
- (re.compile(filtr.lstrip("!")), filtr.startswith("!")) for filtr in data["filters"] or ()
- ]
- return super().coerce(**data)
-
-
-# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
-@dataclass(**_dataclass_options) # type: ignore[call-overload]
-class Inventory:
- """An inventory."""
-
- url: Annotated[
- str,
- Field(
- parent="inventories",
- description="The URL of the inventory.",
- ),
- ]
-
- base: Annotated[
- str | None,
- Field(
- parent="inventories",
- description="The base URL of the inventory.",
- ),
- ] = None
-
- domains: Annotated[
- list[str],
- Field(
- parent="inventories",
- description="The domains to load from the inventory.",
- ),
- ] = field(default_factory=lambda: ["py"])
-
- @property
- def _config(self) -> dict[str, Any]:
- return {"base": self.base, "domains": self.domains}
-
-
-# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
-@dataclass(**_dataclass_options) # type: ignore[call-overload]
-class PythonInputConfig:
- """Python handler configuration."""
-
- inventories: Annotated[
- list[str | Inventory],
- Field(description="The inventories to load."),
- ] = field(default_factory=list)
-
- paths: Annotated[
- list[str],
- Field(description="The paths in which to search for Python packages."),
- ] = field(default_factory=lambda: ["."])
-
- load_external_modules: Annotated[
- bool | None,
- Field(description="Whether to always load external modules/packages."),
- ] = None
-
- options: Annotated[
- PythonInputOptions,
- Field(description="Configuration options for collecting and rendering objects."),
- ] = field(default_factory=PythonInputOptions)
-
- locale: Annotated[
- str | None,
- Field(description="The locale to use when translating template strings."),
- ] = None
-
- @classmethod
- def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
- """Coerce data."""
- return data
-
- @classmethod
- def from_data(cls, **data: Any) -> Self:
- """Create an instance from a dictionary."""
- return cls(**cls.coerce(**data))
-
-
-# YORE: EOL 3.9: Replace `**_dataclass_options` with `frozen=True, kw_only=True` within line.
-@dataclass(**_dataclass_options) # type: ignore[call-overload]
-class PythonConfig(PythonInputConfig): # type: ignore[override,unused-ignore]
- """Python handler configuration."""
-
- inventories: list[Inventory] = field(default_factory=list) # type: ignore[assignment]
- options: dict[str, Any] = field(default_factory=dict) # type: ignore[assignment]
-
- @classmethod
- def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
- """Coerce data."""
- if "inventories" in data:
- data["inventories"] = [
- Inventory(url=inv) if isinstance(inv, str) else Inventory(**inv) for inv in data["inventories"]
- ]
- return data
+def __getattr__(name: str) -> Any:
+ warnings.warn(
+ "Importing from `mkdocstrings_handlers.python.config` is deprecated. Import from `mkdocstrings_handlers.python` directly.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return getattr(config, name)
diff --git a/src/mkdocstrings_handlers/python/handler.py b/src/mkdocstrings_handlers/python/handler.py
index 69f228f1..5b334860 100644
--- a/src/mkdocstrings_handlers/python/handler.py
+++ b/src/mkdocstrings_handlers/python/handler.py
@@ -1,375 +1,17 @@
-"""This module implements a handler for the Python language."""
+"""Deprecated. Import from `mkdocstrings_handlers.python` directly."""
-from __future__ import annotations
+# YORE: Bump 2: Remove file.
-import glob
-import os
-import posixpath
-import sys
-from contextlib import suppress
-from dataclasses import asdict
-from pathlib import Path
-from typing import TYPE_CHECKING, Any, BinaryIO, ClassVar
-from warnings import warn
+import warnings
+from typing import Any
-from griffe import (
- AliasResolutionError,
- GriffeLoader,
- LinesCollection,
- ModulesCollection,
- Parser,
- load_extensions,
- patch_loggers,
-)
-from mkdocs.exceptions import PluginError
-from mkdocstrings import BaseHandler, CollectionError, CollectorItem, HandlerOptions, Inventory, get_logger
+from mkdocstrings_handlers.python._internal import handler
-from mkdocstrings_handlers.python import rendering
-from mkdocstrings_handlers.python.config import PythonConfig, PythonOptions
-if TYPE_CHECKING:
- from collections.abc import Iterator, Mapping, MutableMapping, Sequence
-
- from mkdocs.config.defaults import MkDocsConfig
-
-
-if sys.version_info >= (3, 11):
- from contextlib import chdir
-else:
- # TODO: remove once support for Python 3.10 is dropped
- from contextlib import contextmanager
-
- @contextmanager
- def chdir(path: str) -> Iterator[None]: # noqa: D103
- old_wd = os.getcwd()
- os.chdir(path)
- try:
- yield
- finally:
- os.chdir(old_wd)
-
-
-logger = get_logger(__name__)
-
-patch_loggers(get_logger)
-
-
-def _warn_extra_options(names: Sequence[str]) -> None:
- warn(
- "Passing extra options directly under `options` is deprecated. "
- "Instead, pass them under `options.extra`, and update your templates. "
- f"Current extra (unrecognized) options: {', '.join(sorted(names))}",
+def __getattr__(name: str) -> Any:
+ warnings.warn(
+ "Importing from `mkdocstrings_handlers.python.handler` is deprecated. Import from `mkdocstrings_handlers.python` directly.",
DeprecationWarning,
- stacklevel=3,
- )
-
-
-class PythonHandler(BaseHandler):
- """The Python handler class."""
-
- name: ClassVar[str] = "python"
- """The handler's name."""
-
- domain: ClassVar[str] = "py"
- """The cross-documentation domain/language for this handler."""
-
- enable_inventory: ClassVar[bool] = True
- """Whether this handler is interested in enabling the creation of the `objects.inv` Sphinx inventory file."""
-
- fallback_theme: ClassVar[str] = "material"
- """The fallback theme."""
-
- def __init__(self, config: PythonConfig, base_dir: Path, **kwargs: Any) -> None:
- """Initialize the handler.
-
- Parameters:
- config: The handler configuration.
- base_dir: The base directory of the project.
- **kwargs: Arguments passed to the parent constructor.
- """
- super().__init__(**kwargs)
-
- self.config = config
- self.base_dir = base_dir
-
- # YORE: Bump 2: Replace block with `self.global_options = config.options`.
- global_extra, global_options = PythonOptions._extract_extra(config.options)
- if global_extra:
- _warn_extra_options(global_extra.keys()) # type: ignore[arg-type]
- self._global_extra = global_extra
- self.global_options = global_options
-
- # Warn if user overrides base templates.
- if self.custom_templates:
- for theme_dir in base_dir.joinpath(self.custom_templates, "python").iterdir():
- if theme_dir.joinpath("_base").is_dir():
- logger.warning(
- f"Overriding base template '{theme_dir.name}/_base/.html.jinja' is not supported, "
- f"override '{theme_dir.name}/.html.jinja' instead",
- )
-
- paths = config.paths or []
-
- # Expand paths with glob patterns.
- with chdir(str(base_dir)):
- resolved_globs = [glob.glob(path) for path in paths]
- paths = [path for glob_list in resolved_globs for path in glob_list]
-
- # By default, add the base directory to the search paths.
- if not paths:
- paths.append(str(base_dir))
-
- # Initialize search paths from `sys.path`, eliminating empty paths.
- search_paths = [path for path in sys.path if path]
-
- for path in reversed(paths):
- # If it's not absolute, make path relative to the config file path, then make it absolute.
- if not os.path.isabs(path):
- path = os.path.abspath(base_dir / path) # noqa: PLW2901
- # Remove pre-listed paths.
- if path in search_paths:
- search_paths.remove(path)
- # Give precedence to user-provided paths.
- search_paths.insert(0, path)
-
- self._paths = search_paths
- self._modules_collection: ModulesCollection = ModulesCollection()
- self._lines_collection: LinesCollection = LinesCollection()
-
- def get_inventory_urls(self) -> list[tuple[str, dict[str, Any]]]:
- """Return the URLs of the inventory files to download."""
- return [(inv.url, inv._config) for inv in self.config.inventories]
-
- @staticmethod
- def load_inventory(
- in_file: BinaryIO,
- url: str,
- base_url: str | None = None,
- domains: list[str] | None = None,
- **kwargs: Any, # noqa: ARG004
- ) -> Iterator[tuple[str, str]]:
- """Yield items and their URLs from an inventory file streamed from `in_file`.
-
- This implements mkdocstrings' `load_inventory` "protocol" (see [`mkdocstrings.plugin`][]).
-
- Arguments:
- in_file: The binary file-like object to read the inventory from.
- url: The URL that this file is being streamed from (used to guess `base_url`).
- base_url: The URL that this inventory's sub-paths are relative to.
- domains: A list of domain strings to filter the inventory by, when not passed, "py" will be used.
- **kwargs: Ignore additional arguments passed from the config.
-
- Yields:
- Tuples of (item identifier, item URL).
- """
- domains = domains or ["py"]
- if base_url is None:
- base_url = posixpath.dirname(url)
-
- for item in Inventory.parse_sphinx(in_file, domain_filter=domains).values():
- yield item.name, posixpath.join(base_url, item.uri)
-
- def get_options(self, local_options: Mapping[str, Any]) -> HandlerOptions:
- """Get combined default, global and local options.
-
- Arguments:
- local_options: The local options.
-
- Returns:
- The combined options.
- """
- # YORE: Bump 2: Remove block.
- local_extra, local_options = PythonOptions._extract_extra(local_options) # type: ignore[arg-type]
- if local_extra:
- _warn_extra_options(local_extra.keys()) # type: ignore[arg-type]
- unknown_extra = self._global_extra | local_extra
-
- extra = {**self.global_options.get("extra", {}), **local_options.get("extra", {})}
- options = {**self.global_options, **local_options, "extra": extra}
- try:
- # YORE: Bump 2: Replace `opts =` with `return` within line.
- opts = PythonOptions.from_data(**options)
- except Exception as error:
- raise PluginError(f"Invalid options: {error}") from error
-
- # YORE: Bump 2: Remove block.
- for key, value in unknown_extra.items():
- object.__setattr__(opts, key, value)
- return opts
-
- def collect(self, identifier: str, options: PythonOptions) -> CollectorItem: # noqa: D102
- module_name = identifier.split(".", 1)[0]
- unknown_module = module_name not in self._modules_collection
- reapply = True
- if options == {}:
- if unknown_module:
- raise CollectionError("Not loading additional modules during fallback")
- options = self.get_options({})
- reapply = False
-
- parser_name = options.docstring_style
- parser = parser_name and Parser(parser_name)
- parser_options = options.docstring_options and asdict(options.docstring_options)
-
- if unknown_module:
- extensions = self.normalize_extension_paths(options.extensions)
- loader = GriffeLoader(
- extensions=load_extensions(*extensions),
- search_paths=self._paths,
- docstring_parser=parser,
- docstring_options=parser_options, # type: ignore[arg-type]
- modules_collection=self._modules_collection,
- lines_collection=self._lines_collection,
- allow_inspection=options.allow_inspection,
- force_inspection=options.force_inspection,
- )
- try:
- for pre_loaded_module in options.preload_modules:
- if pre_loaded_module not in self._modules_collection:
- loader.load(
- pre_loaded_module,
- try_relative_path=False,
- find_stubs_package=options.find_stubs_package,
- )
- loader.load(
- module_name,
- try_relative_path=False,
- find_stubs_package=options.find_stubs_package,
- )
- except ImportError as error:
- raise CollectionError(str(error)) from error
- unresolved, iterations = loader.resolve_aliases(
- implicit=False,
- external=self.config.load_external_modules,
- )
- if unresolved:
- logger.debug(f"{len(unresolved)} aliases were still unresolved after {iterations} iterations")
- logger.debug(f"Unresolved aliases: {', '.join(sorted(unresolved))}")
-
- try:
- doc_object = self._modules_collection[identifier]
- except KeyError as error:
- raise CollectionError(f"{identifier} could not be found") from error
- except AliasResolutionError as error:
- raise CollectionError(str(error)) from error
-
- if not unknown_module and reapply:
- with suppress(AliasResolutionError):
- if doc_object.docstring is not None:
- doc_object.docstring.parser = parser
- doc_object.docstring.parser_options = parser_options or {}
-
- return doc_object
-
- def render(self, data: CollectorItem, options: PythonOptions) -> str: # noqa: D102 (ignore missing docstring)
- template_name = rendering.do_get_template(self.env, data)
- template = self.env.get_template(template_name)
-
- return template.render(
- **{
- "config": options,
- data.kind.value: data,
- # Heading level is a "state" variable, that will change at each step
- # of the rendering recursion. Therefore, it's easier to use it as a plain value
- # than as an item in a dictionary.
- "heading_level": options.heading_level,
- "root": True,
- "locale": self.config.locale,
- },
- )
-
- def update_env(self, config: Any) -> None: # noqa: ARG002
- """Update the Jinja environment with custom filters and tests.
-
- Parameters:
- config: The SSG configuration.
- """
- self.env.trim_blocks = True
- self.env.lstrip_blocks = True
- self.env.keep_trailing_newline = False
- self.env.filters["split_path"] = rendering.do_split_path
- self.env.filters["crossref"] = rendering.do_crossref
- self.env.filters["multi_crossref"] = rendering.do_multi_crossref
- self.env.filters["order_members"] = rendering.do_order_members
- self.env.filters["format_code"] = rendering.do_format_code
- self.env.filters["format_signature"] = rendering.do_format_signature
- self.env.filters["format_attribute"] = rendering.do_format_attribute
- self.env.filters["filter_objects"] = rendering.do_filter_objects
- self.env.filters["stash_crossref"] = rendering.do_stash_crossref
- self.env.filters["get_template"] = rendering.do_get_template
- self.env.filters["as_attributes_section"] = rendering.do_as_attributes_section
- self.env.filters["as_functions_section"] = rendering.do_as_functions_section
- self.env.filters["as_classes_section"] = rendering.do_as_classes_section
- self.env.filters["as_modules_section"] = rendering.do_as_modules_section
- self.env.filters["backlink_tree"] = rendering.do_backlink_tree
- self.env.globals["AutorefsHook"] = rendering.AutorefsHook
- self.env.tests["existing_template"] = lambda template_name: template_name in self.env.list_templates()
-
- def get_aliases(self, identifier: str) -> tuple[str, ...]: # noqa: D102 (ignore missing docstring)
- if "(" in identifier:
- identifier, parameter = identifier.split("(", 1)
- parameter.removesuffix(")")
- else:
- parameter = ""
- try:
- data = self._modules_collection[identifier]
- except (KeyError, AliasResolutionError):
- return ()
- aliases = [data.path]
- try:
- for alias in [data.canonical_path, *data.aliases]:
- if alias not in aliases:
- aliases.append(alias)
- except AliasResolutionError:
- pass
- if parameter:
- return tuple(f"{alias}({parameter})" for alias in aliases)
- return tuple(aliases)
-
- def normalize_extension_paths(self, extensions: Sequence) -> Sequence:
- """Resolve extension paths relative to config file."""
- normalized = []
-
- for ext in extensions:
- if isinstance(ext, dict):
- pth, options = next(iter(ext.items()))
- pth = str(pth)
- else:
- pth = str(ext)
- options = None
-
- if pth.endswith(".py") or ".py:" in pth or "/" in pth or "\\" in pth:
- # This is a system path. Normalize it, make it absolute relative to config file path.
- pth = os.path.abspath(self.base_dir / pth)
-
- if options is not None:
- normalized.append({pth: options})
- else:
- normalized.append(pth)
-
- return normalized
-
-
-def get_handler(
- handler_config: MutableMapping[str, Any],
- tool_config: MkDocsConfig,
- **kwargs: Any,
-) -> PythonHandler:
- """Simply return an instance of `PythonHandler`.
-
- Arguments:
- handler_config: The handler configuration.
- tool_config: The tool (SSG) configuration.
-
- Returns:
- An instance of `PythonHandler`.
- """
- base_dir = Path(tool_config.config_file_path or "./mkdocs.yml").parent
- if "inventories" not in handler_config and "import" in handler_config:
- warn("The 'import' key is renamed 'inventories' for the Python handler", FutureWarning, stacklevel=1)
- handler_config["inventories"] = handler_config.pop("import", [])
- return PythonHandler(
- config=PythonConfig.from_data(**handler_config),
- base_dir=base_dir,
- **kwargs,
+ stacklevel=2,
)
+ return getattr(handler, name)
diff --git a/src/mkdocstrings_handlers/python/rendering.py b/src/mkdocstrings_handlers/python/rendering.py
index 0a670b90..5cd4d200 100644
--- a/src/mkdocstrings_handlers/python/rendering.py
+++ b/src/mkdocstrings_handlers/python/rendering.py
@@ -1,775 +1,17 @@
-"""This module implements rendering utilities."""
+"""Deprecated. Import from `mkdocstrings_handlers.python` directly."""
-from __future__ import annotations
+# YORE: Bump 2: Remove file.
-import random
-import re
-import string
-import subprocess
-import sys
import warnings
-from collections import defaultdict
-from dataclasses import replace
-from functools import lru_cache
-from pathlib import Path
-from re import Match, Pattern
-from typing import TYPE_CHECKING, Any, Callable, ClassVar, Literal, TypeVar
+from typing import Any
-from griffe import (
- Alias,
- DocstringAttribute,
- DocstringClass,
- DocstringFunction,
- DocstringModule,
- DocstringSectionAttributes,
- DocstringSectionClasses,
- DocstringSectionFunctions,
- DocstringSectionModules,
- Object,
-)
-from jinja2 import TemplateNotFound, pass_context, pass_environment
-from markupsafe import Markup
-from mkdocs_autorefs import AutorefsHookInterface, Backlink, BacklinkCrumb
-from mkdocstrings import get_logger
+from mkdocstrings_handlers.python._internal import rendering
-if TYPE_CHECKING:
- from collections.abc import Iterable, Iterator, Sequence
- from griffe import Attribute, Class, Function, Module
- from jinja2 import Environment, Template
- from jinja2.runtime import Context
- from mkdocstrings import CollectorItem
-
-logger = get_logger(__name__)
-
-
-def _sort_key_alphabetical(item: CollectorItem) -> Any:
- # chr(sys.maxunicode) is a string that contains the final unicode
- # character, so if 'name' isn't found on the object, the item will go to
- # the end of the list.
- return item.name or chr(sys.maxunicode)
-
-
-def _sort_key_source(item: CollectorItem) -> Any:
- # if 'lineno' is none, the item will go to the start of the list.
- if item.is_alias:
- return item.alias_lineno if item.alias_lineno is not None else -1
- return item.lineno if item.lineno is not None else -1
-
-
-Order = Literal["alphabetical", "source"]
-order_map = {
- "alphabetical": _sort_key_alphabetical,
- "source": _sort_key_source,
-}
-
-
-def do_format_code(code: str, line_length: int) -> str:
- """Format code.
-
- Parameters:
- code: The code to format.
- line_length: The line length.
-
- Returns:
- The same code, formatted.
- """
- code = code.strip()
- if len(code) < line_length:
- return code
- formatter = _get_formatter()
- return formatter(code, line_length)
-
-
-class _StashCrossRefFilter:
- stash: ClassVar[dict[str, str]] = {}
-
- @staticmethod
- def _gen_key(length: int) -> str:
- return "_" + "".join(random.choice(string.ascii_letters + string.digits) for _ in range(max(1, length - 1))) # noqa: S311
-
- def _gen_stash_key(self, length: int) -> str:
- key = self._gen_key(length)
- while key in self.stash:
- key = self._gen_key(length)
- return key
-
- def __call__(self, crossref: str, *, length: int) -> str:
- key = self._gen_stash_key(length)
- self.stash[key] = crossref
- return key
-
-
-do_stash_crossref = _StashCrossRefFilter()
-
-
-def _format_signature(name: Markup, signature: str, line_length: int) -> str:
- name = str(name).strip() # type: ignore[assignment]
- signature = signature.strip()
- if len(name + signature) < line_length:
- return name + signature
-
- # Black cannot format names with dots, so we replace
- # the whole name with a string of equal length
- name_length = len(name)
- formatter = _get_formatter()
- formatable = f"def {'x' * name_length}{signature}: pass"
- formatted = formatter(formatable, line_length)
-
- # We put back the original name
- # and remove starting `def ` and trailing `: pass`
- return name + formatted[4:-5].strip()[name_length:-1]
-
-
-@pass_context
-def do_format_signature(
- context: Context,
- callable_path: Markup,
- function: Function,
- line_length: int,
- *,
- annotations: bool | None = None,
- crossrefs: bool = False, # noqa: ARG001
-) -> str:
- """Format a signature.
-
- Parameters:
- context: Jinja context, passed automatically.
- callable_path: The path of the callable we render the signature of.
- function: The function we render the signature of.
- line_length: The line length.
- annotations: Whether to show type annotations.
- crossrefs: Whether to cross-reference types in the signature.
-
- Returns:
- The same code, formatted.
- """
- env = context.environment
- # TODO: Stop using `do_get_template` when `*.html` templates are removed.
- template = env.get_template(do_get_template(env, "signature"))
-
- if annotations is None:
- new_context = context.parent
- else:
- new_context = dict(context.parent)
- new_context["config"] = replace(new_context["config"], show_signature_annotations=annotations)
-
- signature = template.render(new_context, function=function, signature=True)
- signature = _format_signature(callable_path, signature, line_length)
- signature = str(
- env.filters["highlight"](
- Markup.escape(signature),
- language="python",
- inline=False,
- classes=["doc-signature"],
- linenums=False,
- ),
- )
-
- # Since we highlight the signature without `def`,
- # Pygments sees it as a function call and not a function definition.
- # The result is that the function name is not parsed as such,
- # but instead as a regular name: `n` CSS class instead of `nf`.
- # To fix it, we replace the first occurrence of an `n` CSS class
- # with an `nf` one, unless we found `nf` already.
- if signature.find('class="nf"') == -1:
- signature = signature.replace('class="n"', 'class="nf"', 1)
-
- if stash := env.filters["stash_crossref"].stash:
- for key, value in stash.items():
- signature = re.sub(rf"\b{key}\b", value, signature)
- stash.clear()
-
- return signature
-
-
-@pass_context
-def do_format_attribute(
- context: Context,
- attribute_path: Markup,
- attribute: Attribute,
- line_length: int,
- *,
- crossrefs: bool = False, # noqa: ARG001
-) -> str:
- """Format an attribute.
-
- Parameters:
- context: Jinja context, passed automatically.
- attribute_path: The path of the callable we render the signature of.
- attribute: The attribute we render the signature of.
- line_length: The line length.
- crossrefs: Whether to cross-reference types in the signature.
-
- Returns:
- The same code, formatted.
- """
- env = context.environment
- # TODO: Stop using `do_get_template` when `*.html` templates are removed.
- template = env.get_template(do_get_template(env, "expression"))
- annotations = context.parent["config"].show_signature_annotations
-
- signature = str(attribute_path).strip()
- if annotations and attribute.annotation:
- annotation = template.render(
- context.parent,
- expression=attribute.annotation,
- signature=True,
- backlink_type="returned-by",
- )
- signature += f": {annotation}"
- if attribute.value:
- value = template.render(context.parent, expression=attribute.value, signature=True, backlink_type="used-by")
- signature += f" = {value}"
-
- signature = do_format_code(signature, line_length)
- signature = str(
- env.filters["highlight"](
- Markup.escape(signature),
- language="python",
- inline=False,
- classes=["doc-signature"],
- linenums=False,
- ),
- )
-
- if stash := env.filters["stash_crossref"].stash:
- for key, value in stash.items():
- signature = re.sub(rf"\b{key}\b", value, signature)
- stash.clear()
-
- return signature
-
-
-def do_order_members(
- members: Sequence[Object | Alias],
- order: Order,
- members_list: bool | list[str] | None,
-) -> Sequence[Object | Alias]:
- """Order members given an ordering method.
-
- Parameters:
- members: The members to order.
- order: The ordering method.
- members_list: An optional member list (manual ordering).
-
- Returns:
- The same members, ordered.
- """
- if isinstance(members_list, list) and members_list:
- sorted_members = []
- members_dict = {member.name: member for member in members}
- for name in members_list:
- if name in members_dict:
- sorted_members.append(members_dict[name])
- return sorted_members
- return sorted(members, key=order_map[order])
-
-
-@lru_cache
-def _warn_crossref() -> None:
- warnings.warn(
- "The `crossref` filter is deprecated and will be removed in a future version",
- DeprecationWarning,
- stacklevel=1,
- )
-
-
-def do_crossref(path: str, *, brief: bool = True) -> Markup:
- """Deprecated. Filter to create cross-references.
-
- Parameters:
- path: The path to link to.
- brief: Show only the last part of the path, add full path as hover.
-
- Returns:
- Markup text.
- """
- _warn_crossref()
- full_path = path
- if brief:
- path = full_path.split(".")[-1]
- return Markup("{text}
"
- return Markup(text).format(**variables)
-
-
-_split_path_re = re.compile(r"([.(]?)([\w]+)(\))?")
-_splitable_re = re.compile(r"[().]")
-
-
-def do_split_path(path: str, full_path: str) -> Iterator[tuple[str, str, str, str]]:
- """Split object paths for building cross-references.
-
- Parameters:
- path: The path to split.
- full_path: The full path, used to compute correct paths for each part of the path.
-
- Yields:
- 4-tuples: prefix, word, full path, suffix.
- """
- # Path is a single word, yield full path directly.
- if not _splitable_re.search(path):
- yield ("", path, full_path, "")
- return
-
- current_path = ""
- if path == full_path:
- # Split full path and yield directly without storing data in a dict.
- for match in _split_path_re.finditer(full_path):
- prefix, word, suffix = match.groups()
- current_path = f"{current_path}{prefix}{word}{suffix or ''}" if current_path else word
- yield prefix or "", word, current_path, suffix or ""
- return
-
- # Split full path first to store tuples in a dict.
- elements = {}
- for match in _split_path_re.finditer(full_path):
- prefix, word, suffix = match.groups()
- current_path = f"{current_path}{prefix}{word}{suffix or ''}" if current_path else word
- elements[word] = (prefix or "", word, current_path, suffix or "")
-
- # Then split path and pick tuples from the dict.
- first = True
- for match in _split_path_re.finditer(path):
- prefix, word, current_path, suffix = elements[match.group(2)]
- yield "" if first else prefix, word, current_path, suffix
- first = False
-
-
-def _keep_object(name: str, filters: Sequence[tuple[Pattern, bool]]) -> bool:
- keep = None
- rules = set()
- for regex, exclude in filters:
- rules.add(exclude)
- if regex.search(name):
- keep = not exclude
- if keep is None:
- # When we only include stuff, no match = reject.
- # When we only exclude stuff, or include and exclude stuff, no match = keep.
- return rules != {False}
- return keep
-
-
-def do_filter_objects(
- objects_dictionary: dict[str, Object | Alias],
- *,
- filters: Sequence[tuple[Pattern, bool]] | None = None,
- members_list: bool | list[str] | None = None,
- inherited_members: bool | list[str] = False,
- keep_no_docstrings: bool = True,
-) -> list[Object | Alias]:
- """Filter a dictionary of objects based on their docstrings.
-
- Parameters:
- objects_dictionary: The dictionary of objects.
- filters: Filters to apply, based on members' names.
- Each element is a tuple: a pattern, and a boolean indicating whether
- to reject the object if the pattern matches.
- members_list: An optional, explicit list of members to keep.
- When given and empty, return an empty list.
- When given and not empty, ignore filters and docstrings presence/absence.
- inherited_members: Whether to keep inherited members or exclude them.
- keep_no_docstrings: Whether to keep objects with no/empty docstrings (recursive check).
-
- Returns:
- A list of objects.
- """
- inherited_members_specified = False
- if inherited_members is True:
- # Include all inherited members.
- objects = list(objects_dictionary.values())
- elif inherited_members is False:
- # Include no inherited members.
- objects = [obj for obj in objects_dictionary.values() if not obj.inherited]
- else:
- # Include specific inherited members.
- inherited_members_specified = True
- objects = [
- obj for obj in objects_dictionary.values() if not obj.inherited or obj.name in set(inherited_members)
- ]
-
- if members_list is True:
- # Return all pre-selected members.
- return objects
-
- if members_list is False or members_list == []:
- # Return selected inherited members, if any.
- return [obj for obj in objects if obj.inherited]
-
- if members_list is not None:
- # Return selected members (keeping any pre-selected inherited members).
- return [
- obj for obj in objects if obj.name in set(members_list) or (inherited_members_specified and obj.inherited)
- ]
-
- # Use filters and docstrings.
- if filters:
- objects = [
- obj for obj in objects if _keep_object(obj.name, filters) or (inherited_members_specified and obj.inherited)
- ]
- if keep_no_docstrings:
- return objects
-
- return [obj for obj in objects if obj.has_docstrings or (inherited_members_specified and obj.inherited)]
-
-
-@lru_cache(maxsize=1)
-def _get_formatter() -> Callable[[str, int], str]:
- for formatter_function in [
- _get_black_formatter,
- _get_ruff_formatter,
- ]:
- if (formatter := formatter_function()) is not None:
- return formatter
-
- logger.info("Formatting signatures requires either Black or Ruff to be installed.")
- return lambda text, _: text
-
-
-def _get_ruff_formatter() -> Callable[[str, int], str] | None:
- try:
- from ruff.__main__ import find_ruff_bin
- except ImportError:
- return None
-
- try:
- ruff_bin = find_ruff_bin()
- except FileNotFoundError:
- ruff_bin = "ruff"
-
- def formatter(code: str, line_length: int) -> str:
- try:
- completed_process = subprocess.run( # noqa: S603
- [
- ruff_bin,
- "format",
- "--config",
- f"line-length={line_length}",
- "--stdin-filename",
- "file.py",
- "-",
- ],
- check=True,
- capture_output=True,
- text=True,
- input=code,
- )
- except subprocess.CalledProcessError:
- return code
- else:
- return completed_process.stdout
-
- return formatter
-
-
-def _get_black_formatter() -> Callable[[str, int], str] | None:
- try:
- from black import InvalidInput, Mode, format_str
- except ModuleNotFoundError:
- return None
-
- def formatter(code: str, line_length: int) -> str:
- mode = Mode(line_length=line_length)
- try:
- return format_str(code, mode=mode)
- except InvalidInput:
- return code
-
- return formatter
-
-
-@pass_environment
-def do_get_template(env: Environment, obj: str | Object) -> str | Template:
- """Get the template name used to render an object.
-
- Parameters:
- env: The Jinja environment, passed automatically.
- obj: A Griffe object, or a template name.
-
- Returns:
- A template name.
- """
- name = obj
- if isinstance(obj, (Alias, Object)):
- extra_data = getattr(obj, "extra", {}).get("mkdocstrings", {})
- if name := extra_data.get("template", ""):
- return name
- name = obj.kind.value
- try:
- template = env.get_template(f"{name}.html")
- except TemplateNotFound:
- return f"{name}.html.jinja"
- our_template = Path(template.filename).is_relative_to(Path(__file__).parent) # type: ignore[arg-type]
- if our_template:
- return f"{name}.html.jinja"
- # TODO: Switch to a warning log after some time.
- logger.info(
- f"DeprecationWarning: Overriding '{name}.html' is deprecated, override '{name}.html.jinja' instead. "
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
- once=True,
- )
- return f"{name}.html"
-
-
-@pass_context
-def do_as_attributes_section(
- context: Context, # noqa: ARG001
- attributes: Sequence[Attribute],
- *,
- check_public: bool = True,
-) -> DocstringSectionAttributes:
- """Build an attributes section from a list of attributes.
-
- Parameters:
- attributes: The attributes to build the section from.
- check_public: Whether to check if the attribute is public.
-
- Returns:
- An attributes docstring section.
- """
-
- def _parse_docstring_summary(attribute: Attribute) -> str:
- if attribute.docstring is None:
- return ""
- line = attribute.docstring.value.split("\n", 1)[0]
- if ":" in line and attribute.docstring.parser_options.get("returns_type_in_property_summary", False):
- _, line = line.split(":", 1)
- return line
-
- return DocstringSectionAttributes(
- [
- DocstringAttribute(
- name=attribute.name,
- description=_parse_docstring_summary(attribute),
- annotation=attribute.annotation,
- value=attribute.value, # type: ignore[arg-type]
- )
- for attribute in attributes
- if not check_public or attribute.is_public
- ],
- )
-
-
-@pass_context
-def do_as_functions_section(
- context: Context,
- functions: Sequence[Function],
- *,
- check_public: bool = True,
-) -> DocstringSectionFunctions:
- """Build a functions section from a list of functions.
-
- Parameters:
- functions: The functions to build the section from.
- check_public: Whether to check if the function is public.
-
- Returns:
- A functions docstring section.
- """
- keep_init_method = not context.parent["config"].merge_init_into_class
- return DocstringSectionFunctions(
- [
- DocstringFunction(
- name=function.name,
- description=function.docstring.value.split("\n", 1)[0] if function.docstring else "",
- )
- for function in functions
- if (not check_public or function.is_public) and (function.name != "__init__" or keep_init_method)
- ],
- )
-
-
-@pass_context
-def do_as_classes_section(
- context: Context, # noqa: ARG001
- classes: Sequence[Class],
- *,
- check_public: bool = True,
-) -> DocstringSectionClasses:
- """Build a classes section from a list of classes.
-
- Parameters:
- classes: The classes to build the section from.
- check_public: Whether to check if the class is public.
-
- Returns:
- A classes docstring section.
- """
- return DocstringSectionClasses(
- [
- DocstringClass(
- name=cls.name,
- description=cls.docstring.value.split("\n", 1)[0] if cls.docstring else "",
- )
- for cls in classes
- if not check_public or cls.is_public
- ],
- )
-
-
-@pass_context
-def do_as_modules_section(
- context: Context, # noqa: ARG001
- modules: Sequence[Module],
- *,
- check_public: bool = True,
-) -> DocstringSectionModules:
- """Build a modules section from a list of modules.
-
- Parameters:
- modules: The modules to build the section from.
- check_public: Whether to check if the module is public.
-
- Returns:
- A modules docstring section.
- """
- return DocstringSectionModules(
- [
- DocstringModule(
- name=module.name,
- description=module.docstring.value.split("\n", 1)[0] if module.docstring else "",
- )
- for module in modules
- if not check_public or module.is_public
- ],
- )
-
-
-class AutorefsHook(AutorefsHookInterface):
- """Autorefs hook.
-
- With this hook, we're able to add context to autorefs (cross-references),
- such as originating file path and line number, to improve error reporting.
- """
-
- def __init__(self, current_object: Object | Alias, config: dict[str, Any]) -> None:
- """Initialize the hook.
-
- Parameters:
- current_object: The object being rendered.
- config: The configuration dictionary.
- """
- self.current_object = current_object
- """The current object being rendered."""
- self.config = config
- """The configuration options."""
-
- def expand_identifier(self, identifier: str) -> str:
- """Expand an identifier.
-
- Parameters:
- identifier: The identifier to expand.
-
- Returns:
- The expanded identifier.
- """
- return identifier
-
- def get_context(self) -> AutorefsHookInterface.Context:
- """Get the context for the current object.
-
- Returns:
- The context.
- """
- role = {
- "attribute": "data" if self.current_object.parent and self.current_object.parent.is_module else "attr",
- "class": "class",
- "function": "meth" if self.current_object.parent and self.current_object.parent.is_class else "func",
- "module": "mod",
- }.get(self.current_object.kind.value.lower(), "obj")
- origin = self.current_object.path
- try:
- filepath = self.current_object.docstring.parent.filepath # type: ignore[union-attr]
- lineno = self.current_object.docstring.lineno or 0 # type: ignore[union-attr]
- except AttributeError:
- filepath = self.current_object.filepath
- lineno = 0
-
- return AutorefsHookInterface.Context(
- domain="py",
- role=role,
- origin=origin,
- filepath=str(filepath),
- lineno=lineno,
- )
-
-
-T = TypeVar("T")
-Tree = dict[T, "Tree"]
-CompactTree = dict[tuple[T, ...], "CompactTree"]
-_rtree = lambda: defaultdict(_rtree) # type: ignore[has-type,var-annotated] # noqa: E731
-
-
-def _tree(data: Iterable[tuple[T, ...]]) -> Tree:
- new_tree = _rtree()
- for nav in data:
- *path, leaf = nav
- node = new_tree
- for key in path:
- node = node[key]
- node[leaf] = _rtree()
- return new_tree
-
-
-def _compact_tree(tree: Tree) -> CompactTree:
- new_tree = _rtree()
- for key, value in tree.items():
- child = _compact_tree(value)
- if len(child) == 1:
- child_key, child_value = next(iter(child.items()))
- new_key = (key, *child_key)
- new_tree[new_key] = child_value
- else:
- new_tree[(key,)] = child
- return new_tree
-
-
-def do_backlink_tree(backlinks: list[Backlink]) -> CompactTree[BacklinkCrumb]:
- """Build a tree of backlinks.
-
- Parameters:
- backlinks: The list of backlinks.
-
- Returns:
- A tree of backlinks.
- """
- return _compact_tree(_tree(backlink.crumbs for backlink in backlinks))
+ return getattr(rendering, name)
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html
index 7effc590..37c8702c 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/attribute.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/attribute.html' is deprecated, extend '_base/attribute.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/attribute.html' is deprecated, extend '_base/attribute.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja
index 3217b4f6..519590e5 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/attribute.html.jinja
@@ -39,7 +39,7 @@ Context:
role="data" if attribute.parent.kind.value == "module" else "attr",
id=html_id,
class="doc doc-heading",
- toc_label=('
'|safe if config.show_symbol_type_toc else '') + attribute.name,
+ toc_label=('
'|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else attribute.name),
) %}
{% block heading scoped %}
@@ -48,8 +48,10 @@ Context:
This block renders the heading for the attribute.
-#}
{% if config.show_symbol_type_heading %}
{% endif %}
- {% if config.separate_signature %}
- {{ config.heading if config.heading and root else attribute_name }}
+ {% if config.heading and root %}
+ {{ config.heading }}
+ {% elif config.separate_signature %}
+ {{ attribute_name }}
{% else %}
{%+ filter highlight(language="python", inline=True) %}
{{ attribute_name }}{% if attribute.annotation and config.show_signature_annotations %}: {{ attribute.annotation }}{% endif %}
@@ -64,6 +66,7 @@ Context:
This block renders the labels for the attribute.
-#}
{% with labels = attribute.labels %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "labels"|get_template with context %}
{% endwith %}
{% endblock labels %}
@@ -110,6 +113,7 @@ Context:
This block renders the docstring for the attribute.
-#}
{% with docstring_sections = attribute.docstring.parsed %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring"|get_template with context %}
{% endwith %}
{% endblock docstring %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/children.html b/src/mkdocstrings_handlers/python/templates/material/_base/children.html
index 15fada5a..eada68e8 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/children.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/children.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/children.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/children.html' is deprecated, extend '_base/children.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/children.html' is deprecated, extend '_base/children.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja
index 40c011ed..0b9fcd64 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja
@@ -49,7 +49,7 @@ Context:
{% endif %}
{% with heading_level = heading_level + extra_level %}
{% for attribute in attributes|order_members(config.members_order, members_list) %}
- {% if members_list is not none or (not attribute.is_imported or attribute.is_public) %}
+ {% if config.filters == "public" or members_list is not none or (not attribute.is_imported or attribute.is_public) %}
{% include attribute|get_template with context %}
{% endif %}
{% endfor %}
@@ -69,7 +69,7 @@ Context:
{% endif %}
{% with heading_level = heading_level + extra_level %}
{% for class in classes|order_members(config.members_order, members_list) %}
- {% if members_list is not none or (not class.is_imported or class.is_public) %}
+ {% if config.filters == "public" or members_list is not none or (not class.is_imported or class.is_public) %}
{% include class|get_template with context %}
{% endif %}
{% endfor %}
@@ -90,7 +90,7 @@ Context:
{% with heading_level = heading_level + extra_level %}
{% for function in functions|order_members(config.members_order, members_list) %}
{% if not (obj.kind.value == "class" and function.name == "__init__" and config.merge_init_into_class) %}
- {% if members_list is not none or (not function.is_imported or function.is_public) %}
+ {% if config.filters == "public" or members_list is not none or (not function.is_imported or function.is_public) %}
{% include function|get_template with context %}
{% endif %}
{% endif %}
@@ -112,7 +112,7 @@ Context:
{% endif %}
{% with heading_level = heading_level + extra_level %}
{% for module in modules|order_members("alphabetical", members_list) %}
- {% if members_list is not none or (not module.is_alias or module.is_public) %}
+ {% if config.filters == "public" or members_list is not none or (not module.is_alias or module.is_public) %}
{% include module|get_template with context %}
{% endif %}
{% endfor %}
@@ -137,7 +137,7 @@ Context:
{% if not (obj.is_class and child.name == "__init__" and config.merge_init_into_class) %}
- {% if members_list is not none or child.is_public %}
+ {% if config.filters == "public" or members_list is not none or child.is_public %}
{% if child.is_attribute %}
{% with attribute = child %}
{% include attribute|get_template with context %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/class.html b/src/mkdocstrings_handlers/python/templates/material/_base/class.html
index ac3e421e..0fb87f5b 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/class.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/class.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/class.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/class.html' is deprecated, extend '_base/class.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/class.html' is deprecated, extend '_base/class.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja
index a07a36be..8a54dd1b 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja
@@ -38,7 +38,7 @@ Context:
role="class",
id=html_id,
class="doc doc-heading",
- toc_label=('
'|safe if config.show_symbol_type_toc else '') + class.name,
+ toc_label=('
'|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else class.name),
) %}
{% block heading scoped %}
@@ -47,13 +47,16 @@ Context:
This block renders the heading for the class.
-#}
{% if config.show_symbol_type_heading %}
{% endif %}
- {% if config.separate_signature %}
- {{ config.heading if config.heading and root else class_name }}
+ {% if config.heading and root %}
+ {{ config.heading }}
+ {% elif config.separate_signature %}
+ {{ class_name }}
{% elif config.merge_init_into_class and "__init__" in all_members %}
{% with function = all_members["__init__"] %}
- {%+ filter highlight(language="python", inline=True) %}
+ {%+ filter highlight(language="python", inline=True) -%}
+ {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#}
{{ class_name }}{% include "signature"|get_template with context %}
- {% endfilter %}
+ {%- endfilter %}
{% endwith %}
{% else %}
{{ class_name }}
@@ -66,6 +69,7 @@ Context:
This block renders the labels for the class.
-#}
{% with labels = class.labels %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "labels"|get_template with context %}
{% endwith %}
{% endblock labels %}
@@ -132,6 +136,7 @@ Context:
Bases: {% for expression in class.bases -%}
{%- with backlink_type = "subclassed-by" -%}
+ {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#}
{%- include "expression"|get_template with context -%}
{%- endwith -%}
{% if not loop.last %}, {% endif %}
@@ -146,6 +151,7 @@ Context:
This block renders the docstring for the class.
-#}
{% with docstring_sections = class.docstring.parsed %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring"|get_template with context %}
{% endwith %}
{% if config.merge_init_into_class %}
@@ -155,6 +161,7 @@ Context:
{% if "__init__" in check_members and check_members["__init__"].has_docstring %}
{% with function = check_members["__init__"] %}
{% with obj = function, docstring_sections = function.docstring.parsed %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring"|get_template with context %}
{% endwith %}
{% endwith %}
@@ -172,6 +179,7 @@ Context:
This block renders auto-summaries for classes, methods, and attributes.
-#}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "summary"|get_template with context %}
{% endblock summary %}
@@ -218,6 +226,7 @@ Context:
-#}
{% set root = False %}
{% set heading_level = heading_level + 1 %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "children"|get_template with context %}
{% endblock children %}
{% endblock contents %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html
index 5ef9da3e..c487550b 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring.html' is deprecated, extend '_base/docstring.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring.html' is deprecated, extend '_base/docstring.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja
index 6983b2e1..c560668e 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja
@@ -24,30 +24,43 @@ Context:
{% if config.show_docstring_description and section.kind.value == "text" %}
{{ section.value|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
{% elif config.show_docstring_attributes and section.kind.value == "attributes" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring/attributes"|get_template with context %}
{% elif config.show_docstring_functions and section.kind.value == "functions" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring/functions"|get_template with context %}
{% elif config.show_docstring_classes and section.kind.value == "classes" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring/classes"|get_template with context %}
{% elif config.show_docstring_modules and section.kind.value == "modules" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring/modules"|get_template with context %}
{% elif config.show_docstring_parameters and section.kind.value == "parameters" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring/parameters"|get_template with context %}
{% elif config.show_docstring_other_parameters and section.kind.value == "other parameters" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring/other_parameters"|get_template with context %}
{% elif config.show_docstring_raises and section.kind.value == "raises" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring/raises"|get_template with context %}
{% elif config.show_docstring_warns and section.kind.value == "warns" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring/warns"|get_template with context %}
{% elif config.show_docstring_yields and section.kind.value == "yields" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring/yields"|get_template with context %}
{% elif config.show_docstring_receives and section.kind.value == "receives" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring/receives"|get_template with context %}
{% elif config.show_docstring_returns and section.kind.value == "returns" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring/returns"|get_template with context %}
{% elif config.show_docstring_examples and section.kind.value == "examples" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring/examples"|get_template with context %}
{% elif config.show_docstring_description and section.kind.value == "admonition" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring/admonition"|get_template with context %}
{% endif %}
{% endfor %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html
index a8a75542..e94d6e61 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/admonition.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/admonition.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/admonition.html' is deprecated, extend '_base/docstring/admonition.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/admonition.html' is deprecated, extend '_base/docstring/admonition.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html
index cd4b05be..9f2abcd1 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/attributes.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/attributes.html' is deprecated, extend '_base/docstring/attributes.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/attributes.html' is deprecated, extend '_base/docstring/attributes.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html.jinja
index 13bd15b2..03104333 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/attributes.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug("Rendering attributes section") }}
{% endblock logs %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -37,6 +38,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
{% endif %}
@@ -61,6 +63,7 @@ Context:
{{ attribute.name }}
{% if attribute.annotation %}
{% with expression = attribute.annotation %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
({% include "expression"|get_template with context %}
)
{% endwith %}
{% endif %}
@@ -95,6 +98,7 @@ Context:
TYPE:
{% with expression = attribute.annotation %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html
index 78b47e2d..9c04b145 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/classes.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/classes.html' is deprecated, extend '_base/docstring/classes.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/classes.html' is deprecated, extend '_base/docstring/classes.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html.jinja
index 73f39329..09a5b758 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/classes.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug("Rendering classes section") }}
{% endblock logs %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html
index 37674811..4f66600f 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/examples.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/examples.html' is deprecated, extend '_base/docstring/examples.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/examples.html' is deprecated, extend '_base/docstring/examples.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html.jinja
index 0caacc15..09293cfb 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/examples.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug("Rendering examples section") }}
{% endblock logs %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html
index a61c48fb..906658b4 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/functions.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/functions.html' is deprecated, extend '_base/docstring/functions.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/functions.html' is deprecated, extend '_base/docstring/functions.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html.jinja
index 28bb0cae..dd33984f 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/functions.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug("Rendering functions section") }}
{% endblock logs %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html
index d0b303b4..7b0dcc51 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/modules.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/modules.html' is deprecated, extend '_base/docstring/modules.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/modules.html' is deprecated, extend '_base/docstring/modules.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html.jinja
index d55f854e..106e6bf6 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/modules.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug("Rendering modules section") }}
{% endblock logs %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html
index eae60aa7..02261331 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/other_parameters.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/other_parameters.html' is deprecated, extend '_base/docstring/other_parameters.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/other_parameters.html' is deprecated, extend '_base/docstring/other_parameters.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html.jinja
index 8b64af1b..66940069 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/other_parameters.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug("Rendering other parameters section") }}
{% endblock logs %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -37,6 +38,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
{% endif %}
@@ -61,6 +63,7 @@ Context:
{{ parameter.name }}
{% if parameter.annotation %}
{% with expression = parameter.annotation, backlink_type = "used-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
({% include "expression"|get_template with context %}
)
{% endwith %}
{% endif %}
@@ -95,6 +98,7 @@ Context:
{{ lang.t("TYPE:") }}
{% with expression = parameter.annotation, backlink_type = "used-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html
index f5745464..f5292150 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/parameters.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/parameters.html' is deprecated, extend '_base/docstring/parameters.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/parameters.html' is deprecated, extend '_base/docstring/parameters.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html.jinja
index ae8fb7a3..1035ddf7 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/parameters.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug("Rendering parameters section") }}
{% endblock logs %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -52,6 +53,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
{% endif %}
@@ -64,6 +66,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
{% else %}
@@ -97,9 +100,11 @@ Context:
{% endif %}
{% if parameter.annotation %}
{% with expression = parameter.annotation, backlink_type = "used-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
({% include "expression"|get_template with context %}
{%- if parameter.default %}, {{ lang.t("default:") }}
{% with expression = parameter.default, backlink_type = "used-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% endwith %}
{% endif %})
@@ -150,6 +155,7 @@ Context:
{{ lang.t("TYPE:") }}
{% with expression = parameter.annotation, backlink_type = "used-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% endwith %}
@@ -158,6 +164,7 @@ Context:
{{ lang.t("DEFAULT:") }}
{% with expression = parameter.default, backlink_type = "used-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html
index 361b9732..38a21e89 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/raises.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/raises.html' is deprecated, extend '_base/docstring/raises.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/raises.html' is deprecated, extend '_base/docstring/raises.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html.jinja
index 1e1d5006..cd034c0e 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/raises.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug("Rendering raises section") }}
{% endblock logs %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -35,6 +36,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
{% endif %}
@@ -58,6 +60,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
–
@@ -85,6 +88,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html
index e5a115c1..d9c404b6 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/receives.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/receives.html' is deprecated, extend '_base/docstring/receives.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/receives.html' is deprecated, extend '_base/docstring/receives.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html.jinja
index a447b216..3ecc5b41 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/receives.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug("Rendering receives section") }}
{% endblock logs %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -38,6 +39,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
{% endif %}
@@ -63,6 +65,7 @@ Context:
{% if receives.annotation %}
{% with expression = receives.annotation, backlink_type = "received-by" %}
{% if receives.name %} ({% endif %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% if receives.name %}){% endif %}
{% endwith %}
@@ -94,6 +97,7 @@ Context:
{% elif receives.annotation %}
{% with expression = receives.annotation, backlink_type = "received-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% endwith %}
@@ -108,6 +112,7 @@ Context:
{{ lang.t("TYPE:") }}
{% with expression = receives.annotation, backlink_type = "received-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html
index 0e7807ac..b608af5f 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/returns.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/returns.html' is deprecated, extend '_base/docstring/returns.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/returns.html' is deprecated, extend '_base/docstring/returns.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html.jinja
index 30540e66..bc8ee4ff 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/returns.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug("Rendering returns section") }}
{% endblock logs %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -38,6 +39,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
{% endif %}
@@ -63,6 +65,7 @@ Context:
{% if returns.annotation %}
{% with expression = returns.annotation, backlink_type = "returned-by" %}
{% if returns.name %} ({% endif %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% if returns.name %}){% endif %}
{% endwith %}
@@ -94,6 +97,7 @@ Context:
{% elif returns.annotation %}
{% with expression = returns.annotation, backlink_type = "returned-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% endwith %}
@@ -108,6 +112,7 @@ Context:
{{ lang.t("TYPE:") }}
{% with expression = returns.annotation, backlink_type = "returned-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html
index b7b937a9..9eba72ab 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/warns.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/warns.html' is deprecated, extend '_base/docstring/warns.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/warns.html' is deprecated, extend '_base/docstring/warns.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html.jinja
index 814e3020..d5a24262 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/warns.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug("Rendering warns section") }}
{% endblock logs %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -35,6 +36,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
{% endif %}
@@ -58,6 +60,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
–
@@ -85,6 +88,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html
index ecd6f513..6ec31dd0 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/yields.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/yields.html' is deprecated, extend '_base/docstring/yields.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/yields.html' is deprecated, extend '_base/docstring/yields.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html.jinja
index 01b8b9e5..154d0202 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/yields.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug("Rendering yields section") }}
{% endblock logs %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -38,6 +39,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
{% endif %}
@@ -63,6 +65,7 @@ Context:
{% if yields.annotation %}
{% with expression = yields.annotation, backlink_type = "yielded-by" %}
{% if yields.name %} ({% endif %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% if yields.name %}){% endif %}
{% endwith %}
@@ -94,6 +97,7 @@ Context:
{% elif yields.annotation %}
{% with expression = yields.annotation, backlink_type = "yielded-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% endwith %}
@@ -108,6 +112,7 @@ Context:
{{ lang.t("TYPE:") }}:
{% with expression = yields.annotation, backlink_type = "yielded-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/expression.html b/src/mkdocstrings_handlers/python/templates/material/_base/expression.html
index 556b3e2b..8c84928c 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/expression.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/expression.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/expression.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/expression.html' is deprecated, extend '_base/expression.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/expression.html' is deprecated, extend '_base/expression.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/function.html b/src/mkdocstrings_handlers/python/templates/material/_base/function.html
index 07be5abb..4afd930b 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/function.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/function.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/function.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/function.html' is deprecated, extend '_base/function.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/function.html' is deprecated, extend '_base/function.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja
index 4adcf3bd..21888939 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja
@@ -17,6 +17,7 @@ Context:
{{ log.debug("Rendering " + function.path) }}
{% endblock logs %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -44,7 +45,7 @@ Context:
role="function",
id=html_id,
class="doc doc-heading",
- toc_label=(('
')|safe if config.show_symbol_type_toc else '') + function.name,
+ toc_label=(('
')|safe if config.show_symbol_type_toc else '') + (config.toc_label if config.toc_label and root else function.name),
) %}
{% block heading scoped %}
@@ -53,12 +54,15 @@ Context:
This block renders the heading for the function.
-#}
{% if config.show_symbol_type_heading %}
{% endif %}
- {% if config.separate_signature %}
- {{ config.heading if config.heading and root else function_name }}
+ {% if config.heading and root %}
+ {{ config.heading }}
+ {% elif config.separate_signature %}
+ {{ function_name }}
{% else %}
- {%+ filter highlight(language="python", inline=True) %}
+ {%+ filter highlight(language="python", inline=True) -%}
+ {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#}
{{ function_name }}{% include "signature"|get_template with context %}
- {% endfilter %}
+ {%- endfilter %}
{% endif %}
{% endblock heading %}
@@ -68,6 +72,7 @@ Context:
This block renders the labels for the function.
-#}
{% with labels = function.labels %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "labels"|get_template with context %}
{% endwith %}
{% endblock labels %}
@@ -125,6 +130,7 @@ Context:
This block renders the docstring for the function.
-#}
{% with docstring_sections = function.docstring.parsed %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring"|get_template with context %}
{% endwith %}
{% endblock docstring %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/labels.html b/src/mkdocstrings_handlers/python/templates/material/_base/labels.html
index 784150c4..cda79114 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/labels.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/labels.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/labels.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/labels.html' is deprecated, extend '_base/labels.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/labels.html' is deprecated, extend '_base/labels.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/language.html b/src/mkdocstrings_handlers/python/templates/material/_base/language.html
index c97d0c31..a5a86545 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/language.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/language.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/language.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/language.html' is deprecated, extend '_base/language.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/language.html' is deprecated, extend '_base/language.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/language.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/language.html.jinja
index e3a614bb..5a4b773e 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/language.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/language.html.jinja
@@ -7,12 +7,15 @@
-#}
{% endblock logs %}
+{# YORE: Bump 2: Replace `| get_template` with `~ ".html.jinja"` within line. #}
{% set lang_pth = "languages/" ~ locale | get_template %}
{% if lang_pth is existing_template %}
- {% import lang_pth as lang %}
- {% import "languages/en"|get_template as fallback %}
- {% macro t(key) %}{{ lang.t(key) or fallback.t(key) }}{% endmacro %}
+ {% import lang_pth as lang %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
+ {% import "languages/en"|get_template as fallback %}
+ {% macro t(key) %}{{ lang.t(key) or fallback.t(key) }}{% endmacro %}
{% else %}
- {% import "languages/en"|get_template as lang %}
- {% macro t(key) %}{{ lang.t(key) }}{% endmacro %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
+ {% import "languages/en"|get_template as lang %}
+ {% macro t(key) %}{{ lang.t(key) }}{% endmacro %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html b/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html
index eab87415..2f050a32 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/languages/en.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/languages/en.html' is deprecated, extend '_base/languages/en.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/languages/en.html' is deprecated, extend '_base/languages/en.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html b/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html
index 14319499..1f3095f4 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/languages/ja.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/languages/ja.html' is deprecated, extend '_base/languages/ja.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/languages/ja.html' is deprecated, extend '_base/languages/ja.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html b/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html
index 0b281195..b58b0479 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/languages/zh.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/languages/zh.html' is deprecated, extend '_base/languages/zh.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/languages/zh.html' is deprecated, extend '_base/languages/zh.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/module.html b/src/mkdocstrings_handlers/python/templates/material/_base/module.html
index 918ab6d0..dcda15ea 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/module.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/module.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/module.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/module.html' is deprecated, extend '_base/module.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/module.html' is deprecated, extend '_base/module.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja
index d49dc76d..283f2654 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/module.html.jinja
@@ -47,8 +47,10 @@ Context:
This block renders the heading for the module.
-#}
{% if config.show_symbol_type_heading %}
{% endif %}
- {% if config.separate_signature %}
- {{ config.heading if config.heading and root else module_name }}
+ {% if config.heading and root %}
+ {{ config.heading }}
+ {% elif config.separate_signature %}
+ {{ module_name }}
{% else %}
{{ module_name }}
{% endif %}
@@ -60,6 +62,7 @@ Context:
This block renders the labels for the module.
-#}
{% with labels = module.labels %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "labels"|get_template with context %}
{% endwith %}
{% endblock labels %}
@@ -93,6 +96,7 @@ Context:
This block renders the docstring for the module.
-#}
{% with docstring_sections = module.docstring.parsed %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "docstring"|get_template with context %}
{% endwith %}
{% endblock docstring %}
@@ -106,6 +110,7 @@ Context:
This block renders auto-summaries for classes, methods, and attributes.
-#}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "summary"|get_template with context %}
{% endblock summary %}
@@ -116,6 +121,7 @@ Context:
-#}
{% set root = False %}
{% set heading_level = heading_level + 1 %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "children"|get_template with context %}
{% endblock children %}
{% endblock contents %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/signature.html b/src/mkdocstrings_handlers/python/templates/material/_base/signature.html
index 623879db..6f05fed7 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/signature.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/signature.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/signature.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/signature.html' is deprecated, extend '_base/signature.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/signature.html' is deprecated, extend '_base/signature.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/signature.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/signature.html.jinja
index e414fbe3..0e0678a1 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/signature.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/signature.html.jinja
@@ -50,6 +50,7 @@ Context:
{%- if config.separate_signature -%}
{%- with expression = parameter.annotation -%}
{%- set ns.annotation -%}: {% with backlink_type = "used-by" -%}
+ {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#}
{%- include "expression"|get_template with context -%}
{%- endwith -%}{%- endset -%}
{%- endwith -%}
@@ -105,6 +106,7 @@ Context:
{{ ns.equal }}
{%- if config.signature_crossrefs and config.separate_signature -%}
{%- with expression = parameter.default, backlink_type = "used-by" -%}
+ {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#}
{%- include "expression"|get_template with context -%}
{%- endwith -%}
{%- else -%}
@@ -124,6 +126,7 @@ Context:
and not (config.merge_init_into_class and function.name == "__init__" )
%} -> {% if config.separate_signature and config.signature_crossrefs -%}
{%- with expression = function.annotation, backlink_type = "returned-by" -%}
+ {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#}
{%- include "expression"|get_template with context -%}
{%- endwith -%}
{%- else -%}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary.html b/src/mkdocstrings_handlers/python/templates/material/_base/summary.html
index aa33dc9c..b970164d 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/summary.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/summary.html' is deprecated, extend '_base/summary.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/summary.html' is deprecated, extend '_base/summary.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja
index 0a4ee071..78b0b9d7 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja
@@ -9,18 +9,22 @@
{% with members_list = config.members if root_members else None %}
{% if config.summary.modules %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "summary/modules"|get_template with context %}
{% endif %}
{% if config.summary.classes %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "summary/classes"|get_template with context %}
{% endif %}
{% if config.summary.functions %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "summary/functions"|get_template with context %}
{% endif %}
{% if config.summary.attributes %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "summary/attributes"|get_template with context %}
{% endif %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html b/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html
index f2643791..8e575a44 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/summary/attributes.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/summary/attributes.html' is deprecated, extend '_base/summary/attributes.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/summary/attributes.html' is deprecated, extend '_base/summary/attributes.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html.jinja
index cabda067..52f9a43a 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/attributes.html.jinja
@@ -18,6 +18,7 @@
|order_members(config.members_order, members_list)
|as_attributes_section(check_public=not members_list)
%}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% if section %}{% include "docstring/attributes"|get_template with context %}{% endif %}
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html b/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html
index 5c6275b4..a74eff99 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/summary/classes.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/summary/classes.html' is deprecated, extend '_base/summary/classes.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/summary/classes.html' is deprecated, extend '_base/summary/classes.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html.jinja
index 7527781b..628d4133 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/classes.html.jinja
@@ -18,6 +18,7 @@
|order_members(config.members_order, members_list)
|as_classes_section(check_public=not members_list)
%}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% if section %}{% include "docstring/classes"|get_template with context %}{% endif %}
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html b/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html
index 31887e0a..ff95f246 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/summary/functions.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/summary/functions.html' is deprecated, extend '_base/summary/functions.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/summary/functions.html' is deprecated, extend '_base/summary/functions.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html.jinja
index cdf75973..a82f2f87 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/functions.html.jinja
@@ -18,6 +18,7 @@
|order_members(config.members_order, members_list)
|as_functions_section(check_public=not members_list)
%}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% if section %}{% include "docstring/functions"|get_template with context %}{% endif %}
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html b/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html
index 31dcb5f0..51e964c1 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/summary/modules.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/summary/modules.html' is deprecated, extend '_base/summary/modules.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/summary/modules.html' is deprecated, extend '_base/summary/modules.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html.jinja
index b9654593..109b34a9 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/modules.html.jinja
@@ -18,6 +18,7 @@
|order_members("alphabetical", members_list)
|as_modules_section(check_public=not members_list)
%}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% if section %}{% include "docstring/modules"|get_template with context %}{% endif %}
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/attribute.html b/src/mkdocstrings_handlers/python/templates/material/attribute.html
index a3c27503..aaf56880 100644
--- a/src/mkdocstrings_handlers/python/templates/material/attribute.html
+++ b/src/mkdocstrings_handlers/python/templates/material/attribute.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/attribute.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/children.html b/src/mkdocstrings_handlers/python/templates/material/children.html
index 2c2a73ab..312346ec 100644
--- a/src/mkdocstrings_handlers/python/templates/material/children.html
+++ b/src/mkdocstrings_handlers/python/templates/material/children.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/children.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/class.html b/src/mkdocstrings_handlers/python/templates/material/class.html
index 5e7329df..7ee0f690 100644
--- a/src/mkdocstrings_handlers/python/templates/material/class.html
+++ b/src/mkdocstrings_handlers/python/templates/material/class.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/class.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring.html b/src/mkdocstrings_handlers/python/templates/material/docstring.html
index a7ccd66c..cb91e77a 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/admonition.html b/src/mkdocstrings_handlers/python/templates/material/docstring/admonition.html
index e9da5e9a..943c883f 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/admonition.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/admonition.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/admonition.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/attributes.html b/src/mkdocstrings_handlers/python/templates/material/docstring/attributes.html
index 4ac364b0..6a67cafb 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/attributes.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/attributes.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/attributes.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/classes.html b/src/mkdocstrings_handlers/python/templates/material/docstring/classes.html
index 035b3102..fce82b60 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/classes.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/classes.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/classes.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/examples.html b/src/mkdocstrings_handlers/python/templates/material/docstring/examples.html
index 34e9c4ba..334796a6 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/examples.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/examples.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/examples.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/functions.html b/src/mkdocstrings_handlers/python/templates/material/docstring/functions.html
index f3eaed78..9f07107e 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/functions.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/functions.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/functions.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/modules.html b/src/mkdocstrings_handlers/python/templates/material/docstring/modules.html
index 8ea02a33..23a9965e 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/modules.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/modules.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/modules.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/other_parameters.html b/src/mkdocstrings_handlers/python/templates/material/docstring/other_parameters.html
index 7c50379b..a7024661 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/other_parameters.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/other_parameters.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/other_parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/parameters.html b/src/mkdocstrings_handlers/python/templates/material/docstring/parameters.html
index 70c557fb..fb49b54d 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/parameters.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/parameters.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/raises.html b/src/mkdocstrings_handlers/python/templates/material/docstring/raises.html
index f8c3cf03..1365fc5e 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/raises.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/raises.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/raises.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/receives.html b/src/mkdocstrings_handlers/python/templates/material/docstring/receives.html
index 004ff00e..9521ee68 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/receives.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/receives.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/receives.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/returns.html b/src/mkdocstrings_handlers/python/templates/material/docstring/returns.html
index 979ce9ef..93413ed8 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/returns.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/returns.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/returns.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/warns.html b/src/mkdocstrings_handlers/python/templates/material/docstring/warns.html
index bb06cc85..95523fde 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/warns.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/warns.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/warns.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/yields.html b/src/mkdocstrings_handlers/python/templates/material/docstring/yields.html
index 717ef5d4..58bccc7b 100644
--- a/src/mkdocstrings_handlers/python/templates/material/docstring/yields.html
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/yields.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/yields.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/expression.html b/src/mkdocstrings_handlers/python/templates/material/expression.html
index 60c64d79..5edd5520 100644
--- a/src/mkdocstrings_handlers/python/templates/material/expression.html
+++ b/src/mkdocstrings_handlers/python/templates/material/expression.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/expression.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/function.html b/src/mkdocstrings_handlers/python/templates/material/function.html
index 54bba061..c90df9b5 100644
--- a/src/mkdocstrings_handlers/python/templates/material/function.html
+++ b/src/mkdocstrings_handlers/python/templates/material/function.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/function.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/labels.html b/src/mkdocstrings_handlers/python/templates/material/labels.html
index 51cb29d6..124caf19 100644
--- a/src/mkdocstrings_handlers/python/templates/material/labels.html
+++ b/src/mkdocstrings_handlers/python/templates/material/labels.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/labels.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/language.html b/src/mkdocstrings_handlers/python/templates/material/language.html
index b905cff4..6da4f8df 100644
--- a/src/mkdocstrings_handlers/python/templates/material/language.html
+++ b/src/mkdocstrings_handlers/python/templates/material/language.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/language.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/languages/en.html b/src/mkdocstrings_handlers/python/templates/material/languages/en.html
index 931967c1..bcc4121e 100644
--- a/src/mkdocstrings_handlers/python/templates/material/languages/en.html
+++ b/src/mkdocstrings_handlers/python/templates/material/languages/en.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/languages/en.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/languages/ja.html b/src/mkdocstrings_handlers/python/templates/material/languages/ja.html
index 17070edf..87827f60 100644
--- a/src/mkdocstrings_handlers/python/templates/material/languages/ja.html
+++ b/src/mkdocstrings_handlers/python/templates/material/languages/ja.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/languages/ja.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/languages/zh.html b/src/mkdocstrings_handlers/python/templates/material/languages/zh.html
index e4ea3116..37c36ff0 100644
--- a/src/mkdocstrings_handlers/python/templates/material/languages/zh.html
+++ b/src/mkdocstrings_handlers/python/templates/material/languages/zh.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/languages/zh.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/module.html b/src/mkdocstrings_handlers/python/templates/material/module.html
index 9d8efea5..ea043657 100644
--- a/src/mkdocstrings_handlers/python/templates/material/module.html
+++ b/src/mkdocstrings_handlers/python/templates/material/module.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/module.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/signature.html b/src/mkdocstrings_handlers/python/templates/material/signature.html
index 33b266c8..e6573985 100644
--- a/src/mkdocstrings_handlers/python/templates/material/signature.html
+++ b/src/mkdocstrings_handlers/python/templates/material/signature.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/signature.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/style.css b/src/mkdocstrings_handlers/python/templates/material/style.css
index e5e150ec..b8c3e639 100644
--- a/src/mkdocstrings_handlers/python/templates/material/style.css
+++ b/src/mkdocstrings_handlers/python/templates/material/style.css
@@ -9,6 +9,11 @@
display: inline;
}
+/* No text transformation from Material for MkDocs for H5 headings. */
+.md-typeset h5 .doc-object-name {
+ text-transform: none;
+}
+
/* Max width for docstring sections tables. */
.doc .md-typeset__table,
.doc .md-typeset__table table {
@@ -30,6 +35,11 @@
display: inline;
}
+/* Default font size for parameter headings. */
+.md-typeset .doc-heading-parameter {
+ font-size: inherit;
+}
+
/* Prefer space on the right, not the left of parameter permalinks. */
.doc-heading-parameter .headerlink {
margin-left: 0 !important;
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary.html b/src/mkdocstrings_handlers/python/templates/material/summary.html
index 59eddea0..604624e7 100644
--- a/src/mkdocstrings_handlers/python/templates/material/summary.html
+++ b/src/mkdocstrings_handlers/python/templates/material/summary.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/summary.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/attributes.html b/src/mkdocstrings_handlers/python/templates/material/summary/attributes.html
index c69755c6..a0fdbb04 100644
--- a/src/mkdocstrings_handlers/python/templates/material/summary/attributes.html
+++ b/src/mkdocstrings_handlers/python/templates/material/summary/attributes.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/summary/attributes.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/classes.html b/src/mkdocstrings_handlers/python/templates/material/summary/classes.html
index 825eb1bb..c01b2094 100644
--- a/src/mkdocstrings_handlers/python/templates/material/summary/classes.html
+++ b/src/mkdocstrings_handlers/python/templates/material/summary/classes.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/summary/classes.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/functions.html b/src/mkdocstrings_handlers/python/templates/material/summary/functions.html
index fc609bda..90ca63e0 100644
--- a/src/mkdocstrings_handlers/python/templates/material/summary/functions.html
+++ b/src/mkdocstrings_handlers/python/templates/material/summary/functions.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/summary/functions.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/modules.html b/src/mkdocstrings_handlers/python/templates/material/summary/modules.html
index 46db0023..1f69b3dc 100644
--- a/src/mkdocstrings_handlers/python/templates/material/summary/modules.html
+++ b/src/mkdocstrings_handlers/python/templates/material/summary/modules.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/summary/modules.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html
index cd4b05be..9f2abcd1 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/attributes.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/attributes.html' is deprecated, extend '_base/docstring/attributes.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/attributes.html' is deprecated, extend '_base/docstring/attributes.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html.jinja
index ad798971..e8804310 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/attributes.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug() }}
{% endblock %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -33,6 +34,7 @@ Context:
{{ attribute.name }}
{% if attribute.annotation %}
{% with expression = attribute.annotation %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
({% include "expression"|get_template with context %}
)
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html
index eae60aa7..02261331 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/other_parameters.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/other_parameters.html' is deprecated, extend '_base/docstring/other_parameters.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/other_parameters.html' is deprecated, extend '_base/docstring/other_parameters.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html.jinja
index 657b21b4..6605e48d 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/other_parameters.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug() }}
{% endblock %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -33,6 +34,7 @@ Context:
{{ parameter.name }}
{% if parameter.annotation %}
{% with expression = parameter.annotation, backlink_type = "used-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
({% include "expression"|get_template with context %}
)
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html
index f5745464..f5292150 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/parameters.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/parameters.html' is deprecated, extend '_base/docstring/parameters.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/parameters.html' is deprecated, extend '_base/docstring/parameters.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html.jinja
index 6017a8cb..de01dcbe 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/parameters.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug() }}
{% endblock %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -33,9 +34,11 @@ Context:
{{ parameter.name }}
{% if parameter.annotation %}
{% with expression = parameter.annotation, backlink_type = "used-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
({% include "expression"|get_template with context %}
{%- if parameter.default %}, {{ lang.t("default:") }}
{% with expression = parameter.default, backlink_type = "used-by" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% endwith %}
{% endif %})
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html
index 361b9732..38a21e89 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/raises.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/raises.html' is deprecated, extend '_base/docstring/raises.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/raises.html' is deprecated, extend '_base/docstring/raises.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html.jinja
index 11f695e8..cf7d0b01 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/raises.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug() }}
{% endblock %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -32,6 +33,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html
index e5a115c1..d9c404b6 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/receives.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/receives.html' is deprecated, extend '_base/docstring/receives.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/receives.html' is deprecated, extend '_base/docstring/receives.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html.jinja
index aec9a858..84d6c1bc 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/receives.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug() }}
{% endblock %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -34,6 +35,7 @@ Context:
{% if receives.annotation %}
{% with expression = receives.annotation, backlink_type = "received-by" %}
{% if receives.name %}({% endif %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% if receives.name %}){% endif %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html
index 0e7807ac..b608af5f 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/returns.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/returns.html' is deprecated, extend '_base/docstring/returns.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/returns.html' is deprecated, extend '_base/docstring/returns.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html.jinja
index 3f8bbba4..c1171c7e 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/returns.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug() }}
{% endblock %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -34,6 +35,7 @@ Context:
{% if returns.annotation %}
{% with expression = returns.annotation, backlink_type = "returned-by" %}
{% if returns.name %}({% endif %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% if returns.name %}){% endif %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html
index b7b937a9..9eba72ab 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/warns.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/warns.html' is deprecated, extend '_base/docstring/warns.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/warns.html' is deprecated, extend '_base/docstring/warns.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html.jinja
index 1d465ec9..5570ca37 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/warns.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug() }}
{% endblock %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -32,6 +33,7 @@ Context:
{% include "expression"|get_template with context %}
{% endwith %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html
index ecd6f513..6ec31dd0 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/yields.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/docstring/yields.html' is deprecated, extend '_base/docstring/yields.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/yields.html' is deprecated, extend '_base/docstring/yields.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html.jinja
index 70c782b3..712776fe 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/docstring/yields.html.jinja
@@ -15,6 +15,7 @@ Context:
{{ log.debug() }}
{% endblock %}
+{# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "language"|get_template as lang with context %}
{#- Language module providing the `t` translation method. -#}
@@ -34,6 +35,7 @@ Context:
{% if yields.annotation %}
{% with expression = yields.annotation, backlink_type = "yielded-by" %}
{% if yields.name %}({% endif %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% include "expression"|get_template with context %}
{% if yields.name %}){% endif %}
{% endwith %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html
index c97d0c31..a5a86545 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/language.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/language.html' is deprecated, extend '_base/language.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/language.html' is deprecated, extend '_base/language.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html.jinja b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html.jinja
index 21163f47..5a4b773e 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/language.html.jinja
@@ -7,12 +7,15 @@
-#}
{% endblock logs %}
+{# YORE: Bump 2: Replace `| get_template` with `~ ".html.jinja"` within line. #}
{% set lang_pth = "languages/" ~ locale | get_template %}
{% if lang_pth is existing_template %}
{% import lang_pth as lang %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "languages/en"|get_template as fallback %}
{% macro t(key) %}{{ lang.t(key) or fallback.t(key) }}{% endmacro %}
{% else %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
{% import "languages/en"|get_template as lang %}
{% macro t(key) %}{{ lang.t(key) }}{% endmacro %}
{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/en.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/en.html
index eab87415..2f050a32 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/en.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/en.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/languages/en.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/languages/en.html' is deprecated, extend '_base/languages/en.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/languages/en.html' is deprecated, extend '_base/languages/en.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/ja.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/ja.html
index 14319499..1f3095f4 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/ja.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/ja.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/languages/ja.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/languages/ja.html' is deprecated, extend '_base/languages/ja.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/languages/ja.html' is deprecated, extend '_base/languages/ja.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/zh.html b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/zh.html
index 0b281195..b58b0479 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/zh.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/_base/languages/zh.html
@@ -1,11 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/languages/zh.html.jinja" %}
{% block logs scoped %}
{{ super() }}
- {# TODO: Switch to a warning after some time. #}
- {{ log.info(
- "DeprecationWarning: Extending '_base/languages/zh.html' is deprecated, extend '_base/languages/zh.html.jinja' instead. " ~
- "After some time, this message will be logged as a warning, causing strict builds to fail.",
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/languages/zh.html' is deprecated, extend '_base/languages/zh.html.jinja' instead. ",
once=True,
) }}
{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/attributes.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/attributes.html
index 4ac364b0..6a67cafb 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/attributes.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/attributes.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/attributes.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/other_parameters.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/other_parameters.html
index 7c50379b..a7024661 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/other_parameters.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/other_parameters.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/other_parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/parameters.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/parameters.html
index 70c557fb..fb49b54d 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/parameters.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/parameters.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/raises.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/raises.html
index f8c3cf03..1365fc5e 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/raises.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/raises.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/raises.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/receives.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/receives.html
index 004ff00e..9521ee68 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/receives.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/receives.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/receives.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/returns.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/returns.html
index 979ce9ef..93413ed8 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/returns.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/returns.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/returns.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/warns.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/warns.html
index bb06cc85..95523fde 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/warns.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/warns.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/warns.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/yields.html b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/yields.html
index 717ef5d4..58bccc7b 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/yields.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/docstring/yields.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/docstring/yields.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/language.html b/src/mkdocstrings_handlers/python/templates/readthedocs/language.html
index b905cff4..6da4f8df 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/language.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/language.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/language.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/languages/en.html b/src/mkdocstrings_handlers/python/templates/readthedocs/languages/en.html
index 931967c1..bcc4121e 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/languages/en.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/languages/en.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/languages/en.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/languages/ja.html b/src/mkdocstrings_handlers/python/templates/readthedocs/languages/ja.html
index 17070edf..87827f60 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/languages/ja.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/languages/ja.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/languages/ja.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/readthedocs/languages/zh.html b/src/mkdocstrings_handlers/python/templates/readthedocs/languages/zh.html
index e4ea3116..37c36ff0 100644
--- a/src/mkdocstrings_handlers/python/templates/readthedocs/languages/zh.html
+++ b/src/mkdocstrings_handlers/python/templates/readthedocs/languages/zh.html
@@ -1 +1,2 @@
+{# YORE: Bump 2: Remove file. #}
{% extends "_base/languages/zh.html.jinja" %}
diff --git a/tests/conftest.py b/tests/conftest.py
index 5b2dd33f..926c4b83 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -17,7 +17,7 @@
from mkdocs.config.defaults import MkDocsConfig
from mkdocstrings import MkdocstringsPlugin
- from mkdocstrings_handlers.python.handler import PythonHandler
+ from mkdocstrings_handlers.python import PythonHandler
# --------------------------------------------
diff --git a/tests/helpers.py b/tests/helpers.py
index b0dc6ad7..d7fb7e1d 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -16,7 +16,7 @@
import pytest
from mkdocstrings import MkdocstringsPlugin
- from mkdocstrings_handlers.python.handler import PythonHandler
+ from mkdocstrings_handlers.python import PythonHandler
@contextmanager
diff --git a/tests/snapshots/__init__.py b/tests/snapshots/__init__.py
index 712cdafe..36eb97b7 100644
--- a/tests/snapshots/__init__.py
+++ b/tests/snapshots/__init__.py
@@ -8,12 +8,12 @@
("separate_signature", True),
("show_signature_annotations", False),
("signature_crossrefs", False),
- ): external("4370d843cc76*.html"),
+ ): external("d03d16d1919a*.html"),
(
("separate_signature", True),
("show_signature_annotations", True),
("signature_crossrefs", True),
- ): external("261a38d7a86b*.html"),
+ ): external("e412376be64f*.html"),
(
("separate_signature", False),
("show_signature_annotations", True),
@@ -33,12 +33,12 @@
("separate_signature", True),
("show_signature_annotations", True),
("signature_crossrefs", False),
- ): external("f5ce06acbb7a*.html"),
+ ): external("74ee37cd1e94*.html"),
(
("separate_signature", True),
("show_signature_annotations", False),
("signature_crossrefs", True),
- ): external("9c0bfc0ee407*.html"),
+ ): external("4041a38e355f*.html"),
(
("separate_signature", False),
("show_signature_annotations", True),
@@ -353,5 +353,53 @@
("inherited_members", ()),
("members", ()),
): external("a185e216dc7b*.html"),
+ (("filters", "public"), ("inherited_members", ("method1",)), ("members", None)): external("6af55596d9c4*.html"),
+ (("filters", "public"), ("inherited_members", ("method1",)), ("members", False)): external(
+ "6abf5ddd819b*.html",
+ ),
+ (("filters", "public"), ("inherited_members", ()), ("members", None)): external("6d72c524b827*.html"),
+ (("filters", "public"), ("inherited_members", False), ("members", False)): external("9dab67183389*.html"),
+ (("filters", "public"), ("inherited_members", ("method1",)), ("members", True)): external("6c0b7207df03*.html"),
+ (("filters", "public"), ("inherited_members", True), ("members", ())): external("f48d651b3f1a*.html"),
+ (("filters", "public"), ("inherited_members", ("method1",)), ("members", ("module_attribute",))): external(
+ "408244423577*.html",
+ ),
+ (("filters", "public"), ("inherited_members", True), ("members", None)): external("16295fa51a2c*.html"),
+ (("filters", "public"), ("inherited_members", True), ("members", True)): external("37232379c426*.html"),
+ (("filters", "public"), ("inherited_members", ()), ("members", ())): external("2e866eca9a45*.html"),
+ (("filters", "public"), ("inherited_members", True), ("members", False)): external("ed5d07bcdbaa*.html"),
+ (("filters", "public"), ("inherited_members", False), ("members", ())): external("135f57223e00*.html"),
+ (("filters", "public"), ("inherited_members", False), ("members", None)): external("b4e20d5cd52e*.html"),
+ (("filters", "public"), ("inherited_members", ()), ("members", False)): external("46daa7e60b98*.html"),
+ (("filters", "public"), ("inherited_members", False), ("members", True)): external("a255ee80bf7a*.html"),
+ (("filters", "public"), ("inherited_members", ()), ("members", True)): external("74e2496015e1*.html"),
+ (("filters", "public"), ("inherited_members", True), ("members", ("module_attribute",))): external(
+ "e254ae60f9af*.html",
+ ),
+ (("filters", "public"), ("inherited_members", ("method1",)), ("members", ())): external("51d73351dc55*.html"),
+ (("filters", "public"), ("inherited_members", ()), ("members", ("module_attribute",))): external(
+ "d56d3aeae22b*.html",
+ ),
+ (("filters", "public"), ("inherited_members", False), ("members", ("module_attribute",))): external(
+ "80399c502938*.html",
+ ),
+ (("heading", ""), ("members", False), ("separate_signature", False), ("show_if_no_docstring", True)): external(
+ "d1dd339f9260*.html",
+ ),
+ (
+ ("heading", "Some heading"),
+ ("members", False),
+ ("separate_signature", True),
+ ("show_if_no_docstring", True),
+ ): external("480324b25439*.html"),
+ (("heading", ""), ("members", False), ("separate_signature", True), ("show_if_no_docstring", True)): external(
+ "2eef87791b97*.html",
+ ),
+ (
+ ("heading", "Some heading"),
+ ("members", False),
+ ("separate_signature", False),
+ ("show_if_no_docstring", True),
+ ): external("51deee0f00f3*.html"),
},
)
diff --git a/tests/snapshots/external/135f57223e006849dcdd1463367127e4c5ee4aba5f12bde17ab3e494dbeed490.html b/tests/snapshots/external/135f57223e006849dcdd1463367127e4c5ee4aba5f12bde17ab3e494dbeed490.html
new file mode 100644
index 00000000..e8d65a7e
--- /dev/null
+++ b/tests/snapshots/external/135f57223e006849dcdd1463367127e4c5ee4aba5f12bde17ab3e494dbeed490.html
@@ -0,0 +1,22 @@
+
+
+
+ members_package
+
+ + Docstring for the package. +
+
+ members_package
+
+ + Docstring for the package. +
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+ Class
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+ NestedClass
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+ Subclass
+
+
+ Bases:
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+ NestedClass
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+ members_package
+
+ + Docstring for the package. +
+
+ members_package
+
+ + Docstring for the package. +
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+ Class
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+ NestedClass
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+ Subclass
+
+
+ Bases:
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+ NestedClass
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
__init__(a, b)
+ __init__(a, b)
+ members_package
+
+ + Docstring for the package. +
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+ members_package
+
+ + Docstring for the package. +
+
+ members_package
+
+ + Docstring for the package. +
+
+ members_package
+
+ + Docstring for the package. +
+
+ members_package
+
+ + Docstring for the package. +
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+ Class
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+ NestedClass
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+ Subclass
+
+
+ Bases:
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+ members_package
+
+ + Docstring for the package. +
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+ Class
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+ NestedClass
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+ Subclass
+
+
+ Bases:
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+ members_package
+
+ + Docstring for the package. +
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+ Class
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+ NestedClass
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+ Subclass
+
+
+ Bases:
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+ members_package
+
+ + Docstring for the package. +
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+ Class
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+ NestedClass
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+ Subclass
+
+
+ Bases:
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
__init__(a: int, b: str) -> None
+ __init__(a: int, b: str) -> None
+ members_package
+
+ + Docstring for the package. +
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+ members_package
+
+ + Docstring for the package. +
+
+ members_package
+
+ + Docstring for the package. +
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+ Class
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+ NestedClass
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+ Subclass
+
+
+ Bases:
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
+ members_package
+
+ + Docstring for the package. +
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+ Class
+
+
+ Docstring for
+
+ Class
+
+ .
+
+
+ class_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ class-attribute
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.class_attribute
+
+ .
+
+
+ instance_attribute
+
+
+ =
+
+
+ a
+
+
+ +
+
+
+ b
+
+
+
+
+
+ instance-attribute
+
+
+
+
+ Docstring for
+
+ Class.instance_attribute
+
+ .
+
+ NestedClass
+
+
+ Docstring for
+
+ NestedClass
+
+ .
+
+
+ __init__
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.__init__
+
+ .
+
+
+ method1
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method1
+
+ .
+
+
+ method2
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ Class.method2
+
+ .
+
+ Subclass
+
+
+ Bases:
+
+
+
+ Docstring for
+
+ Subclass
+
+ .
+
+
+ module_function
+
+
+ (
+
+
+ a
+
+
+ ,
+
+
+ b
+
+
+ )
+
+
+
+ Docstring for
+
+ module_function
+
+ .
+
__init__(a, b)
+ __init__(a, b)
+ headings_package
+
+
+ members_package
+
+ + Docstring for the package. +
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
+ members_package
+
+ + Docstring for the package. +
+
+
+ module_attribute
+
+
+ =
+
+
+ 42
+
+
+
+
+
+ module-attribute
+
+
+
+
+ Docstring for
+
+ module_attribute
+
+ .
+
__init__(a: int , b: str ) -> None
+ __init__(a: int , b: str ) -> None
+ members_package
+
+ + Docstring for the package. +
+
+ members_package
+
+ + Docstring for the package. +
+