Commit c16ee61b authored by Lucas Bourneuf's avatar Lucas Bourneuf

export is now able to be imported by biseau as any script

This is really awesome: you export a set of scripts, and get a new
script that can also be used as a standalone program.
parent 987a44bf
......@@ -12,6 +12,21 @@ try:
except ImportError:
black = None
def repr_argument_type(ctype) -> str:
"""Return the represenation of a biseau argument type, ready to be use
to generate the annotations of run_on function."""
if ctype in {int, float, str, bool}:
return ctype.__name__
elif ctype is open or ctype == (open, 'r'):
return 'open'
elif ctype == (open, 'w'):
return "(open, 'w')"
elif isinstance(ctype, range):
return "range({ctype.start}, {ctype.stop}, {ctype.step})"
elif isinstance(ctype, (int, float, str, bool, list, tuple, set, frozenset, dict)):
return repr(ctype)
else:
raise NotImplementedError(f"Type '{type}' cannot be represented as an argument type")
def get_pipeline_options(scripts:[Script]) -> dict:
"""Return the mapping option->False to be used by standalone_export_pipeline.
......@@ -40,6 +55,9 @@ def _standalone_export_pipeline(scripts:[Script], options:dict={}, default_conte
((idx, name), final_name) for (idx, name), final_name in option_names.items()
if options.get(final_name)
)
def options_as_dict(opts):
return {name: vals for name, *vals in opts}
# print('OPTIONS USED:', options_used)
yield f'"""{name}'
yield f'Generated by biseau {__version__}, {datetime.datetime.now()}.'
......@@ -77,9 +95,7 @@ def _standalone_export_pipeline(scripts:[Script], options:dict={}, default_conte
yield ' return element'
yield ' return valid_element'
for (idx, name), final_name in options_used:
def as_dict(opts):
return {name: vals for name, *vals in opts}
option = as_dict(scripts[idx].options)[final_name]
option = options_as_dict(scripts[idx].options)[final_name]
func, args = argparse_addarg_args_from_option(final_name, option, explicit_value=scripts[idx].options_values.get(name))
yield f' parser.{func}({", ".join(args)})'
# print('MAKE ARG:', f' parser.{func}({", ".join(args)})')
......@@ -116,11 +132,28 @@ def _standalone_export_pipeline(scripts:[Script], options:dict={}, default_conte
if not script.erase_context:
new_context = r'context + ("\n" if context else "") + ' + new_context
yield f' return {new_context}'
yield 'def run_on(context:str, args):'
# informations about the script, for biseau
yield f'NAME = {name}'
yield f'TAGS = {repr(set.union(*(script.tags for script in scripts)))}'
outputs = set.union(*(set(script.outputs()) for script in scripts))
inputs = set.union(*(set(script.inputs()) for script in scripts))
yield f'OUTPUTS = {repr(outputs - inputs)}' # expose what is not used
yield f'INPUTS = {repr(inputs - outputs)}'
# write the main run_on function, expecting all parameters
main_args = []
for (idx, name), final_name in options_used:
ctype, default, help = options_as_dict(scripts[idx].options)[name]
main_args.append(f"{final_name}:{repr_argument_type(ctype)}={repr(default)}")
main_args = ', '.join(main_args)
yield f'def run_on(context:str, *, {main_args}):'
# call each *_run_on inside the run_on, taking care to provide its arguments
for runon, script in runons:
target_idx = scripts.index(script)
options = ((name, final_name) for (idx, name), final_name in options_used if idx == target_idx)
args = ', '.join(f"{name}=args.{final_name}" for name, final_name in options)
args = ', '.join(f"{name}={final_name}" for name, final_name in options)
yield f' context = {runon}(context, {args})'
yield f' biseau.compile_to_single_image(context, outfile={repr(metarg_outfile)}, dotfile={repr(metarg_dotfile)}, dot_prog={repr(metarg_dot_prog)}, verbosity={repr(verbosity)})'
......@@ -128,7 +161,9 @@ def _standalone_export_pipeline(scripts:[Script], options:dict={}, default_conte
yield 'if __name__ == "__main__":'
yield ' args = cli().parse_args()'
yield ' context = ' + repr(default_context)
yield ' run_on(context, args)'
# calling the main run_on
all_args = ', '.join(f'{final_name}=args.{final_name}' for (idx, name), final_name in options_used)
yield f' run_on(context, {all_args})'
def option_names_from_options(scripts:[Script]) -> [(int, str, str)]:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment