22
33import functools
44from abc import ABC , abstractmethod
5+ from inspect import cleandoc
56
67import numpy as np
78
3334 warnif ,
3435)
3536
37+
38+ def _clean_doc (doc ):
39+ """Return a docstring fragment formatted for concatenation."""
40+ return cleandoc (doc ).rstrip ()
41+
42+
3643doc_target = """
3744 target : {float, ndarray}, optional
3845 Target value(s) of the objective. Only used if ``bounds`` is ``None``.
131138 "jac_chunk_size" : doc_jac_chunk_size ,
132139}
133140
134- doc_bounce = """
141+ doc_bounce = "\n \n " + _clean_doc ( " ""
135142 Notes
136143 -----
137144 Developer notes: Performance will improve significantly by resolving GitHub issues:
217224 instead of Chebyshev series. Default is ``True``. It can be preferable
218225 to set to ``False`` on equilibria with high ``NFP``, (such cases make
219226 smaller ``Y_B`` feasible), or on GPUs where eigenvalue solves are fast.
220- """ . rstrip ( )
227+ """ )
221228
222229
223- # Note: If we ever switch to Python 3.13 for building the docs, there will probably
224- # be some errors since 3.13 changed how tabs are handled in docstrings. This can be
225- # resolved by deleting the tabs in the collected docstring above and the ones
226- # that are defined in objectives. Check `test_objective_docstring`.
230+ # Generated fragments are concatenated into class docstrings after Python has already
231+ # applied normal docstring cleaning, so keep them explicitly dedented here.
227232def collect_docs (
228233 overwrite = None ,
229234 target_default = "" ,
@@ -265,7 +270,7 @@ def collect_docs(
265270 String of default parameters for the docstring.
266271
267272 """
268- doc_params = ""
273+ doc_params = []
269274
270275 # Copy to allow for objective-specific updates to docs
271276 docs_obj = docs .copy ()
@@ -280,39 +285,34 @@ def collect_docs(
280285
281286 for key in docs_obj .keys ():
282287 if overwrite is not None and key in overwrite .keys ():
283- doc_params += overwrite [key ].rstrip ()
288+ doc = _clean_doc (overwrite [key ])
289+ if doc :
290+ doc_params .append (doc )
284291 else :
292+ doc = _clean_doc (docs_obj [key ])
285293 if key == "target" :
286- target = ""
287294 if target_default != "" :
288- target += " Defaults to " + target_default
289- doc_params += docs_obj [ key ]. rstrip () + target
295+ doc += " Defaults to " + target_default
296+ doc_params . append ( doc )
290297 elif key == "bounds" and bounds_default != "" :
291- doc_params = (
292- doc_params
293- + docs_obj [key ].rstrip ()
294- + " Defaults to "
295- + bounds_default
296- )
298+ doc += " Defaults to " + bounds_default
299+ doc_params .append (doc )
297300 elif key == "loss_function" :
298- loss = ""
299301 if loss_detail is not None :
300- loss += loss_detail
301- doc_params += docs_obj [ key ]. rstrip () + loss
302+ doc += loss_detail
303+ doc_params . append ( doc )
302304 elif key == "normalize" :
303- norm = ""
304305 if normalize_detail is not None :
305- norm += normalize_detail
306- doc_params += docs_obj [ key ]. rstrip () + norm
306+ doc += normalize_detail
307+ doc_params . append ( doc )
307308 elif key == "normalize_target" :
308- norm_target = ""
309309 if normalize_target_detail is not None :
310- norm_target = normalize_target_detail
311- doc_params += docs_obj [ key ]. rstrip () + norm_target
310+ doc + = normalize_target_detail
311+ doc_params . append ( doc )
312312 else :
313- doc_params += docs_obj [ key ]. rstrip ( )
313+ doc_params . append ( doc )
314314
315- return doc_params
315+ return " \n " + " \n " . join ( doc_params )
316316
317317
318318class ObjectiveFunction (IOAble ):
@@ -1927,7 +1927,7 @@ def things(self, new):
19271927 self ._built = False
19281928
19291929
1930- _Objective .__doc__ += "" . join ( value . rstrip ( " \n " ) for value in docs . values () )
1930+ _Objective .__doc__ += collect_docs ( )
19311931
19321932# local functions assigned as attributes aren't hashable so they cause stuff to
19331933# recompile, so instead we define a hashable class to do the same thing.
0 commit comments