Source code for asr.core.decorators

import typing
import inspect
from .comparators import comparators
from .command import ASRCommand
from asr.calculators import set_calculator_hook


[docs]def instruction( module: typing.Optional[str] = None, version: int = 0, argument_hooks: typing.List[typing.Callable] = [set_calculator_hook], package_dependencies=('asr', 'ase', 'gpaw'), ): """Make instruction object. Parameters ---------- module: str Name of recipe that instruction belongs to. version: int Instruction version number. argument_hooks: list[callable] Functions for preprocessing arguments. Gets a parameter object and should return parameter object. package_dependencies: typing.Tuple[str] Python packages for which versions should be logged. """ def decorator(func): if module is None: mod = inspect.getmodule(func) mod = mod.__name__ else: mod = module return ASRCommand( func, module=mod, version=version, argument_hooks=argument_hooks, ) return decorator
command = instruction
[docs]def option(*aliases, matcher=comparators.EQUAL, **kwargs): """Make argument descriptor for a CLI option. Parameters ---------- aliases: list[str] matcher: callable Matching function that wraps value when matching parameter with cache. Default is to use "equal", eg. EQUAL("value"). kwargs: dict Arguments forwarded to click.option. """ def decorator(func): assert aliases, 'You have to give a name to this parameter' for arg in aliases: params = inspect.signature(func).parameters name = arg.lstrip('-').split('/')[0].replace('-', '_') if name in params: break else: raise AssertionError( _paramerrormsg(func, 'You must give exactly one alias that starts ' 'with -- and matches a function argument.')) param = {'argtype': 'option', 'alias': aliases, 'name': name, 'matcher': matcher} param.update(kwargs) _add_param(func, param) return func return decorator
[docs]def argument(name, matcher=comparators.EQUAL, **kwargs): """Make argument descriptor for a CLI argument. Parameters ---------- name: str Name of argument. matcher: callable Matching function that wraps value when matching parameter with cache. Default is to use "equal", eg. EQ("value"). kwargs: dict Arguments forwarded to click.argument. """ def decorator(func): assert 'default' not in kwargs, 'Arguments do not support defaults!' param = {'argtype': 'argument', 'alias': (name, ), 'name': name, 'matcher': matcher} param.update(kwargs) _add_param(func, param) return func return decorator
def _paramerrormsg(func, msg): return f'Problem in {func.__module__}@{func.__name__}. {msg}' def _add_param(func, param): if not hasattr(func, '__asr_params__'): func.__asr_params__ = {} name = param['name'] assert name not in func.__asr_params__, \ _paramerrormsg(func, f'Double assignment of {name}') import inspect sig = inspect.signature(func) assert name in sig.parameters, \ _paramerrormsg(func, f'Unkown parameter {name}') assert 'argtype' in param, \ _paramerrormsg(func, 'You have to specify the parameter ' 'type: option or argument') if param['argtype'] == 'option': if 'nargs' in param: assert param['nargs'] > 0, \ _paramerrormsg(func, 'Options only allow one argument') elif param['argtype'] == 'argument': assert 'default' not in param, \ _paramerrormsg(func, 'Argument don\'t allow defaults') else: raise AssertionError( _paramerrormsg(func, f'Unknown argument type {param["argtype"]}')) func.__asr_params__[name] = param