From e83153e8ae173fd7c4aa769c85f2032a442f93a2 Mon Sep 17 00:00:00 2001 From: Daniil Fajnberg Date: Wed, 29 Dec 2021 18:26:16 +0100 Subject: [PATCH] allow using module-function-combinations as dynamic field defaults --- src/yamlhttpforms/form.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/yamlhttpforms/form.py b/src/yamlhttpforms/form.py index dd7b957..a1680a9 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 @@ -215,3 +228,6 @@ def load_form(*def_paths: PathT, dir_sort_key: Callable[[PathT], Any] = None, di full_payload=full_payload, url=url ) + +form = load_form('../../foo/a.yaml') +print(form.get_payload(mandatory_field='a'))