Skip to content

Commit 162d571

Browse files
refactor: Update get_template filter to support both *.html and *.html.jinja templates, logging a message (info) when *.html templates are overridden by users
Issue-151: mkdocstrings/python#151
1 parent 57b2ec5 commit 162d571

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

Diff for: src/mkdocstrings_handlers/python/handler.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ def collect(self, identifier: str, config: Mapping[str, Any]) -> CollectorItem:
333333
def render(self, data: CollectorItem, config: Mapping[str, Any]) -> str: # noqa: D102 (ignore missing docstring)
334334
final_config = ChainMap(config, self.default_config) # type: ignore[arg-type]
335335

336-
template_name = rendering.do_get_template(data)
336+
template_name = rendering.do_get_template(self.env, data)
337337
template = self.env.get_template(template_name)
338338

339339
# Heading level is a "state" variable, that will change at each step

Diff for: src/mkdocstrings_handlers/python/rendering.py

+42-8
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,23 @@
99
import sys
1010
import warnings
1111
from functools import lru_cache, partial
12+
from pathlib import Path
1213
from typing import TYPE_CHECKING, Any, Callable, Match, Pattern, Sequence
1314

15+
from griffe.dataclasses import Alias, Object
1416
from griffe.docstrings.dataclasses import (
1517
DocstringSectionAttributes,
1618
DocstringSectionClasses,
1719
DocstringSectionFunctions,
1820
DocstringSectionModules,
1921
)
20-
from jinja2 import pass_context
22+
from jinja2 import TemplateNotFound, pass_context, pass_environment
2123
from markupsafe import Markup
2224
from mkdocstrings.loggers import get_logger
2325

2426
if TYPE_CHECKING:
25-
from griffe.dataclasses import Alias, Attribute, Class, Function, Module, Object
27+
from griffe.dataclasses import Attribute, Class, Function, Module
28+
from jinja2 import Environment, Template
2629
from jinja2.runtime import Context
2730
from mkdocstrings.handlers.base import CollectorItem
2831

@@ -137,7 +140,8 @@ def do_format_signature(
137140
The same code, formatted.
138141
"""
139142
env = context.environment
140-
template = env.get_template("signature.html")
143+
# TODO: Stop using `do_get_template` when `*.html` templates are removed.
144+
template = env.get_template(do_get_template(env, "signature"))
141145
config_annotations = context.parent["config"]["show_signature_annotations"]
142146
old_stash_ref_filter = env.filters["stash_crossref"]
143147

@@ -204,7 +208,8 @@ def do_format_attribute(
204208
The same code, formatted.
205209
"""
206210
env = context.environment
207-
template = env.get_template("expression.html")
211+
# TODO: Stop using `do_get_template` when `*.html` templates are removed.
212+
template = env.get_template(do_get_template(env, "expression"))
208213
annotations = context.parent["config"]["show_signature_annotations"]
209214
separate_signature = context.parent["config"]["separate_signature"]
210215
old_stash_ref_filter = env.filters["stash_crossref"]
@@ -448,17 +453,46 @@ def formatter(code: str, line_length: int) -> str:
448453
return formatter
449454

450455

451-
def do_get_template(obj: Object) -> str:
456+
@pass_environment
457+
def do_get_template(env: Environment, obj: str | Object) -> str | Template:
452458
"""Get the template name used to render an object.
453459
454460
Parameters:
455-
obj: A Griffe object.
461+
env: The Jinja environment, passed automatically.
462+
obj: A Griffe object, or a template name.
456463
457464
Returns:
458465
A template name.
459466
"""
460-
extra_data = getattr(obj, "extra", {}).get("mkdocstrings", {})
461-
return extra_data.get("template", "") or f"{obj.kind.value}.html"
467+
name = obj
468+
if isinstance(obj, (Alias, Object)):
469+
extra_data = getattr(obj, "extra", {}).get("mkdocstrings", {})
470+
if name := extra_data.get("template", ""):
471+
return name
472+
name = obj.kind.value
473+
try:
474+
template = env.get_template(f"{name}.html")
475+
except TemplateNotFound:
476+
return f"{name}.html.jinja"
477+
else:
478+
# TODO: Remove once support for Python 3.8 is dropped.
479+
if sys.version_info < (3, 9):
480+
try:
481+
Path(template.filename).relative_to(Path(__file__).parent) # type: ignore[arg-type]
482+
except ValueError:
483+
our_template = False
484+
else:
485+
our_template = True
486+
else:
487+
our_template = Path(template.filename).is_relative_to(Path(__file__).parent) # type: ignore[arg-type]
488+
if not our_template:
489+
# TODO: Switch to a warning log after some time.
490+
logger.info(
491+
f"DeprecationWarning: Overriding '{name}.html' is deprecated, override '{name}.html.jinja' instead. "
492+
"After some time, this message will be logged as a warning, causing strict builds to fail.",
493+
once=True,
494+
)
495+
return f"{name}.html"
462496

463497

464498
@pass_context

0 commit comments

Comments
 (0)