Skip to content
Snippets Groups Projects
Commit 5bb83e88 authored by Peter Lünenschloß's avatar Peter Lünenschloß
Browse files

added template.py to doc/integrated decorator based methods documentation

parent 50f81ce0
No related branches found
No related tags found
6 merge requests!685Release 2.4,!684Release 2.4,!567Release 2.2.1,!566Release 2.2,!501Release 2.1,!420Doc decorator
Showing
with 167 additions and 21 deletions
......@@ -10,6 +10,7 @@ from __future__ import annotations
from saqc.constants import BAD, FILTER_ALL
import saqc
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Breaks:
......
......@@ -15,6 +15,7 @@ from typing_extensions import Literal
from saqc.constants import BAD
import saqc
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class ChangePoints:
......
......@@ -10,6 +10,7 @@ from __future__ import annotations
from saqc.constants import BAD
import saqc
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Constants:
......
......@@ -14,6 +14,7 @@ from typing_extensions import Literal
from saqc.constants import BAD
import saqc
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Curvefit:
......
......@@ -18,10 +18,11 @@ import saqc
from saqc.funcs import LinkageString
from saqc.lib.types import CurveFitter
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Drift:
@doc(saqc.drift.flagDriftFromNorm.__doc__)
@doc(saqc.funcs.drift.flagDriftFromNorm.__doc__)
def flagDriftFromNorm(
self,
field: Sequence[str],
......@@ -38,7 +39,7 @@ class Drift:
) -> saqc.SaQC:
return self._defer("flagDriftFromNorm", locals())
@doc(saqc.drift.flagDriftFromReference.__doc__)
@doc(saqc.funcs.drift.flagDriftFromReference.__doc__)
def flagDriftFromReference(
self,
field: Sequence[str],
......@@ -55,7 +56,7 @@ class Drift:
return self._defer("flagDriftFromReference", locals())
@doc(saqc.drift.correctDrift.__doc__)
@doc(saqc.funcs.drift.correctDrift.__doc__)
def correctDrift(
self,
field: str,
......@@ -67,7 +68,7 @@ class Drift:
return self._defer("correctDrift", locals())
@doc(saqc.drift.correctRegimeAnomaly.__doc__)
@doc(saqc.funcs.drift.correctRegimeAnomaly.__doc__)
def correctRegimeAnomaly(
self,
field: str,
......@@ -80,7 +81,7 @@ class Drift:
return self._defer("correctRegimeAnomaly", locals())
@doc(saqc.drift.correctOffset.__doc__)
@doc(saqc.funcs.drift.correctOffset.__doc__)
def correctOffset(
self,
field: str,
......
......@@ -17,26 +17,27 @@ from typing_extensions import Literal
from saqc.constants import BAD
import saqc
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class FlagTools:
@doc(saqc.flagtools.clearFlags.__doc__)
@doc(saqc.funcs.flagtools.clearFlags.__doc__)
def clearFlags(self, field: str, **kwargs) -> saqc.SaQC:
return self._defer("clearFlags", locals())
@doc(saqc.flagtools.forceFlags.__doc__)
@doc(saqc.funcs.flagtools.forceFlags.__doc__)
def forceFlags(self, field: str, flag: float = BAD, **kwargs) -> saqc.SaQC:
return self._defer("forceFlags", locals())
@doc(saqc.flagDummy.forceFlags.__doc__)
@doc(saqc.funcs.flagtools.forceFlags.__doc__)
def flagDummy(self, field: str, **kwargs) -> saqc.SaQC:
return self._defer("flagDummy", locals())
@doc(saqc.flagtools.flagUnflagged.__doc__)
@doc(saqc.funcs.flagtools.flagUnflagged.__doc__)
def flagUnflagged(self, field: str, flag: float = BAD, **kwargs) -> saqc.SaQC:
return self._defer("flagUnflagged", locals())
@doc(saqc.flagtools.flagManual.__doc__)
@doc(saqc.funcs.flagtools.flagManual.__doc__)
def flagManual(
self,
field: str,
......@@ -51,7 +52,7 @@ class FlagTools:
) -> saqc.SaQC:
return self._defer("flagManual", locals())
@doc(saqc.flagtools.transferFlags.__doc__)
@doc(saqc.funcs.flagtools.transferFlags.__doc__)
def transferFlags(
self,
field: str | Sequence[str],
......
......@@ -13,10 +13,11 @@ import saqc
from saqc.constants import UNFLAGGED, BAD, FILTER_ALL
from saqc.lib.types import GenericFunction
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Generic:
@doc(saqc.generic.processGeneric.__doc__)
@doc(saqc.funcs.generic.processGeneric.__doc__)
def processGeneric(
self,
field: str | Sequence[str],
......@@ -28,7 +29,7 @@ class Generic:
) -> saqc.SaQC:
return self._defer("processGeneric", locals())
@doc(saqc.generic.flagGeneric.__doc__)
@doc(saqc.funcs.generic.flagGeneric.__doc__)
def flagGeneric(
self,
field: Union[str, Sequence[str]],
......
......@@ -16,10 +16,11 @@ from saqc.constants import UNFLAGGED
import saqc
from saqc.funcs.interpolation import _SUPPORTED_METHODS
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Interpolation:
@doc(saqc.interpolation.interpolateByRolling.__doc__)
@doc(saqc.funcs.interpolation.interpolateByRolling.__doc__)
def interpolateByRolling(
self,
field: str,
......@@ -33,7 +34,7 @@ class Interpolation:
return self._defer("interpolateByRolling", locals())
@doc(saqc.interpolation.interpolateInvalid.__doc__)
@doc(saqc.funcs.interpolation.interpolateInvalid.__doc__)
def interpolateInvalid(
self,
field: str,
......@@ -46,7 +47,7 @@ class Interpolation:
) -> saqc.SaQC:
return self._defer("interpolateInvalid", locals())
@doc(saqc.interpolation.interpolateIndex.__doc__)
@doc(saqc.funcs.interpolation.interpolateIndex.__doc__)
def interpolateIndex(
self,
field: str,
......
......@@ -14,10 +14,11 @@ from typing import Callable
from saqc.constants import BAD
import saqc
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Noise:
@doc(saqc.noise.flagByStatLowPass.__doc__)
@doc(saqc.funcs.noise.flagByStatLowPass.__doc__)
def flagByStatLowPass(
self,
field: str,
......
......@@ -16,6 +16,7 @@ from typing_extensions import Literal
from saqc.constants import BAD
import saqc
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Outliers:
......
......@@ -10,6 +10,7 @@ from __future__ import annotations
from saqc.constants import BAD
import saqc
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Pattern:
......
......@@ -17,6 +17,7 @@ from saqc.constants import BAD
import saqc
from saqc.funcs.interpolation import _SUPPORTED_METHODS
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Resampling:
......
......@@ -16,6 +16,7 @@ from typing_extensions import Literal
from saqc.constants import BAD
import saqc
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Residues:
......
......@@ -13,6 +13,7 @@ import pandas as pd
from saqc.constants import BAD
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Rolling:
......
......@@ -15,6 +15,7 @@ from typing_extensions import Literal
import saqc
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Scores:
......
......@@ -15,6 +15,7 @@ import numpy as np
from saqc.constants import FILTER_NONE
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Tools:
......
......@@ -13,6 +13,7 @@ import pandas as pd
import saqc
from sphinxdoc.scripts.templates import doc
import saqc.funcs
class Transformation:
......
import re
def doc(dc_string):
def dc_func(meth):
meth.__doc__ = dc_string
FUNC_NAPOLEAN_STYLE_ORDER = ['Head', 'Parameters', 'Returns', 'Notes', 'See also', 'Examples', 'References']
def doc(doc_string: str, template='saqc_methods', source='function_string'):
def doc_func(meth):
if template=='saqc_methods':
meth.__doc__ = saqc_methods_template(doc_string, source)
return meth
return dc_func
\ No newline at end of file
return doc_func
def get_docstring_indent(doc_string: list) -> str:
"""returns a whitespace string matching the indent size of the passed docstring_list"""
regular_line = False
current_line = 0
while not regular_line:
# check if line isnt just a newline string and also not a blank line (with all white space)
if (not len(doc_string[current_line])==0) and (not re.match(' *$', doc_string[current_line])):
regular_line = True
else:
current_line += 1
# get indent-string (smth. like " ")
indent_str = re.match(' *', doc_string[current_line])[0]
return indent_str
def get_sections(doc_string: list, indent_str:str) -> dict:
"""Returns a dictionary of sections, with section names as keys"""
section_lines = [0]
section_headings = ['Head']
for k in range(len(doc_string)-1):
# check if next line is an underscore line (section signator):
if re.match(indent_str + '-+$', doc_string[k + 1]):
# check if underscore length matches heading length
if len(doc_string[k + 1]) == len(doc_string[k]):
section_lines.append(k)
# skip leading whitespaces (start with whitespace and end with anything but whitespace
skip = re.match('^ *', doc_string[k]).span()[-1]
section_headings.append(doc_string[k][skip:])
section_lines.append(len(doc_string))
section_content = [doc_string[section_lines[k]:section_lines[k + 1]] for k in range(len(section_lines)-1)]
section_content = [clear_whitespace_tail(p) for p in section_content]
sections = dict(zip(section_headings, section_content))
return sections
def get_parameters(section: list, indent_str: str) -> dict:
"""Returns a dictionary of Parameter documentations, with parameter names as keys"""
parameter_lines = []
parameter_names = []
for k in range(len(section)):
# try catch a parameter definition start (implicitly assuming parameter names have no
# whitespaces):
para = re.match(indent_str + '(\S+) *:', section[k])
# got one ?
if para:
parameter_lines.append(k)
parameter_names.append(para.group(1))
parameter_lines.append(len(section))
parameter_content = [section[parameter_lines[k]:parameter_lines[k + 1]] for k in range(len(parameter_lines) - 1)]
parameter_content = [clear_whitespace_tail(p) for p in parameter_content]
parameter_dict = dict(zip(parameter_names, parameter_content))
return parameter_dict
def mk_parameter(parameter_name: str, parameter_type: str, parameter_doc: str, indent_str: str) -> dict:
parameter_doc = parameter_doc.splitlines()
parameter_doc = [indent_str + ' '*4 + p for p in parameter_doc]
content = [indent_str + f"{parameter_name} : {parameter_type}"]
content += parameter_doc
return {parameter_name: content}
def mk_section(section_name: str, indent_str: str, doc_content: str=None) -> dict:
content = [indent_str + section_name]
content += [indent_str + '_'*len(section_name)]
content += [' ']
if doc_content:
content += doc_content.splitlines()
return {section_name: content}
def compose_docstring(section_dict: dict, order: list=FUNC_NAPOLEAN_STYLE_ORDER) -> str:
"""Compose final docstring from a sections dictionary"""
doc_string = []
section_dict = section_dict.copy()
for sec in order:
# append section
dc = section_dict.pop(sec, [])
doc_string += dc
# blank line at section end
if len(dc)>0:
doc_string += ['']
return '\n'.join(doc_string)
def clear_whitespace_tail(doc: list) -> list:
"""Clears tailing whitespace lines"""
for k in range(len(doc), 0 , -1):
if not re.match('^\s*$', doc[k-1]):
break
return doc[:k]
def saqc_methods_template(doc_string: str, source='function_string'):
if source == 'function_string':
# splitline doc string:
doc_string = doc_string.splitlines()
# retrieve doc indention
indent_string = get_docstring_indent(doc_string)
# retrieve sections dict
sections = get_sections(doc_string, indent_str=indent_string)
# remove returns section (if present)
sections.pop('Returns', None)
# generate new (blank) returns section
returns_section = mk_section(section_name='Returns',
indent_str=indent_string)
# generate return parameter 'out'
out_para = mk_parameter(parameter_name='out',
parameter_type='saqc.SaQC',
parameter_doc='An :py:meth:`saqc.SaQC` object, holding the (possibly) modified data',
indent_str=indent_string)
# add out - parameter description content to new returns section
returns_section['Returns'] += out_para['out']
# add new returns section to sections dict
sections.update(returns_section)
# compose output string with reference to desired order
doc_string = compose_docstring(section_dict=sections,
order=FUNC_NAPOLEAN_STYLE_ORDER)
return doc_string
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment