@@ -77,6 +77,38 @@ def wrapped_func(*args, **kwargs):
7777 return wrap
7878
7979
80+ DOCSTRING_SECTIONS = ['Parameters' , 'Returns' , 'Yields' , 'Raises' ,
81+ 'Warns' , 'Examples' , 'References' , 'Notes' ,
82+ 'Attributes' , 'Methods' ]
83+
84+
85+ def get_docs_indices (docstring , sections = DOCSTRING_SECTIONS ):
86+ """Get the indices of each section within a docstring.
87+
88+ Parameters
89+ ----------
90+ docstring : str
91+ Docstring to check indices for.
92+ sections : list of str, optional
93+ List of sections to check and get indices for.
94+ If not provided, uses the default set of
95+
96+ Returns
97+ -------
98+ inds : dict
99+ Dictionary in which each key is a section label, and each value is the corresponding index.
100+ """
101+
102+ inds = {label : None for label in DOCSTRING_SECTIONS }
103+
104+ for ind , line in enumerate (docstring .split ('\n ' )):
105+ for key , val in inds .items ():
106+ if key in line :
107+ inds [key ] = ind
108+
109+ return inds
110+
111+
80112def docs_drop_param (docstring ):
81113 """Drop the first parameter description for a string representation of a docstring.
82114
@@ -132,6 +164,91 @@ def docs_append_to_section(docstring, section, add):
132164 for split in docstring .split ('\n \n ' )])
133165
134166
167+ def docs_get_section (docstring , section , output = 'extract' ):
168+ """Extract and/or remove a specified section from a docstring.
169+
170+ Parameters
171+ ----------
172+ docstring : str
173+ Docstring to extract / remove a section from.
174+ section : str
175+ Label of the section to extract / remove.
176+ mode : {'extract', 'remove'}
177+ Run mode, options:
178+ 'extract' - returns the extracted section from the docstring.
179+ 'remove' - returns the docstring after removing the specified section.
180+
181+ Returns
182+ -------
183+ out_docstring : str
184+ Extracted / updated docstring.
185+ """
186+
187+ outs = []
188+ in_section = False
189+
190+ docstring_split = docstring .split ('\n ' )
191+ for ind , line in enumerate (docstring_split ):
192+
193+ # Track whether in the desired section
194+ if section in line and '--' in docstring_split [ind + 1 ]:
195+ in_section = True
196+ if in_section and line == '' :
197+ in_section = False
198+
199+ # Collect desired outputs based on whether extracting or removing section
200+ if output == 'extract' and in_section :
201+ outs .append (line )
202+ if output == 'remove' and not in_section :
203+ outs .append (line )
204+
205+ # As a special case, when removing section, end section marker if there is a '%' line
206+ if in_section and output == 'remove' and not line .isspace () and line .strip ()[0 ] == '%' :
207+ in_section = False
208+
209+ out_docstring = '\n ' .join (outs )
210+
211+ return out_docstring
212+
213+
214+ def docs_add_section (docstring , section ):
215+ """Add a section to a specified index of a docstring.
216+
217+ Parameters
218+ ----------
219+ docstring : str
220+ Docstring to add section to.
221+ section : str
222+ New section to add to docstring.
223+
224+ Returns
225+ -------
226+ out_docstring : str
227+ Updated docstring, with the new section added.
228+ """
229+
230+ inds = get_docs_indices (docstring )
231+
232+ # Split the section, extract the label, and check it's a known docstring section
233+ split_section = section .split ('\n ' )
234+ section_label = split_section [0 ].strip ()
235+ assert section_label in inds , 'Section label does not match expected list.'
236+
237+ # Remove the header section from the docstring (to replace it)
238+ docstring = docs_get_section (docstring , section_label , 'remove' )
239+
240+ # Check for and drop leading and trailing empty lines
241+ split_section = split_section [1 :] if split_section [0 ] == '' else split_section
242+ split_section = split_section [:- 1 ] if split_section [- 1 ] == ' ' else split_section
243+
244+ # Insert the new section into the docstring and rejoin it together
245+ split_docstring = docstring .split ('\n ' )
246+ split_docstring [inds [section_label ]:inds [section_label ]] = split_section
247+ new_docstring = '\n ' .join (split_docstring )
248+
249+ return new_docstring
250+
251+
135252def copy_doc_func_to_method (source ):
136253 """Decorator that copies method docstring from function, dropping first parameter.
137254
0 commit comments