Skip to content

Commit 1b4d1c0

Browse files
committed
feat: Add option to merge __init__ methods' docstrings into their classes' docstrings
1 parent e962b88 commit 1b4d1c0

File tree

5 files changed

+109
-49
lines changed

5 files changed

+109
-49
lines changed

mkdocs.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,15 @@ plugins:
7474
handlers:
7575
python:
7676
import:
77+
- https://docs.python.org/3/objects.inv
7778
- https://mkdocstrings.github.io/objects.inv
79+
selection:
80+
docstring_style: google
81+
docstring_options:
82+
ignore_init_summary: yes
7883
rendering:
7984
show_submodules: no
85+
merge_init_into_class: yes
8086
watch:
8187
- src/mkdocstrings_handlers
8288

src/mkdocstrings_handlers/python/renderer.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class PythonRenderer(BaseRenderer):
7373
"show_signature_annotations": False,
7474
"separate_signature": False,
7575
"line_length": 60,
76+
"merge_init_into_class": False,
7677
"show_source": True,
7778
"show_bases": True,
7879
"show_submodules": True,
@@ -96,6 +97,7 @@ class PythonRenderer(BaseRenderer):
9697
**`show_signature_annotations`** | `bool` | Show the type annotations in method and function signatures. | `False`
9798
**`separate_signature`** | `bool` | Whether to put the whole signature in a code block below the heading. | `False`
9899
**`line_length`** | `int` | Maximum line length when formatting code. | `60`
100+
**`merge_init_into_class`** | `bool` | Whether to merge the `__init__` method into the class' signature and docstring. | `False`
99101
**`show_source`** | `bool` | Show the source code of this object. | `True`
100102
**`show_bases`** | `bool` | Show the base classes of a class. | `True`
101103
**`show_submodules`** | `bool` | When rendering a module, show its submodules recursively. | `True`

src/mkdocstrings_handlers/python/templates/material/_base/children.html

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@
4040
{% endif %}
4141
{% with heading_level = heading_level + extra_level %}
4242
{% for function in obj.functions.values()|order_members(config.members_order) %}
43-
{% if not function.is_alias or function.is_explicitely_exported %}
44-
{% include "function.html" with context %}
43+
{% if not (obj.kind.value == "class" and function.name == "__init__" and config.merge_init_into_class) %}
44+
{% if not function.is_alias or function.is_explicitely_exported %}
45+
{% include "function.html" with context %}
46+
{% endif %}
4547
{% endif %}
4648
{% endfor %}
4749
{% endwith %}
@@ -65,25 +67,29 @@
6567

6668
{% for child in obj.members.values()|order_members(config.members_order) %}
6769

68-
{% if child.kind.value == "attribute" %}
69-
{% with attribute = child %}
70-
{% include "attribute.html" with context %}
71-
{% endwith %}
70+
{% if not (obj.kind.value == "class" and child.name == "__init__" and config.merge_init_into_class) %}
7271

73-
{% elif child.kind.value == "class" %}
74-
{% with class = child %}
75-
{% include "class.html" with context %}
76-
{% endwith %}
72+
{% if child.kind.value == "attribute" %}
73+
{% with attribute = child %}
74+
{% include "attribute.html" with context %}
75+
{% endwith %}
7776

78-
{% elif child.kind.value == "function" %}
79-
{% with function = child %}
80-
{% include "function.html" with context %}
81-
{% endwith %}
77+
{% elif child.kind.value == "class" %}
78+
{% with class = child %}
79+
{% include "class.html" with context %}
80+
{% endwith %}
8281

83-
{% elif child.kind.value == "module" and config.show_submodules %}
84-
{% with module = child %}
85-
{% include "module.html" with context %}
86-
{% endwith %}
82+
{% elif child.kind.value == "function" %}
83+
{% with function = child %}
84+
{% include "function.html" with context %}
85+
{% endwith %}
86+
87+
{% elif child.kind.value == "module" and config.show_submodules %}
88+
{% with module = child %}
89+
{% include "module.html" with context %}
90+
{% endwith %}
91+
92+
{% endif %}
8793

8894
{% endif %}
8995

src/mkdocstrings_handlers/python/templates/material/_base/class.html

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,40 @@
2222
class="doc doc-heading",
2323
toc_label=class.name) %}
2424

25-
<code>
26-
{% if show_full_path %}{{ class.path }}{% else %}{{ class.name }}{% endif %}
27-
{% if config.show_bases and class.bases %}
28-
({% for expression in class.bases -%}
29-
{% include "expression.html" with context %}{% if not loop.last %}, {% endif %}
30-
{% endfor %})
31-
{% endif %}
32-
</code>
25+
{% if config.separate_signature %}
26+
<code>{% if show_full_path %}{{ class.path }}{% else %}{{ class.name }}{% endif %}</code>
27+
{% elif config.merge_init_into_class and "__init__" in class.members -%}
28+
{%- with function = class.members["__init__"] -%}
29+
{%- filter highlight(language="python", inline=True) -%}
30+
{% if show_full_path %}{{ class.path }}{% else %}{{ class.name }}{% endif %}
31+
{% with no_self = True %}
32+
{%- include "signature.html" with context -%}
33+
{% endwith %}
34+
{%- endfilter -%}
35+
{%- endwith -%}
36+
{% else %}
37+
<code>{% if show_full_path %}{{ class.path }}{% else %}{{ class.name }}{% endif %}</code>
38+
{% endif %}
3339

3440
{% with labels = class.labels %}
3541
{% include "labels.html" with context %}
3642
{% endwith %}
3743

3844
{% endfilter %}
3945

46+
{% if config.separate_signature and config.merge_init_into_class %}
47+
{% if "__init__" in class.members %}
48+
{% with function = class.members["__init__"], no_self = True %}
49+
{% filter highlight(language="python", inline=False) %}
50+
{% filter format_signature(config.line_length) %}
51+
{% if show_full_path %}{{ class.path }}{% else %}{{ class.name }}{% endif %}
52+
{% include "signature.html" with context %}
53+
{% endfilter %}
54+
{% endfilter %}
55+
{% endwith %}
56+
{% endif %}
57+
{% endif %}
58+
4059
{% else %}
4160
{% if config.show_root_toc_entry %}
4261
{% filter heading(heading_level,
@@ -50,15 +69,40 @@
5069
{% endif %}
5170

5271
<div class="doc doc-contents {% if root %}first{% endif %}">
72+
{% if config.show_bases and class.bases %}
73+
<p class="doc doc-class-bases">
74+
Bases: {% for expression in class.bases -%}
75+
<code>{% include "expression.html" with context %}</code>{% if not loop.last %}, {% endif %}
76+
{% endfor -%}
77+
</p>
78+
{% endif %}
79+
5380
{% with docstring_sections = class.docstring.parsed %}
5481
{% include "docstring.html" with context %}
5582
{% endwith %}
5683

57-
{% if config.show_source and class.source %}
58-
<details class="quote">
59-
<summary>Source code in <code>{{ class.relative_filepath }}</code></summary>
60-
{{ class.source|highlight(language="python", linestart=class.lineno, linenums=True) }}
61-
</details>
84+
{% if config.merge_init_into_class %}
85+
{% if "__init__" in class.members and class.members["__init__"].has_docstring %}
86+
{% with docstring_sections = class.members["__init__"].docstring.parsed %}
87+
{% include "docstring.html" with context %}
88+
{% endwith %}
89+
{% endif %}
90+
{% endif %}
91+
92+
{% if config.show_source %}
93+
{% if config.merge_init_into_class %}
94+
{% if "__init__" in class.members %}
95+
<details class="quote">
96+
<summary>Source code in <code>{{ class.relative_filepath }}</code></summary>
97+
{{ class.members["__init__"].source|highlight(language="python", linestart=class.lineno, linenums=True) }}
98+
</details>
99+
{% endif %}
100+
{% elif class.source %}
101+
<details class="quote">
102+
<summary>Source code in <code>{{ class.relative_filepath }}</code></summary>
103+
{{ class.source|highlight(language="python", linestart=class.lineno, linenums=True) }}
104+
</details>
105+
{% endif %}
62106
{% endif %}
63107

64108
{% with obj = class %}

src/mkdocstrings_handlers/python/templates/material/_base/signature.html

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,32 @@
1010

1111
(
1212
{%- for parameter in function.parameters -%}
13+
{%- if parameter.name != "self" or not no_self -%}
1314

14-
{%- if parameter.kind.value == "positional-only" -%}
15-
{%- if ns.render_pos_only_separator -%}
16-
{%- set ns.render_pos_only_separator = False %}/, {% endif -%}
17-
{%- elif parameter.kind.value == "keyword-only" -%}
18-
{%- if ns.render_kw_only_separator -%}
19-
{%- set ns.render_kw_only_separator = False %}*, {% endif -%}
20-
{%- endif -%}
15+
{%- if parameter.kind.value == "positional-only" -%}
16+
{%- if ns.render_pos_only_separator -%}
17+
{%- set ns.render_pos_only_separator = False %}/, {% endif -%}
18+
{%- elif parameter.kind.value == "keyword-only" -%}
19+
{%- if ns.render_kw_only_separator -%}
20+
{%- set ns.render_kw_only_separator = False %}*, {% endif -%}
21+
{%- endif -%}
2122

22-
{%- if config.show_signature_annotations and parameter.annotation is not none -%}
23-
{%- set annotation = ": " + parameter.annotation|safe -%}
24-
{%- endif -%}
23+
{%- if config.show_signature_annotations and parameter.annotation is not none -%}
24+
{%- set annotation = ": " + parameter.annotation|safe -%}
25+
{%- endif -%}
2526

26-
{%- if parameter.default is not none and parameter.kind.value != "variadic positional" and parameter.kind.value != "variadic keyword" -%}
27-
{%- set default = ns.equal + parameter.default|safe -%}
28-
{%- endif -%}
27+
{%- if parameter.default is not none and parameter.kind.value != "variadic positional" and parameter.kind.value != "variadic keyword" -%}
28+
{%- set default = ns.equal + parameter.default|safe -%}
29+
{%- endif -%}
2930

30-
{%- if parameter.kind.value == "variadic positional" -%}
31-
{%- set ns.render_kw_only_separator = False -%}
32-
{%- endif -%}
31+
{%- if parameter.kind.value == "variadic positional" -%}
32+
{%- set ns.render_kw_only_separator = False -%}
33+
{%- endif -%}
3334

34-
{{ parameter.name }}{{ annotation }}{{ default }}
35-
{%- if not loop.last %}, {% endif -%}
35+
{{ parameter.name }}{{ annotation }}{{ default }}
36+
{%- if not loop.last %}, {% endif -%}
3637

38+
{%- endif -%}
3739
{%- endfor -%}
3840
)
3941
{%- if config.show_signature_annotations and "return_annotation" in signature %} -> {{ signature.return_annotation }}{%- endif -%}

0 commit comments

Comments
 (0)