autodoctools¶
This module implements tools for increasing the level of automation and standardisation of the online documentation generated with Sphinx.
Module autodoctools
implements the following members:
AUXS
Priority level for members defined in different sources.
BUILTINS
Priority level for members defined in different sources.
CORE
Priority level for members defined in different sources.
CYTHONS
Priority level for members defined in different sources.
ELSE
Priority level for members defined in different sources.
EXE
Priority level for members defined in different sources.
HYDPY
Priority level for members defined in different sources.
MODELS
Priority level for members defined in different sources.
Priority
Priority level for members defined in different sources.
autodoc_basemodel()
Add an exhaustive docstring to the given module of a basemodel.
autodoc_applicationmodel()
Improves the docstrings of application models.
Substituter
Implements a HydPy specific docstring substitution mechanism.
prepare_mainsubstituter()
Prepare and return aSubstituter
object for the main __init__ file of HydPy.
autodoc_module()
Add a short summary of all implemented members to a module’s docstring.
autodoc_tuple2doc()
Include tuples as CLASSES of ControlParameters and RUN_METHODS of Models into the respective docstring.
- class hydpy.core.autodoctools.Priority(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
Bases:
Enum
Priority level for members defined in different sources.
- CORE = 1¶
Priority level for members defined in the core subpackage.
- EXE = 2¶
Priority level for members defined in the exe subpackage.
- AUXS = 3¶
Priority level for members defined in the auxs subpackage.
- CYTHONS = 4¶
Priority level for members defined in the cythons subpackage.
- MODELS = 5¶
Priority level for members defined in the models subpackage.
- HYDPY = 6¶
Priority level for HydPy members not falling in the other categories.
- classmethod get_priority(modulename: str) Priority [source]¶
Return the priority for the given module name.
>>> from hydpy.core.autodoctools import Priority >>> assert Priority.get_priority("builtins") == Priority.BUILTINS >>> assert Priority.get_priority("hydpy.core.test") == Priority.CORE >>> assert Priority.get_priority("hydpy.exe.test") == Priority.EXE >>> assert Priority.get_priority("hydpy.auxs.test") == Priority.AUXS >>> assert Priority.get_priority("hydpy.cythons.test") == Priority.CYTHONS >>> assert Priority.get_priority("hydpy.models.test") == Priority.MODELS >>> assert Priority.get_priority("hydpy.test") == Priority.HYDPY >>> assert Priority.get_priority("numpy.test") == Priority.ELSE
- hydpy.core.autodoctools.autodoc_basemodel(module: module) None [source]¶
Add an exhaustive docstring to the given module of a basemodel.
Works onlye when all modules of the basemodel are named in the standard way, e.g. lland_model, lland_control, lland_inputs.
- hydpy.core.autodoctools.autodoc_applicationmodel(module: module) None [source]¶
Improves the docstrings of application models.
autodoc_applicationmodel()
requires, similar toautodoc_basemodel()
, that both the application model and its base model are defined in the conventional way.
- class hydpy.core.autodoctools.Substituter(master: Substituter | None = None)[source]¶
Bases:
object
Implements a HydPy specific docstring substitution mechanism.
- master: Substituter | None¶
- slaves: List[Substituter]¶
- static consider_member(name_member: str, member: Any, module: module, class_: Type[object] | None = None, ignore: Dict[str, object] | None = None) bool [source]¶
Return
True
if the given member should be added to the substitutions. If not, returnFalse
.Some examples based on the site-package
numpy
:>>> from hydpy.core.autodoctools import Substituter >>> import numpy
A constant like
nan
should be added:>>> Substituter.consider_member("nan", numpy.nan, numpy) True
Members with a prefixed underscore should not be added:
>>> Substituter.consider_member("_NoValue", numpy._NoValue, numpy) False
Members that are actually imported modules should not be added:
>>> Substituter.consider_member("warnings", numpy.random, numpy) False
Members that are actually defined in other modules should not be added:
>>> numpy.Substituter = Substituter >>> Substituter.consider_member("Substituter", numpy.Substituter, numpy) False >>> del numpy.Substituter
Members that are defined in submodules of a given package (either from the standard library or from site-packages) should be added…
>>> Substituter.consider_member("clip", numpy.clip, numpy) True
…but not members defined in HydPy submodules:
>>> import hydpy >>> Substituter.consider_member("Node", hydpy.Node, hydpy) False
Module
typingtools
is unique, as it is the only one for whichconsider_member()
returnsTrue
all explicitly exported type aliases:>>> from hydpy.core import sequencetools, typingtools >>> Substituter.consider_member( ... "NDArrayFloat", typingtools.NDArrayFloat, typingtools) True
>>> Substituter.consider_member( ... "NDArrayFloat", typingtools.NDArrayFloat, sequencetools) False
For descriptor instances (with method __get__) being members of classes should be added:
>>> from hydpy.auxs import anntools >>> Substituter.consider_member( ... "shape_neurons", anntools.ANN.shape_neurons, anntools, anntools.ANN) True
You can decide to ignore certain members:
>>> Substituter.consider_member( ... "shape_neurons", anntools.ANN.shape_neurons, anntools, anntools.ANN, ... {"test": 1.0}) True >>> Substituter.consider_member( ... "shape_neurons", anntools.ANN.shape_neurons, anntools, anntools.ANN, ... {"shape_neurons": anntools.ANN.shape_neurons}) False
- static get_role(member: object, cython: bool = False) str [source]¶
Return the reStructuredText role func, class, or const best describing the given member.
Some examples based on the site-package
numpy
.clip()
is a function:>>> from hydpy.core.autodoctools import Substituter >>> import numpy >>> Substituter.get_role(numpy.clip) 'func'
ndarray
is a class:>>> Substituter.get_role(numpy.ndarray) 'class'
clip()
is a method, for which also the function role is returned:>>> Substituter.get_role(numpy.ndarray.clip) 'func'
For everything else the constant role is returned:
>>> Substituter.get_role(numpy.nan) 'const'
When analysing cython extension modules, set the option cython flag to
True
.Double
is correctly identified as a class:>>> from hydpy.cythons import pointerutils >>> Substituter.get_role(pointerutils.Double, cython=True) 'class'
Only with the cython flag beeing
True
, for everything else the function text role is returned (doesn’t make sense here, but thenumpy
module is not something defined in modulepointerutils
anyway):>>> Substituter.get_role(pointerutils.numpy, cython=True) 'func'
- add_substitution(short: str, medium: str, long: str, module: module) None [source]¶
Add the given substitutions both as a short2long and a medium2long mapping.
Assume variable1, variable2, and variable3 are defined in the HydPy module module1 of subpackage exe and the short and medium descriptions are var1 and mod1.var1 and so on:
>>> import types >>> module1 = types.ModuleType("hydpy.exe.module1") >>> from hydpy.core.autodoctools import Substituter >>> substituter = Substituter() >>> substituter.add_substitution( ... "var1", "mod1.var1", "hydpy.exe.module1.variable1", module1) >>> substituter.add_substitution( ... "var2", "mod1.var2", "hydpy.exe.module1.variable2", module1) >>> substituter.add_substitution( ... "var3", "mod1.var3", "hydpy.exe.module1.variable3", module1) >>> print(substituter.get_commands()) .. var1 replace:: hydpy.exe.module1.variable1 .. var2 replace:: hydpy.exe.module1.variable2 .. var3 replace:: hydpy.exe.module1.variable3 .. mod1.var1 replace:: hydpy.exe.module1.variable1 .. mod1.var2 replace:: hydpy.exe.module1.variable2 .. mod1.var3 replace:: hydpy.exe.module1.variable3
If we add an object with the same, the updating of
short2long
depends on its priority. Builtins have the highest priority. Objects defined in the core, exe, auxs, cythons, and models subpackages have the priorities two to six. All other objects (incuding those of other site-packages) have the lowest priority. If we add variable1, said to be defined in the core subpackage (higher priority than the exe subpackage), the new short substitution replaces the old one:>>> module2 = types.ModuleType("hydpy.core.module2") >>> substituter.add_substitution( ... "var1", "mod2.var1", "hydpy.core.module2.variable1", module2) >>> print(substituter.get_commands()) .. var1 replace:: hydpy.core.module2.variable1 .. var2 replace:: hydpy.exe.module1.variable2 .. var3 replace:: hydpy.exe.module1.variable3 .. mod1.var1 replace:: hydpy.exe.module1.variable1 .. mod1.var2 replace:: hydpy.exe.module1.variable2 .. mod1.var3 replace:: hydpy.exe.module1.variable3 .. mod2.var1 replace:: hydpy.core.module2.variable1
If we add variable2, said to be defined in the auxs subpackage (lower priority than the exe subpackage), the old short substitution does not change:
>>> module3 = types.ModuleType("hydpy.auxs.module3") >>> substituter.add_substitution( ... "var2", "mod3.var2", "hydpy.auxs.module3.variable2", module3) >>> print(substituter.get_commands()) .. var1 replace:: hydpy.core.module2.variable1 .. var2 replace:: hydpy.exe.module1.variable2 .. var3 replace:: hydpy.exe.module1.variable3 .. mod1.var1 replace:: hydpy.exe.module1.variable1 .. mod1.var2 replace:: hydpy.exe.module1.variable2 .. mod1.var3 replace:: hydpy.exe.module1.variable3 .. mod2.var1 replace:: hydpy.core.module2.variable1 .. mod3.var2 replace:: hydpy.auxs.module3.variable2
If we add variable3, said to be also defined in the exe subpackage, the short substitution is removed to avoid ambiguity:
>>> module4 = types.ModuleType("hydpy.exe.module4") >>> substituter.add_substitution( ... "var3", "mod4.var3", "hydpy.exe.module4.variable3", module4) >>> print(substituter.get_commands()) .. var1 replace:: hydpy.core.module2.variable1 .. var2 replace:: hydpy.exe.module1.variable2 .. mod1.var1 replace:: hydpy.exe.module1.variable1 .. mod1.var2 replace:: hydpy.exe.module1.variable2 .. mod1.var3 replace:: hydpy.exe.module1.variable3 .. mod2.var1 replace:: hydpy.core.module2.variable1 .. mod3.var2 replace:: hydpy.auxs.module3.variable2 .. mod4.var3 replace:: hydpy.exe.module4.variable3
Adding variable3 of module1 accidentally again does not result in any undesired side-effects:
>>> substituter.add_substitution( ... "var3", "mod1.var3", "hydpy.exe.module1.variable3", module1) >>> print(substituter.get_commands()) .. var1 replace:: hydpy.core.module2.variable1 .. var2 replace:: hydpy.exe.module1.variable2 .. mod1.var1 replace:: hydpy.exe.module1.variable1 .. mod1.var2 replace:: hydpy.exe.module1.variable2 .. mod1.var3 replace:: hydpy.exe.module1.variable3 .. mod2.var1 replace:: hydpy.core.module2.variable1 .. mod3.var2 replace:: hydpy.auxs.module3.variable2 .. mod4.var3 replace:: hydpy.exe.module4.variable3
In order to reduce the risk of name conflicts, only the medium2long mapping is supported for modules not part of the HydPy package:
>>> module5 = types.ModuleType("external") >>> substituter.add_substitution( ... "var4", "mod5.var4", "external.variable4", module5) >>> print(substituter.get_commands()) .. var1 replace:: hydpy.core.module2.variable1 .. var2 replace:: hydpy.exe.module1.variable2 .. mod1.var1 replace:: hydpy.exe.module1.variable1 .. mod1.var2 replace:: hydpy.exe.module1.variable2 .. mod1.var3 replace:: hydpy.exe.module1.variable3 .. mod2.var1 replace:: hydpy.core.module2.variable1 .. mod3.var2 replace:: hydpy.auxs.module3.variable2 .. mod4.var3 replace:: hydpy.exe.module4.variable3 .. mod5.var4 replace:: external.variable4
The only exception to this rule is
builtins
, for which only theshort2long
mapping is supported (note also, that the module name builtins is removed from string long):>>> import builtins >>> substituter.add_substitution( ... "str", "blt.str", ":func:`~builtins.str`", builtins) >>> print(substituter.get_commands()) .. str replace:: :func:`str` .. var1 replace:: hydpy.core.module2.variable1 .. var2 replace:: hydpy.exe.module1.variable2 .. mod1.var1 replace:: hydpy.exe.module1.variable1 .. mod1.var2 replace:: hydpy.exe.module1.variable2 .. mod1.var3 replace:: hydpy.exe.module1.variable3 .. mod2.var1 replace:: hydpy.core.module2.variable1 .. mod3.var2 replace:: hydpy.auxs.module3.variable2 .. mod4.var3 replace:: hydpy.exe.module4.variable3 .. mod5.var4 replace:: external.variable4
- add_module(module: module, cython: bool = False) None [source]¶
Add the given module, its members, and their submembers.
The first examples are based on the site-package
numpy
: which is passed to methodadd_module()
:>>> from hydpy.core.autodoctools import Substituter >>> substituter = Substituter() >>> import numpy >>> substituter.add_module(numpy)
First, the module itself is added:
>>> substituter.find("|numpy|") |numpy| :mod:`~numpy`
Second, constants like
nan
are added:>>> substituter.find("|numpy.nan|") |numpy.nan| :const:`~numpy.nan`
Third, functions like
clip()
are added:>>> substituter.find("|numpy.clip|") |numpy.clip| :func:`~numpy.clip`
Fourth, clases line
ndarray
are added:>>> substituter.find("|numpy.ndarray|") |numpy.ndarray| :class:`~numpy.ndarray`
Method
add_module()
also searches for available annotations:>>> from hydpy.core import timetools >>> substituter.add_module(timetools) >>> substituter.find("Timegrids.init") |Timegrids.initindices| :const:`~hydpy.core.timetools.Timegrids.initindices` |Timegrids.init| :attr:`~hydpy.core.timetools.Timegrids.init` |timetools.Timegrids.initindices| :const:`~hydpy.core.timetools.Timegrids.initindices` |timetools.Timegrids.init| :attr:`~hydpy.core.timetools.Timegrids.init`
>>> from hydpy.auxs import calibtools >>> substituter.add_module(calibtools) >>> substituter.find("RuleIUH.update_parameters") |RuleIUH.update_parameters| :attr:`~hydpy.auxs.calibtools.RuleIUH.update_parameters` |calibtools.RuleIUH.update_parameters| :attr:`~hydpy.auxs.calibtools.RuleIUH.update_parameters`
Module
typingtools
is unique, as it is the only one for whichadd_module()
considers all explicitly exported type aliases:>>> from hydpy.core import typingtools >>> substituter.add_module(typingtools) >>> substituter.find("|NDArrayFloat|") |NDArrayFloat| :...:`~hydpy.core.typingtools.NDArrayFloat`
When adding Cython modules, the cython flag should be set
True
:>>> from hydpy.cythons import pointerutils >>> substituter.add_module(pointerutils, cython=True) >>> substituter.find("set_pointer") |PPDouble.set_pointer| :func:`~hydpy.cythons.autogen.pointerutils.PPDouble.set_pointer` |pointerutils.PPDouble.set_pointer| :func:`~hydpy.cythons.autogen.pointerutils.PPDouble.set_pointer`
- add_modules(package: module) None [source]¶
Add the modules of the given package without their members.
- update_masters() None [source]¶
Update all master
Substituter
objects.If a
Substituter
object is passed to the constructor of anotherSubstituter
object, they become master and slave:>>> from hydpy.core.autodoctools import Substituter >>> sub1 = Substituter() >>> from hydpy.core import devicetools >>> sub1.add_module(devicetools) >>> sub2 = Substituter(sub1) >>> sub3 = Substituter(sub2) >>> sub3.master.master is sub1 True >>> sub2 in sub1.slaves True
During initialisation, all mappings handled by the master object are passed to its new slave:
>>> sub3.find("Node|") |Node| :class:`~hydpy.core.devicetools.Node` |devicetools.Node| :class:`~hydpy.core.devicetools.Node`
Updating a slave, does not affect its master directly:
>>> from hydpy.core import hydpytools >>> sub3.add_module(hydpytools) >>> sub3.find("HydPy|") |HydPy| :class:`~hydpy.core.hydpytools.HydPy` |hydpytools.HydPy| :class:`~hydpy.core.hydpytools.HydPy` >>> sub2.find("HydPy|")
Through calling
update_masters()
, the medium2long mappings are passed from the slave to its master:>>> sub3.update_masters() >>> sub2.find("HydPy|") |hydpytools.HydPy| :class:`~hydpy.core.hydpytools.HydPy`
Then each master object updates its own master object also:
>>> sub1.find("HydPy|") |hydpytools.HydPy| :class:`~hydpy.core.hydpytools.HydPy`
In reverse, subsequent updates of master objects to not affect their slaves directly:
>>> from hydpy.core import masktools >>> sub1.add_module(masktools) >>> sub1.find("Masks|") |Masks| :class:`~hydpy.core.masktools.Masks` |NodeMasks| :class:`~hydpy.core.masktools.NodeMasks` |masktools.Masks| :class:`~hydpy.core.masktools.Masks` |masktools.NodeMasks| :class:`~hydpy.core.masktools.NodeMasks` >>> sub2.find("Masks|")
Through calling
update_slaves()
, the medium2long mappings are passed the master to all of its slaves:>>> sub1.update_slaves() >>> sub2.find("Masks|") |masktools.Masks| :class:`~hydpy.core.masktools.Masks` |masktools.NodeMasks| :class:`~hydpy.core.masktools.NodeMasks` >>> sub3.find("Masks|") |masktools.Masks| :class:`~hydpy.core.masktools.Masks` |masktools.NodeMasks| :class:`~hydpy.core.masktools.NodeMasks`
- update_slaves() None [source]¶
Update all slave
Substituter
objects.See method
update_masters()
for further information.
- get_commands(source: str | None = None) str [source]¶
Return a string containing multiple reStructuredText replacements with the substitutions currently defined.
Some examples based on the subpackage
optiontools
:>>> from hydpy.core.autodoctools import Substituter >>> substituter = Substituter() >>> from hydpy.core import optiontools >>> substituter.add_module(optiontools)
When calling
get_commands()
with the source argument, the complete short2long and medium2long mappings are translated into replacement commands (only a few of them are shown):>>> print(substituter.get_commands()) .. |OptionContextBase._new_value| replace:: :attr:`~hydpy.core.optiontools.OptionContextBase._new_value` .. |OptionContextBase._old_value| replace:: :attr:`~hydpy.core.optiontools.OptionContextBase._old_value` ... .. |optiontools.TypeOptionPropertyBase| replace:: :const:`~hydpy.core.optiontools.TypeOptionPropertyBase` .. |optiontools.TypeOption| replace:: :const:`~hydpy.core.optiontools.TypeOption`
Through passing a string (usually the source code of a file to be documented), only the replacement commands relevant for this string are translated:
>>> from hydpy.core import objecttools >>> import inspect >>> source = inspect.getsource(objecttools) >>> print(substituter.get_commands(source)) .. |Options.ellipsis| replace:: :const:`~hydpy.core.optiontools.Options.ellipsis` .. |Options.reprdigits| replace:: :const:`~hydpy.core.optiontools.Options.reprdigits`
- hydpy.core.autodoctools.prepare_mainsubstituter() Substituter [source]¶
Prepare and return a
Substituter
object for the main __init__ file of HydPy.