From e44e2db7c6c813054354a000a57dac6e02e2de1e Mon Sep 17 00:00:00 2001 From: Bert Palm <bert.palm@ufz.de> Date: Tue, 23 Mar 2021 20:00:41 +0100 Subject: [PATCH] added signatureMaker, a code generation script --- signatureMaker.py | 159 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 signatureMaker.py diff --git a/signatureMaker.py b/signatureMaker.py new file mode 100644 index 000000000..c68ed4b93 --- /dev/null +++ b/signatureMaker.py @@ -0,0 +1,159 @@ +from saqc.funcs import * +from saqc.core.register import FUNC_MAP +import os + + +def start_with_exactly_N_spaces(line: str, N: int): + return line.startswith(' ' * N) and not line.startswith(' ' * (N + 1)) + + +def find_original_signature(fh, fname): + sig = [] + start = end = False + for line in fh.readlines(): + + # find start of signature + if not start: + + if line.startswith(f'def {fname}'): + sig.append(line) + start = True + continue + + # find end of signature + if '"""' in line or start_with_exactly_N_spaces(line, 4): + end = True + break # do not append line + + # found last line of signature + if '->' in line: + end = True + + sig.append(line) + + if end: + break + + # if end or/and start was not found, + # something went wrong + if end is False: + sig = None + + return sig + + +def replace_core_signatures(readlines, writelines, fname, fh): + start = end = False + for line in readlines: + + # append the rest of the file, the loop ends here + if end is True: + fh.write(line) + continue + + # find start of signature, loop starts here + if not start: + + if line.startswith(f' def {fname}'): + start = True + + # insert the replacement + for rline in writelines: + fh.write(' ') + fh.write(rline) + + else: + fh.write(line) + continue + + # found line after end of signature + if '"""' in line or start_with_exactly_N_spaces(line, 8): + end = True + fh.write(line) + continue + + # found last line of signature + if '->' in line: + end = True + continue + + +def replace_datafieldflagger(lines): + import re + empty = re.compile(' *\n') + data = re.compile('.*(data[=: ][^,]*, ?)') # eg. 'data: DictOfSeries,' + flagger = re.compile('.*(flagger[=: ][^,]*, ?)') # eg. 'flagger: Flagger,' + pattern = [data, flagger] + i = 0 + replaced = [] + for line in lines: + if 'copy' in line: + i = i + + if i < len(pattern): + found = pattern[i].match(line) + if found: + match = found[1] # regex group + replacement = '' + if i == 0: + replacement = 'self, ' + line = line.replace(match, replacement, 1) + i += 1 + + # find in same line + for j in range(i, len(pattern)): + found = pattern[i].match(line) + if found: + line = line.replace(found[1], '', 1) + i += 1 + + empty_line = empty.match(line) + if empty_line: + continue + + replaced.append(line) + + return replaced + + +def autoreplace_signature(): + postfix = '_autosignature' + saqc_path = 'saqc/core/modules/' + touched_modules = [] + + for name in FUNC_MAP: + module, fname = name.split('.') + + with open(f'saqc/funcs/{module}.py', 'r') as fh: + lines = find_original_signature(fh, fname) + + if lines is None: + warnings.warn(f"end of signature of '{fname}' not found - ignoring") + continue + + lines = replace_datafieldflagger(lines) + print(''.join(lines)) + + readfile = f'{saqc_path}{module}.py' + writefile = f'{saqc_path}{module}{postfix}.py' + if module in touched_modules: + readfile = writefile + else: + touched_modules.append(module) + + with open(readfile, 'r') as fh: + readlines = fh.readlines() + + with open(writefile, 'w') as fh: + replace_core_signatures(readlines, lines, fname, fh) + + files = os.listdir('saqc/core/modules/') + for new in files: + if postfix in new: + old = saqc_path + new.replace(postfix, '') + new = saqc_path + new + os.replace(new, old) + + +if __name__ == '__main__': + autoreplace_signature() -- GitLab