# Copyright (c) 2020. BioPro. Scientific. import inspect from functools import wraps from pathlib import Path from typing import Callable, Any, Union, Tuple, Optional def para_validator_build(para: Union[str, Tuple[str, ...]], validator: Callable[..., Any], write_back: bool = False): """validating decorator builder. :param para: parameter names :param validator: argument validator :param write_back: write the result of **validator** back to arguments list :return: instance method decorator """ def _return(f): signature = inspect.signature(f) @wraps(f) def _validator(self, *args, **kwargs): bind = signature.bind(self, *args, **kwargs) if isinstance(para, str): p = bind.arguments[para] p = validator(self, p) if write_back: bind.arguments[para] = p else: p = [bind.arguments[q] for q in para] validator(self, *p) return f(*bind.args, **bind.kwargs) return _validator return _return def path_validator_build(path: str, validator: Callable[[Any, Path], Optional[Path]], write_back: bool = False, imply_path: bool = True): """path validating decorator builder. :param path: path parameter name :param validator: path validator :param write_back: write the result of **validator** back to arguments list :param imply_path: allow path like argument. :return: instance method decorator """ def _return(f): signature = inspect.signature(f) @wraps(f) def _validator(self, *args, **kwargs): bind = signature.bind(self, *args, **kwargs) p = bind.arguments[path] if imply_path and isinstance(p, str): p = Path(p) bind.arguments[path] = p p = validator(self, p) if write_back: bind.arguments[path] = p return f(*bind.args, **bind.kwargs) return _validator return _return