diff --git a/src/yamlhttpforms/form.py b/src/yamlhttpforms/form.py index dd7b957..1512d87 100644 --- a/src/yamlhttpforms/form.py +++ b/src/yamlhttpforms/form.py @@ -1,4 +1,5 @@ from pathlib import Path +from importlib import import_module from typing import Dict, Callable, Union, Optional, Any, TYPE_CHECKING from yaml import safe_load @@ -9,14 +10,26 @@ if TYPE_CHECKING: PathT = Union[Path, str] CallableDefaultT = Callable[[], Optional[str]] -DefaultValueT = Union[str, CallableDefaultT] +DefaultInitT = Union[str, Dict[str, str]] OptionsT = Dict[str, str] class FormField: - def __init__(self, name: str, default: DefaultValueT = None, options: OptionsT = None, required: bool = False): + def __init__(self, name: str, default: DefaultInitT = None, options: OptionsT = None, required: bool = False): self.name: str = name - self._default: Optional[DefaultValueT] = default + self._default: Union[str, CallableDefaultT, None] + if isinstance(default, dict): + try: + module, function = default['module'], default['function'] + except KeyError: + raise TypeError(f"Default for field '{name}' is invalid. The default must be either a string or a " + f"dictionary with the special keys 'module' and 'function'.") + obj = import_module(module) + for attr in function.split('.'): + obj = getattr(obj, attr) + self._default = obj + else: + self._default = default self.options: Optional[OptionsT] = options self.required: bool = required