Skip to content

Commit 7995560

Browse files
author
Benoit Fuentes
committed
new defaults styles with inner section merging
1 parent 56cfc9e commit 7995560

File tree

6 files changed

+623
-39
lines changed

6 files changed

+623
-39
lines changed

README.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,22 +155,35 @@ Utilize a built-in style by specifying any of the following names (as a string),
155155

156156
- `"numpy"`: [NumPy-styled docstrings](https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt#docstring-standard)
157157
from the parent and child are merged gracefully with nice formatting. The child's docstring sections take precedence
158-
in the case of overlap.
158+
in the case of overlap.
159+
160+
- `"numpy_with_merge"`: Behaves identically to the "numpy" style, but also merges sections that overlap,
161+
instead of only keeping the child's section. All sections are concerned except sections "Short Summary",
162+
"Extended Summary", "Deprecation Warning" and "Examples" for which the "numpy" style behaviour applies.
159163

160164
- `"google"`: Google-styled docstrings from the parent and child are merged gracefully
161165
with nice formatting. The child's docstring sections take precedence in the case of overlap.
162166
This adheres to the [napoleon specification for the Google style](http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html#example-google-style-python-docstrings).
163167

168+
- `"google_with_merge"`: Behaves identically to the "google" style, but also merges sections that overlap,
169+
instead of only keeping the child's section. All sections are concerned except sections "Short Summary",
170+
"Example" and "Examples" (or coresponding aliases) for which the 'google' style applies.
171+
164172
- `"numpy_napoleon"`: NumPy-styled docstrings from the parent and child are merged gracefully
165173
with nice formatting. The child's docstring sections take precedence in the case of overlap.
166174
This adheres to the [napoleon specification for the NumPy style](http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_numpy.html#example-numpy).
167175

176+
- `"numpy_napoleon_with_merge"`: Behaves identically to the 'numpy_napoleon' style, but also merges sections
177+
that overlap, instead of only keeping the child's section. All sections are concerned except sections
178+
"Short Summary", "Example" and "Examples" (or coresponding aliases) for which the 'numpy_napoleon' style
179+
behaviour applies.
180+
168181
- `"reST"`: reST-styled docstrings from the parent and child are merged gracefully
169182
with nice formatting. Docstring sections are specified by
170183
[reST section titles](http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#sections).
171184
The child's docstring sections take precedence in the case of overlap.
172185

173-
For the `numpy`, `numpy_napoleon`, and `google` styles, if the parent's docstring contains a "Raises" section and the child's docstring implements a "Returns" or a "Yields" section instead, then the "Raises" section is not included in the resulting docstring. This is to accomodate for the relatively common use case in which an abstract method/property raises `NotImplementedError`. Child classes that implement this method/property clearly will not raise this. Of course, any "Raises" section that is explicitly included in the child's docstring will appear in the resulting docstring.
186+
For the `numpy`, `numpy_with_merge`, `numpy_napoleon`, `numpy_napoleon_with_merge`, `google` and `google_with_merge` styles, if the parent's docstring contains a "Raises" section and the child's docstring implements a "Returns" or a "Yields" section instead, then the "Raises" section is not included in the resulting docstring. This is to accomodate for the relatively common use case in which an abstract method/property raises `NotImplementedError`. Child classes that implement this method/property clearly will not raise this. Of course, any "Raises" section that is explicitly included in the child's docstring will appear in the resulting docstring.
174187

175188
Detailed documentation and example cases for the default styles can be found [here](https://github.com/meowklaski/custom_inherit/blob/master/custom_inherit/_style_store.py)
176189

src/custom_inherit/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44

55
from ._decorator_base import DocInheritDecorator as _DocInheritDecorator
66
from ._metaclass_base import DocInheritorBase as _DocInheritorBase
7-
from ._style_store import google, numpy, numpy_napoleon, parent, reST
7+
from . import _style_store
8+
from ._style_store import (
9+
google, numpy, numpy_napoleon, parent, reST,
10+
google_with_merge, numpy_napoleon_with_merge, numpy_with_merge
11+
)
812
from ._version import get_versions
913

1014
__version__ = get_versions()["version"]
@@ -113,7 +117,6 @@ def items(self):
113117
""" D.items() -> a set-like object providing a view on D's items"""
114118
return self._store.items()
115119

116-
117120
store = _Store([(key, getattr(_style_store, key)) for key in _style_store.__all__])
118121

119122

src/custom_inherit/_doc_parse_tools/napoleon_parse_tools.py

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def parse_napoleon_doc(doc, style):
8787
return doc_sections
8888

8989

90-
def merge_section(key, prnt_sec, child_sec, style):
90+
def merge_section(key, prnt_sec, child_sec, style, merge_within_sections=False):
9191
""" Synthesize a output napoleon docstring section.
9292
9393
Parameters
@@ -102,6 +102,13 @@ def merge_section(key, prnt_sec, child_sec, style):
102102
-------
103103
Optional[str]
104104
The output docstring section."""
105+
106+
napoleon_sections_that_cant_merge = [
107+
"Short Summary",
108+
"Example",
109+
"Examples",
110+
]
111+
105112
if prnt_sec is None and child_sec is None:
106113
return None
107114

@@ -114,13 +121,20 @@ def merge_section(key, prnt_sec, child_sec, style):
114121
header = "\n".join((key, "".join("-" for i in range(len(key))), ""))
115122
else:
116123
header = "\n".join((key + ":", ""))
117-
118-
body = prnt_sec if child_sec is None else child_sec
124+
if merge_within_sections and key not in napoleon_sections_that_cant_merge:
125+
if child_sec is None:
126+
body = prnt_sec
127+
elif prnt_sec is None:
128+
body = child_sec
129+
else:
130+
body = '\n'.join((prnt_sec, child_sec))
131+
else:
132+
body = prnt_sec if child_sec is None else child_sec
119133

120134
return header + body
121135

122136

123-
def merge_all_sections(prnt_sctns, child_sctns, style):
137+
def merge_all_sections(prnt_sctns, child_sctns, style, merge_within_sections=False):
124138
""" Merge the doc-sections of the parent's and child's attribute into a single docstring.
125139
126140
Parameters
@@ -141,13 +155,19 @@ def merge_all_sections(prnt_sctns, child_sctns, style):
141155
prnt_sctns["Raises"] = None
142156

143157
for key in prnt_sctns:
144-
sect = merge_section(key, prnt_sctns[key], child_sctns[key], style)
158+
sect = merge_section(
159+
key,
160+
prnt_sctns[key],
161+
child_sctns[key],
162+
style,
163+
merge_within_sections=merge_within_sections
164+
)
145165
if sect is not None:
146166
doc.append(sect)
147167
return "\n\n".join(doc) if doc else None
148168

149169

150-
def merge_numpy_napoleon_docs(prnt_doc=None, child_doc=None):
170+
def merge_numpy_napoleon_docs(prnt_doc=None, child_doc=None, merge_within_sections=False):
151171
""" Merge two numpy-style docstrings into a single docstring, according to napoleon docstring sections.
152172
153173
Given the numpy-style docstrings from a parent and child's attributes, merge the docstring
@@ -172,11 +192,14 @@ def merge_numpy_napoleon_docs(prnt_doc=None, child_doc=None):
172192
The merged docstring. """
173193
style = "numpy"
174194
return merge_all_sections(
175-
parse_napoleon_doc(prnt_doc, style), parse_napoleon_doc(child_doc, style), style
195+
parse_napoleon_doc(prnt_doc, style),
196+
parse_napoleon_doc(child_doc, style),
197+
style,
198+
merge_within_sections=merge_within_sections
176199
)
177200

178201

179-
def merge_google_napoleon_docs(prnt_doc=None, child_doc=None):
202+
def merge_google_napoleon_docs(prnt_doc=None, child_doc=None, merge_within_sections=False):
180203
""" Merge two google-style docstrings into a single docstring, according to napoleon docstring sections.
181204
182205
Given the google-style docstrings from a parent and child's attributes, merge the docstring
@@ -201,5 +224,8 @@ def merge_google_napoleon_docs(prnt_doc=None, child_doc=None):
201224
The merged docstring. """
202225
style = "google"
203226
return merge_all_sections(
204-
parse_napoleon_doc(prnt_doc, style), parse_napoleon_doc(child_doc, style), style
227+
parse_napoleon_doc(prnt_doc, style),
228+
parse_napoleon_doc(child_doc, style),
229+
style,
230+
merge_within_sections=merge_within_sections
205231
)

src/custom_inherit/_doc_parse_tools/numpy_parse_tools.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def parse_numpy_doc(doc):
6161
return doc_sections
6262

6363

64-
def merge_section(key, prnt_sec, child_sec):
64+
def merge_section(key, prnt_sec, child_sec, merge_within_sections=False):
6565
""" Synthesize a output numpy docstring section.
6666
6767
Parameters
@@ -76,6 +76,14 @@ def merge_section(key, prnt_sec, child_sec):
7676
-------
7777
Optional[str]
7878
The output docstring section."""
79+
80+
doc_sections_that_cant_merge = [
81+
"Short Summary",
82+
"Deprecation Warning",
83+
"Extended Summary",
84+
"Examples"
85+
]
86+
7987
if prnt_sec is None and child_sec is None:
8088
return None
8189

@@ -84,15 +92,20 @@ def merge_section(key, prnt_sec, child_sec):
8492
else:
8593
header = "\n".join((key, "".join("-" for i in range(len(key))), ""))
8694

87-
if child_sec is None:
88-
body = prnt_sec
95+
if merge_within_sections and key not in doc_sections_that_cant_merge:
96+
if child_sec is None:
97+
body = prnt_sec
98+
elif prnt_sec is None:
99+
body = child_sec
100+
else:
101+
body = '\n'.join((prnt_sec, child_sec))
89102
else:
90-
body = child_sec
103+
body = prnt_sec if child_sec is None else child_sec
91104

92105
return header + body
93106

94107

95-
def merge_all_sections(prnt_sctns, child_sctns):
108+
def merge_all_sections(prnt_sctns, child_sctns, merge_within_sections=False):
96109
""" Merge the doc-sections of the parent's and child's attribute into a single docstring.
97110
98111
Parameters
@@ -113,13 +126,18 @@ def merge_all_sections(prnt_sctns, child_sctns):
113126
prnt_sctns["Raises"] = None
114127

115128
for key in prnt_sctns:
116-
sect = merge_section(key, prnt_sctns[key], child_sctns[key])
129+
sect = merge_section(
130+
key,
131+
prnt_sctns[key],
132+
child_sctns[key],
133+
merge_within_sections=merge_within_sections
134+
)
117135
if sect is not None:
118136
doc.append(sect)
119137
return "\n\n".join(doc) if doc else None
120138

121139

122-
def merge_numpy_docs(prnt_doc=None, child_doc=None):
140+
def merge_numpy_docs(prnt_doc=None, child_doc=None, merge_within_sections=False):
123141
""" Merge two numpy-style docstrings into a single docstring.
124142
125143
Given the numpy-style docstrings from a parent and child's attributes, merge the docstring
@@ -141,4 +159,8 @@ def merge_numpy_docs(prnt_doc=None, child_doc=None):
141159
Union[str, None]
142160
The merged docstring.
143161
"""
144-
return merge_all_sections(parse_numpy_doc(prnt_doc), parse_numpy_doc(child_doc))
162+
return merge_all_sections(
163+
parse_numpy_doc(prnt_doc),
164+
parse_numpy_doc(child_doc),
165+
merge_within_sections=merge_within_sections
166+
)

0 commit comments

Comments
 (0)