80 lines
2.2 KiB
Python
80 lines
2.2 KiB
Python
# 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
|