', 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
+
+
def do_order_members(
members: Sequence[Object | Alias],
order: Order | list[Order],
@@ -592,7 +660,7 @@ def do_get_template(env: Environment, obj: str | Object) -> str:
extra_data = getattr(obj, "extra", {}).get("mkdocstrings", {})
if name := extra_data.get("template", ""):
return name
- name = obj.kind.value
+ name = obj.kind.value.replace(" ", "_")
# YORE: Bump 2: Replace block with `return f"{name}.html.jinja"`.
try:
template = env.get_template(f"{name}.html")
@@ -732,6 +800,34 @@ def do_as_modules_section(
)
+@pass_context
+def do_as_type_aliases_section(
+ context: Context, # noqa: ARG001
+ type_aliases: Sequence[TypeAlias],
+ *,
+ check_public: bool = True,
+) -> DocstringSectionTypeAliases:
+ """Build a type aliases section from a list of type aliases.
+
+ Parameters:
+ type_aliases: The type aliases to build the section from.
+ check_public: Whether to check if the type_alias is public.
+
+ Returns:
+ A type aliases docstring section.
+ """
+ return DocstringSectionTypeAliases(
+ [
+ DocstringTypeAlias(
+ name=type_alias.name,
+ description=type_alias.docstring.value.split("\n", 1)[0] if type_alias.docstring else "",
+ )
+ for type_alias in type_aliases
+ if not check_public or type_alias.is_public
+ ],
+ )
+
+
class AutorefsHook(AutorefsHookInterface):
"""Autorefs hook.
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 0538aa9a..3be0a33a 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja
@@ -57,6 +57,26 @@ Context:
{% endif %}
{% endwith %}
+ {% with type_aliases = obj.type_aliases|filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=config.inherited_members,
+ keep_no_docstrings=config.show_if_no_docstring,
+ ) %}
+ {% if type_aliases %}
+ {% if config.show_category_heading %}
+ {% filter heading(heading_level, id=html_id ~ "-type_aliases") %}Type Aliases{% endfilter %}
+ {% endif %}
+ {% with heading_level = heading_level + extra_level %}
+ {% for type_alias in type_aliases|order_members(config.members_order, members_list) %}
+ {% if config.filters == "public" or members_list is not none or (not type_alias.is_imported or type_alias.is_public) %}
+ {% include type_alias|get_template with context %}
+ {% endif %}
+ {% endfor %}
+ {% endwith %}
+ {% endif %}
+ {% endwith %}
+
{% with classes = obj.classes|filter_objects(
filters=config.filters,
members_list=members_list,
@@ -143,6 +163,11 @@ Context:
{% include attribute|get_template with context %}
{% endwith %}
+ {% elif child.is_type_alias %}
+ {% with type_alias = child %}
+ {% include type_alias|get_template with context %}
+ {% endwith %}
+
{% elif child.is_class %}
{% with class = child %}
{% include class|get_template with context %}
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 f366f497..23b3f458 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/class.html.jinja
@@ -54,12 +54,18 @@ Context:
{{ 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) %}
+ {{ class_name -}}
+ {%- with obj = function -%}
+ {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#}
+ {%- include "type_parameters"|get_template with context -%}
+ {%- endwith -%}
{#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#}
- {{ class_name }}{% include "signature"|get_template with context %}
- {%- endfilter %}
+ {%- include "signature"|get_template with context -%}
+ {% endfilter %}
{% endwith %}
{% else %}
+ {# TODO: Maybe render type parameters here. #}
{{ class_name }}
{% endif %}
{% endblock heading %}
@@ -83,26 +89,30 @@ Context:
This block renders the signature for the class.
Overloads of the `__init__` method are rendered if `merge_init_into_class` is enabled.
The actual `__init__` method signature is only rendered if `separate_signature` is also enabled.
+
+ If the class is generic, but the `__init__` method isn't or `merge_init_into_class` is disabled,
+ the class signature is rendered if `separate_signature` and `show_signature_type_parameters` are enabled.
+
+ If the `__init__` method or any overloads are generic, they are rendered as methods if
+ `merge_init_into_class`, `separate_signature` and `show_signature_type_parameters` are enabled.
-#}
- {% if config.merge_init_into_class %}
- {% if "__init__" in all_members %}
- {% with function = all_members["__init__"] %}
- {% if function.overloads and config.show_overloads %}
-
- {% for overload in function.overloads %}
- {% filter format_signature(overload, config.line_length, annotations=True, crossrefs=config.signature_crossrefs) %}
- {{ class.name }}
- {% endfilter %}
- {% endfor %}
-
- {% endif %}
- {% if config.separate_signature %}
- {% filter format_signature(function, config.line_length, crossrefs=config.signature_crossrefs) %}
- {{ class.name }}
- {% endfilter %}
- {% endif %}
- {% endwith %}
- {% endif %}
+ {% if config.merge_init_into_class and "__init__" in all_members %}
+ {% with function = all_members["__init__"] %}
+ {% if function.overloads and config.show_overloads %}
+
+ {% for overload in function.overloads %}
+ {% filter format_signature(overload, config.line_length, annotations=True, crossrefs=config.signature_crossrefs) %}
+ {{ class.name }}
+ {% endfilter %}
+ {% endfor %}
+
+ {% endif %}
+ {% if config.separate_signature and not (config.show_overloads and function.overloads and config.overloads_only) %}
+ {% filter format_signature(function, config.line_length, crossrefs=config.signature_crossrefs) %}
+ {{ class.name }}
+ {% endfilter %}
+ {% endif %}
+ {% endwith %}
{% endif %}
{% endblock signature %}
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 c560668e..cae4f50f 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring.html.jinja
@@ -32,9 +32,15 @@ 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_type_aliases and section.kind.value == "type aliases" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
+ {% include "docstring/type_aliases"|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_type_parameters and section.kind.value == "type parameters" %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
+ {% include "docstring/type_parameters"|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 %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html
new file mode 100644
index 00000000..e9a99d1b
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html
@@ -0,0 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
+{% extends "_base/docstring/type_aliases.html.jinja" %}
+
+{% block logs scoped %}
+ {{ super() }}
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/type_aliases.html' is deprecated, extend '_base/docstring/type_aliases.html.jinja' instead. ",
+ once=True,
+ ) }}
+{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html.jinja
new file mode 100644
index 00000000..ceaa520c
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_aliases.html.jinja
@@ -0,0 +1,86 @@
+{#- Template for "Type Aliases" sections in docstrings.
+
+This template renders a list of documented type aliases in the format
+specified with the [`docstring_section_style`][] configuration option.
+
+Context:
+ section (griffe.DocstringSectionTypeAliases): The section to render.
+-#}
+
+{% block logs scoped %}
+ {#- Logging block.
+
+ This block can be used to log debug messages, deprecation messages, warnings, etc.
+ -#}
+ {{ log.debug("Rendering type aliases section") }}
+{% endblock logs %}
+
+{% import "language"|get_template as lang with context %}
+{#- Language module providing the `t` translation method. -#}
+
+{% if config.docstring_section_style == "table" %}
+ {% block table_style scoped %}
+ {#- Block for the `table` section style. -#}
+ {{ section.title or lang.t("Type Aliases:") }}
+
+
+
+ {{ lang.t("Name") }} |
+ {{ lang.t("Description") }} |
+
+
+
+ {% for type_alias in section.value %}
+
+ {{ type_alias.name }} |
+
+
+ {{ type_alias.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
+
+ |
+
+ {% endfor %}
+
+
+ {% endblock table_style %}
+{% elif config.docstring_section_style == "list" %}
+ {% block list_style scoped %}
+ {#- Block for the `list` section style. -#}
+ {{ section.title or lang.t("Type Aliases:") }}
+
+ {% endblock list_style %}
+{% elif config.docstring_section_style == "spacy" %}
+ {% block spacy_style scoped %}
+ {#- Block for the `spacy` section style. -#}
+
+
+
+ {{ (section.title or lang.t("TYPE ALIAS")).rstrip(":").upper() }} |
+ {{ lang.t("DESCRIPTION") }} |
+
+
+
+ {% for type_alias in section.value %}
+
+ {{ type_alias.name }} |
+
+
+ {{ type_alias.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
+
+ |
+
+ {% endfor %}
+
+
+ {% endblock spacy_style %}
+{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html
new file mode 100644
index 00000000..90a1af38
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html
@@ -0,0 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
+{% extends "_base/docstring/type_parameters.html.jinja" %}
+
+{% block logs scoped %}
+ {{ super() }}
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/docstring/type_parameters.html' is deprecated, extend '_base/docstring/type_parameters.html.jinja' instead. ",
+ once=True,
+ ) }}
+{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html.jinja
new file mode 100644
index 00000000..8e83e8be
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/docstring/type_parameters.html.jinja
@@ -0,0 +1,208 @@
+{#- Template for "Parameters" sections in docstrings.
+
+This template renders a list of documented type parameters in the format
+specified with the [`docstring_section_style`][] configuration option.
+
+Context:
+ section (griffe.DocstringSectionTypeParameters): The section to render.
+-#}
+
+{% block logs scoped %}
+ {#- Logging block.
+
+ This block can be used to log debug messages, deprecation messages, warnings, etc.
+ -#}
+ {{ log.debug("Rendering type parameters section") }}
+{% endblock logs %}
+
+{% import "language"|get_template as lang with context %}
+{#- Language module providing the `t` translation method. -#}
+
+{% if config.docstring_section_style == "table" %}
+ {% block table_style scoped %}
+ {#- Block for the `table` section style. -#}
+
+
+ {{ section.title or lang.t(("Class " if obj.is_class else "Init " if obj.is_init_method else "") ~ "Type Parameters:") }}
+
+
+
+
+
+ {{ lang.t("Name") }} |
+ {{ lang.t("Bound or Constraints") }} |
+ {{ lang.t("Description") }} |
+ {{ lang.t("Default") }} |
+
+
+
+ {% for type_parameter in section.value %}
+
+
+ {% if config.type_parameter_headings %}
+ {% filter heading(
+ heading_level + 1,
+ role="typeparam",
+ id=obj.path ~ "[" ~ type_parameter.name ~ "]",
+ class="doc doc-heading doc-heading-type_parameter",
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + type_parameter.name,
+ ) %}
+ {{ type_parameter.name }}
+ {% endfilter %}
+ {% else %}
+ {{ type_parameter.name }}
+ {% endif %}
+ |
+
+ {% if type_parameter.annotation %}
+ {% with expression = type_parameter.annotation %}
+ {% include "expression"|get_template with context %}
+ {% endwith %}
+ {% endif %}
+ |
+
+
+ {{ type_parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
+
+ |
+
+ {% if type_parameter.default %}
+ {% with expression = type_parameter.default %}
+ {% include "expression"|get_template with context %}
+ {% endwith %}
+ {% else %}
+ {{ lang.t("required") }}
+ {% endif %}
+ |
+
+ {% endfor %}
+
+
+ {% endblock table_style %}
+{% elif config.docstring_section_style == "list" %}
+ {% block list_style scoped %}
+ {#- Block for the `list` section style. -#}
+
+
+ {{ section.title or lang.t(("Class " if obj.is_class else "Init " if obj.is_init_method else "") ~ "Type Parameters:") }}
+
+
+
+ {% endblock list_style %}
+{% elif config.docstring_section_style == "spacy" %}
+ {% block spacy_style scoped %}
+ {#- Block for the `spacy` section style. -#}
+
+
+
+
+
+ {{ (section.title or lang.t(("CLASS " if obj.is_class else "INIT " if obj.is_init_method else "") ~ "TYPE PARAMETER")).rstrip(":").upper() }}
+
+ |
+ {{ lang.t("DESCRIPTION") }} |
+
+
+
+ {% for type_parameter in section.value %}
+
+
+ {% if config.type_parameter_headings %}
+ {% filter heading(
+ heading_level + 1,
+ role="typeparam",
+ id=obj.path ~ "[" ~ type_parameter.name ~ "]",
+ class="doc doc-heading doc-heading-type_parameter",
+ toc_label=(' '|safe if config.show_symbol_type_toc else '') + type_parameter.name,
+ ) %}
+ {{ type_parameter.name }}
+ {% endfilter %}
+ {% else %}
+ {{ type_parameter.name }}
+ {% endif %}
+ |
+
+
+ {{ type_parameter.description|convert_markdown(heading_level, html_id, autoref_hook=autoref_hook) }}
+
+
+ {% if type_parameter.constraints %}
+
+ {{ lang.t("CONSTRAINTS:") }}
+ {% for constraint in type_parameter.constraints -%}
+ {%- with expression = constraint -%}
+ {% include "expression"|get_template with context %}
+ {%- endwith -%}
+ {%- if not loop.last %}, {% endif -%}
+ {% endfor %}
+
+ {% elif type_parameter.bound %}
+
+ {{ lang.t("BOUND:") }}
+ {% with expression = type_parameter.bound %}
+ {% include "expression"|get_template with context %}
+ {% endwith %}
+
+ {% endif %}
+ {% if type_parameter.default %}
+
+ {{ lang.t("DEFAULT:") }}
+ {% with expression = type_parameter.default %}
+ {% include "expression"|get_template with context %}
+ {% endwith %}
+
+ {% endif %}
+
+ |
+
+ {% endfor %}
+
+
+ {% endblock spacy_style %}
+{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja
index d49e43be..54781739 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/expression.html.jinja
@@ -2,6 +2,10 @@
This template renders a Griffe expression,
which is a tree-like structure representing a Python expression.
+
+Context:
+ expression (griffe.Expr): The expression to render.
+ config (dict): The configuration options.
-#}
{% block logs scoped %}
@@ -16,6 +20,25 @@ which is a tree-like structure representing a Python expression.
This macro outputs a cross-reference to the given name.
+ Parameters:
+ name (griffe.ExprName): The name to cross-reference.
+ annotation_path (str): Either "brief", "source", or "full".
+
+ Returns:
+ Either a cross-reference (using an autoref element) or the name itself.
+ -#}
+ {%- if name.classname == "ExprName" and name.is_type_parameter -%}
+ {{ type_param_crossref(name) }}
+ {%- else -%}
+ {{ object_crossref(name, annotation_path) }}
+ {%- endif -%}
+{%- endmacro -%}
+
+{%- macro object_crossref(name, annotation_path) -%}
+ {#- Output a cross-reference to a Griffe object.
+
+ This macro outputs a cross-reference to the given name.
+
Parameters:
name (griffe.ExprName): The name to cross-reference.
annotation_path (str): Either "brief", "source", or "full".
@@ -50,6 +73,26 @@ which is a tree-like structure representing a Python expression.
{%- endwith -%}
{%- endmacro -%}
+{%- macro type_param_crossref(name) -%}
+ {#- Render a cross-reference to a type parameter heading.
+
+ Parameters:
+ name (griffe.ExprName): The name to cross-reference.
+
+ Returns:
+ The autorefs cross-reference, or the type parameter name.
+ -#}
+ {%- if not signature -%}
+ {{ name.name }}
+ {%- elif config.signature_crossrefs -%}
+ {%- filter stash_crossref(length=name.name|length) -%}
+ {{ name.name }}
+ {%- endfilter -%}
+ {%- else -%}
+ {{ name.name }}
+ {%- endif -%}
+{%- endmacro -%}
+
{%- macro param_crossref(expression) -%}
{#- Render a cross-reference to a parameter heading.
@@ -89,7 +132,14 @@ which is a tree-like structure representing a Python expression.
{%- elif config.unwrap_annotated and expression.classname == "ExprSubscript" and expression.canonical_path in ("typing.Annotated", "typing_extensions.Annotated") -%}
{{ render(expression.slice.elements[0], annotations_path) }}
{%- elif expression.classname == "ExprAttribute" -%}
- {%- if annotations_path == "brief" -%}
+ {%- if expression.first.is_type_parameter -%}
+ {{ type_param_crossref(expression.first) }}
+ {%- for element in expression -%}
+ {%- if not loop.first -%}
+ {{ render(element, "brief") }}
+ {%- endif -%}
+ {%- endfor -%}
+ {%- elif annotations_path == "brief" -%}
{%- if expression.last.is_enum_value -%}
{{ crossref(expression.last.parent, "brief", backlink_type) }}.value
{%- else -%}
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 4c84006e..708fde68 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/function.html.jinja
@@ -61,8 +61,10 @@ Context:
{{ function_name }}
{% else %}
{%+ 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 %}
+ {{ function_name }}
+ {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within block. -#}
+ {%- include "type_parameters"|get_template with context -%}
+ {%- include "signature"|get_template with context -%}
{%- endfilter %}
{% endif %}
{% endblock heading %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html.jinja
index bcdcce2d..a2e38b7c 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/languages/en.html.jinja
@@ -10,8 +10,13 @@
{% macro t(key) %}{{ {
"ATTRIBUTE": "ATTRIBUTE",
"Attributes:": "Attributes:",
+ "BOUND:": "BOUND:",
+ "Bound or Constraints": "Bound or Constraints",
"Classes:": "Classes:",
+ "Class Type Parameters:": "Class Type Parameters:",
+ "CLASS TYPE PARAMETER": "CLASS TYPE PARAMETER",
"CLASS": "CLASS",
+ "CONSTRAINTS:": "CONSTRAINTS:",
"DEFAULT:": "DEFAULT:",
"Default": "Default",
"default:": "default:",
@@ -20,6 +25,8 @@
"Examples:": "Examples:",
"Functions:": "Functions:",
"FUNCTION": "FUNCTION",
+ "Init Type Parameters:": "Init Type Parameters:",
+ "INIT TYPE PARAMETER": "INIT TYPE PARAMETER",
"Methods:": "Methods:",
"METHOD": "METHOD",
"Modules:": "Modules:",
@@ -38,6 +45,10 @@
"Source code in": "Source code in",
"TYPE:": "TYPE:",
"Type": "Type",
+ "Type Aliases:": "Type Aliases:",
+ "TYPE ALIAS": "TYPE ALIAS",
+ "Type Parameters:": "Type Parameters:",
+ "TYPE PARAMETER": "TYPE PARAMETER",
"WARNS": "WARNS",
"Warns:": "Warns:",
"YIELDS": "YIELDS",
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html.jinja
index 0393ca03..be0dd62b 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/languages/ja.html.jinja
@@ -10,8 +10,13 @@
{% macro t(key) %}{{ {
"ATTRIBUTE": "属性",
"Attributes:": "属性:",
+ "BOUND:": "BOUND:",
+ "Bound or Constraints": "Bound or Constraints",
"Classes:": "クラス:",
- "CLASS": "クラス",
+ "Class Type Parameters:": "Class Type Parameters:",
+ "CLASS TYPE PARAMETER": "CLASS TYPE PARAMETER",
+ "CLASS": "CLASS",
+ "CONSTRAINTS:": "CONSTRAINTS:",
"DEFAULT:": "デフォルト:",
"Default": "デフォルト",
"default:": "デフォルト:",
@@ -20,6 +25,8 @@
"Examples:": "例:",
"Functions:": "関数:",
"FUNCTION": "関数",
+ "Init Type Parameters:": "Init Type Parameters:",
+ "INIT TYPE PARAMETER": "INIT TYPE PARAMETER",
"Methods:": "メソッド:",
"METHOD": "メソッド",
"Modules:": "モジュール:",
@@ -38,6 +45,10 @@
"Source code in": "ソースコード位置:",
"TYPE:": "タイプ:",
"Type": "タイプ",
+ "Type Aliases:": "Type Aliases:",
+ "TYPE ALIAS": "TYPE ALIAS",
+ "Type Parameters:": "Type Parameters:",
+ "TYPE PARAMETER": "TYPE PARAMETER",
"WARNS": "警告",
"Warns:": "警告:",
"YIELDS": "返す",
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html.jinja
index e57169ad..3f1e3481 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/languages/zh.html.jinja
@@ -10,8 +10,13 @@
{% macro t(key) %}{{ {
"ATTRIBUTE": "属性",
"Attributes:": "属性:",
+ "BOUND:": "BOUND:",
+ "Bound or Constraints": "Bound or Constraints",
"Classes:": "类:",
- "CLASS": "类",
+ "Class Type Parameters:": "Class Type Parameters:",
+ "CLASS TYPE PARAMETER": "CLASS TYPE PARAMETER",
+ "CLASS": "CLASS",
+ "CONSTRAINTS:": "CONSTRAINTS:",
"DEFAULT:": "默认:",
"Default": "默认",
"default:": "默认:",
@@ -20,6 +25,8 @@
"Examples:": "示例:",
"Functions:": "函数:",
"FUNCTION": "函数",
+ "Init Type Parameters:": "Init Type Parameters:",
+ "INIT TYPE PARAMETER": "INIT TYPE PARAMETER",
"Methods:": "方法:",
"METHOD": "方法",
"Modules:": "模块:",
@@ -38,6 +45,10 @@
"Source code in": "源代码位于:",
"TYPE:": "类型:",
"Type": "类型",
+ "Type Aliases:": "Type Aliases:",
+ "TYPE ALIAS": "TYPE ALIAS",
+ "Type Parameters:": "Type Parameters:",
+ "TYPE PARAMETER": "TYPE PARAMETER",
"Warns:": "警告:",
"WARNS": "警告",
"YIELDS": "产生",
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 78b0b9d7..477d0b0d 100644
--- a/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary.html.jinja
@@ -13,6 +13,11 @@
{% include "summary/modules"|get_template with context %}
{% endif %}
+ {% if config.summary.type_aliases %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
+ {% include "summary/type_aliases"|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 %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html b/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html
new file mode 100644
index 00000000..68554b8c
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html
@@ -0,0 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
+{% extends "_base/summary/type_aliases.html.jinja" %}
+
+{% block logs scoped %}
+ {{ super() }}
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/type_aliases/classes.html' is deprecated, extend '_base/type_aliases/classes.html.jinja' instead.",
+ once=True,
+ ) }}
+{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html.jinja
new file mode 100644
index 00000000..9ebc2b23
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/summary/type_aliases.html.jinja
@@ -0,0 +1,24 @@
+{#- Summary of type aliases. -#}
+
+{% block logs scoped %}
+ {#- Logging block.
+
+ This block can be used to log debug messages, deprecation messages, warnings, etc.
+ -#}
+{% endblock logs %}
+
+{% if not obj.docstring.parsed | selectattr("kind.value", "eq", "type aliases") | list %}
+ {% with section = obj.type_aliases
+ |filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=config.inherited_members,
+ keep_no_docstrings=config.show_if_no_docstring,
+ )
+ |order_members("alphabetical", members_list)
+ |as_type_aliases_section(check_public=not members_list)
+ %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
+ {% if section %}{% include "docstring/type_aliases"|get_template with context %}{% endif %}
+ {% endwith %}
+{% endif %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html b/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html
new file mode 100644
index 00000000..d811f7f3
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html
@@ -0,0 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
+{% extends "_base/type_alias.html.jinja" %}
+
+{% block logs scoped %}
+ {{ super() }}
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/type_alias.html' is deprecated, extend '_base/type_alias.html.jinja' instead. ",
+ once=True,
+ ) }}
+{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html.jinja
new file mode 100644
index 00000000..bb7d4d71
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/type_alias.html.jinja
@@ -0,0 +1,120 @@
+{#- Template for Python type aliases.
+
+This template renders a Python type alias.
+
+Context:
+ type_alias (griffe.TypeAlias): The type alias to render.
+ root (bool): Whether this is the root object, injected with `:::` in a Markdown page.
+ heading_level (int): The HTML heading level to use.
+ config (dict): The configuration options.
+-#}
+
+{% block logs scoped %}
+ {#- Logging block.
+
+ This block can be used to log debug messages, deprecation messages, warnings, etc.
+ -#}
+ {{ log.debug("Rendering " + type_alias.path) }}
+{% endblock logs %}
+
+
+ {% with obj = type_alias, html_id = type_alias.path %}
+
+ {% if root %}
+ {% set show_full_path = config.show_root_full_path %}
+ {% set root_members = True %}
+ {% elif root_members %}
+ {% set show_full_path = config.show_root_members_full_path or config.show_object_full_path %}
+ {% set root_members = False %}
+ {% else %}
+ {% set show_full_path = config.show_object_full_path %}
+ {% endif %}
+
+ {% set type_alias_name = type_alias.path if show_full_path else type_alias.name %}
+
+ {% if not root or config.show_root_heading %}
+ {% filter heading(
+ heading_level,
+ role="typealias",
+ id=html_id,
+ class="doc doc-heading",
+ toc_label=('
'|safe if config.show_symbol_type_toc else '') + type_alias.name,
+ ) %}
+
+ {% block heading scoped %}
+ {#- Heading block.
+
+ This block renders the heading for the type alias.
+ -#}
+ {% if config.show_symbol_type_heading %}
{% endif %}
+ {% if config.separate_signature %}
+
{{ type_alias_name }}
+ {% else %}
+ {%+ filter highlight(language="python", inline=True) %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
+ {{ type_alias_name }}{% include "type_parameters"|get_template with context %} = {{ type_alias.value }}
+ {% endfilter %}
+ {% endif %}
+ {% endblock heading %}
+
+ {% block labels scoped %}
+ {#- Labels block.
+
+ This block renders the labels for the type alias.
+ -#}
+ {% with labels = type_alias.labels %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
+ {% include "labels"|get_template with context %}
+ {% endwith %}
+ {% endblock labels %}
+
+ {% endfilter %}
+
+ {% block signature scoped %}
+ {#- Signature block.
+
+ This block renders the signature for the type alias.
+ -#}
+ {% if config.separate_signature %}
+ {% filter format_type_alias(type_alias, config.line_length, crossrefs=config.signature_crossrefs) %}
+ {{ type_alias.name }}
+ {% endfilter %}
+ {% endif %}
+ {% endblock signature %}
+
+ {% else %}
+ {% if config.show_root_toc_entry %}
+ {% filter heading(heading_level,
+ role="typealias",
+ id=html_id,
+ toc_label=('
'|safe if config.show_symbol_type_toc else '') + type_alias.name,
+ hidden=True,
+ ) %}
+ {% endfilter %}
+ {% endif %}
+ {% set heading_level = heading_level - 1 %}
+ {% endif %}
+
+
+ {% block contents scoped %}
+ {#- Contents block.
+
+ This block renders the contents of the type alias.
+ It contains other blocks that users can override.
+ Overriding the contents block allows to rearrange the order of the blocks.
+ -#}
+ {% block docstring scoped %}
+ {#- Docstring block.
+
+ This block renders the docstring for the type alias.
+ -#}
+ {% with docstring_sections = type_alias.docstring.parsed %}
+ {# YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. #}
+ {% include "docstring"|get_template with context %}
+ {% endwith %}
+ {% endblock docstring %}
+ {% endblock contents %}
+
+
+ {% endwith %}
+
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html b/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html
new file mode 100644
index 00000000..782b1e8b
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html
@@ -0,0 +1,10 @@
+{# YORE: Bump 2: Remove file. #}
+{% extends "_base/type_parameters.html.jinja" %}
+
+{% block logs scoped %}
+ {{ super() }}
+ {{ log.warning(
+ "DeprecationWarning: Extending '_base/type_parameters.html' is deprecated, extend '_base/type_parameters.html.jinja' instead.",
+ once=True,
+ ) }}
+{% endblock logs %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html.jinja
new file mode 100644
index 00000000..59fad354
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/_base/type_parameters.html.jinja
@@ -0,0 +1,89 @@
+{#- Template for type parameters.
+
+This template renders the type parameters of a generic obj.
+It iterates over the type parameters of the object to rebuild the signature.
+The signature is the list of type parameters of a generic object, including their names, default values, and bound or constraints.
+
+Context:
+ obj (griffe.Object): The object to render.
+ config (dict): The configuration options.
+-#}
+
+{%- if config.show_signature_type_parameters -%}
+ {%- block logs scoped -%}
+ {#- Logging block.
+
+ This block can be used to log debug messages, deprecation messages, warnings, etc.
+ -#}
+ {{ log.debug("Rendering type parameters") }}
+ {%- endblock logs -%}
+
+ {%- with ns = namespace(annotation="", equal="=", default=False) -%}
+ {%- if obj.is_generic -%}
+ [
+ {%- for type_parameter in obj.type_parameters -%}
+ {#- Prepare type bound or constraints. -#}
+ {%- if config.show_signature_annotations and type_parameter.annotation is not none -%}
+ {%- set ns.equal = " = " -%}
+ {%- if config.separate_signature and config.signature_crossrefs -%}
+ {%- with expression = type_parameter.annotation -%}
+ {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#}
+ {%- set ns.annotation -%}: {% include "expression"|get_template with context %}{%- endset -%}
+ {%- endwith -%}
+ {%- else -%}
+ {%- set ns.annotation = ": " + type_parameter.annotation|safe -%}
+ {%- endif -%}
+ {%- else -%}
+ {%- set ns.equal = "=" -%}
+ {%- set ns.annotation = "" -%}
+ {%- endif -%}
+
+ {#- Prepare default value. -#}
+ {%- if type_parameter.default is not none -%}
+ {%- set ns.default = True -%}
+ {%- else -%}
+ {%- set ns.default = False -%}
+ {%- endif -%}
+
+ {#- Prepare name. -#}
+ {%- set type_param_prefix -%}
+ {%- if type_parameter.kind == "type-var-tuple" -%}
+ *
+ {%- elif type_parameter.kind == "param-spec" -%}
+ **
+ {%- endif -%}
+ {%- endset -%}
+
+ {#- Render type parameter name with optional cross-reference to its heading. -#}
+ {{ type_param_prefix }}
+ {%- if config.separate_signature and config.type_parameter_headings and config.signature_crossrefs -%}
+ {%- filter stash_crossref(length=type_parameter.name|length) -%}
+ {{ type_parameter.name }}
+ {%- endfilter -%}
+ {%- else -%}
+ {{ type_parameter.name }}
+ {%- endif -%}
+
+ {#- Render type parameter bound or constraints. -#}
+ {{ ns.annotation }}
+
+ {#- Render type parameter default value. -#}
+ {%- if ns.default -%}
+ {{ ns.equal }}
+ {%- if config.signature_crossrefs and config.separate_signature -%}
+ {%- with expression = type_parameter.default -%}
+ {#- YORE: Bump 2: Replace `"|get_template` with `.html.jinja"` within line. -#}
+ {%- include "expression"|get_template with context -%}
+ {%- endwith -%}
+ {%- else -%}
+ {{ type_parameter.default|safe }}
+ {%- endif -%}
+ {%- endif -%}
+
+ {%- if not loop.last %}, {% endif -%}
+ {%- endfor -%}
+ ]
+ {%- endif -%}
+
+ {%- endwith -%}
+{%- endif -%}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html b/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html
new file mode 100644
index 00000000..78bd497a
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html
@@ -0,0 +1 @@
+{% extends "_base/docstring/type_aliases.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html.jinja b/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html.jinja
new file mode 100644
index 00000000..78bd497a
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/type_aliases.html.jinja
@@ -0,0 +1 @@
+{% extends "_base/docstring/type_aliases.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html b/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html
new file mode 100644
index 00000000..223fbb04
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html
@@ -0,0 +1 @@
+{% extends "_base/docstring/type_parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html.jinja
new file mode 100644
index 00000000..223fbb04
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/docstring/type_parameters.html.jinja
@@ -0,0 +1 @@
+{% extends "_base/docstring/type_parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/style.css b/src/mkdocstrings_handlers/python/templates/material/style.css
index b8c3e639..7475f5cd 100644
--- a/src/mkdocstrings_handlers/python/templates/material/style.css
+++ b/src/mkdocstrings_handlers/python/templates/material/style.css
@@ -26,12 +26,14 @@
}
/* Defaults in Spacy table style. */
-.doc-param-default {
+.doc-param-default,
+.doc-type_param-default {
float: right;
}
/* Parameter headings must be inline, not blocks. */
-.doc-heading-parameter {
+.doc-heading-parameter,
+.doc-heading-type_parameter {
display: inline;
}
@@ -41,7 +43,8 @@
}
/* Prefer space on the right, not the left of parameter permalinks. */
-.doc-heading-parameter .headerlink {
+.doc-heading-parameter .headerlink,
+.doc-heading-type_parameter .headerlink {
margin-left: 0 !important;
margin-right: 0.2rem;
}
@@ -77,33 +80,41 @@
:root, :host,
[data-md-color-scheme="default"] {
--doc-symbol-parameter-fg-color: #df50af;
+ --doc-symbol-type_parameter-fg-color: #df50af;
--doc-symbol-attribute-fg-color: #953800;
--doc-symbol-function-fg-color: #8250df;
--doc-symbol-method-fg-color: #8250df;
--doc-symbol-class-fg-color: #0550ae;
+ --doc-symbol-type_alias-fg-color: #0550ae;
--doc-symbol-module-fg-color: #5cad0f;
--doc-symbol-parameter-bg-color: #df50af1a;
+ --doc-symbol-type_parameter-bg-color: #df50af1a;
--doc-symbol-attribute-bg-color: #9538001a;
--doc-symbol-function-bg-color: #8250df1a;
--doc-symbol-method-bg-color: #8250df1a;
--doc-symbol-class-bg-color: #0550ae1a;
+ --doc-symbol-type_alias-bg-color: #0550ae1a;
--doc-symbol-module-bg-color: #5cad0f1a;
}
[data-md-color-scheme="slate"] {
--doc-symbol-parameter-fg-color: #ffa8cc;
+ --doc-symbol-type_parameter-fg-color: #ffa8cc;
--doc-symbol-attribute-fg-color: #ffa657;
--doc-symbol-function-fg-color: #d2a8ff;
--doc-symbol-method-fg-color: #d2a8ff;
--doc-symbol-class-fg-color: #79c0ff;
+ --doc-symbol-type_alias-fg-color: #79c0ff;
--doc-symbol-module-fg-color: #baff79;
--doc-symbol-parameter-bg-color: #ffa8cc1a;
+ --doc-symbol-type_parameter-bg-color: #ffa8cc1a;
--doc-symbol-attribute-bg-color: #ffa6571a;
--doc-symbol-function-bg-color: #d2a8ff1a;
--doc-symbol-method-bg-color: #d2a8ff1a;
--doc-symbol-class-bg-color: #79c0ff1a;
+ --doc-symbol-type_alias-bg-color: #79c0ff1a;
--doc-symbol-module-bg-color: #baff791a;
}
@@ -124,6 +135,16 @@ code.doc-symbol-parameter::after {
content: "param";
}
+code.doc-symbol-type_parameter,
+a code.doc-symbol-type_parameter {
+ color: var(--doc-symbol-type_parameter-fg-color);
+ background-color: var(--doc-symbol-type_parameter-bg-color);
+}
+
+code.doc-symbol-type_parameter::after {
+ content: "type-param";
+}
+
code.doc-symbol-attribute,
a code.doc-symbol-attribute {
color: var(--doc-symbol-attribute-fg-color);
@@ -164,6 +185,17 @@ code.doc-symbol-class::after {
content: "class";
}
+
+code.doc-symbol-type_alias,
+a code.doc-symbol-type_alias {
+ color: var(--doc-symbol-type_alias-fg-color);
+ background-color: var(--doc-symbol-type_alias-bg-color);
+}
+
+code.doc-symbol-type_alias::after {
+ content: "type";
+}
+
code.doc-symbol-module,
a code.doc-symbol-module {
color: var(--doc-symbol-module-fg-color);
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html b/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html
new file mode 100644
index 00000000..ca10bc88
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html
@@ -0,0 +1 @@
+{% extends "_base/summary/type_aliases.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html.jinja b/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html.jinja
new file mode 100644
index 00000000..ca10bc88
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/summary/type_aliases.html.jinja
@@ -0,0 +1 @@
+{% extends "_base/summary/type_aliases.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/type_alias.html b/src/mkdocstrings_handlers/python/templates/material/type_alias.html
new file mode 100644
index 00000000..5139a2db
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/type_alias.html
@@ -0,0 +1 @@
+{% extends "_base/type_alias.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/type_alias.html.jinja b/src/mkdocstrings_handlers/python/templates/material/type_alias.html.jinja
new file mode 100644
index 00000000..5139a2db
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/type_alias.html.jinja
@@ -0,0 +1 @@
+{% extends "_base/type_alias.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/type_parameters.html b/src/mkdocstrings_handlers/python/templates/material/type_parameters.html
new file mode 100644
index 00000000..c39ca528
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/type_parameters.html
@@ -0,0 +1 @@
+{% extends "_base/type_parameters.html.jinja" %}
diff --git a/src/mkdocstrings_handlers/python/templates/material/type_parameters.html.jinja b/src/mkdocstrings_handlers/python/templates/material/type_parameters.html.jinja
new file mode 100644
index 00000000..c39ca528
--- /dev/null
+++ b/src/mkdocstrings_handlers/python/templates/material/type_parameters.html.jinja
@@ -0,0 +1 @@
+{% extends "_base/type_parameters.html.jinja" %}
diff --git a/tests/test_end_to_end.py b/tests/test_end_to_end.py
index e442b1a8..3363ebd6 100644
--- a/tests/test_end_to_end.py
+++ b/tests/test_end_to_end.py
@@ -22,7 +22,7 @@
def _normalize_html(html: str) -> str:
soup = bs4.BeautifulSoup(html, features="html.parser")
- html = soup.prettify() # type: ignore[assignment]
+ html = soup.prettify()
html = re.sub(r"\b(0x)[a-f0-9]+\b", r"\1...", html)
html = re.sub(r"^(Build Date UTC ?:).+", r"\1...", html, flags=re.MULTILINE)
html = re.sub(r"\b[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\b", r"...", html)