strictyaml
strictyaml copied to clipboard
Revalidating from type hints
In my code, I wish to parse function parameters from a YAML configuration file, something like this:
modules:
- type: MyFirstFunc
args:
- people:
- Claire
- Frank
- hi
- 2
- type: MySecondFunc
args:
- True
- 25.5
Because the argument list is dynamic, I have to use strictyaml.MapPattern with strictyaml.Any() as key-type to parse the args in this initial config correctly. After inspecting type I can inspect the type-hints on the functions and theoretically revalidate the args using information from the type-hints.
I wrote this prototype function for it:
def _build_strictyaml_schema_from_signature(signature):
type_hint_map = {
bool: strictyaml.Bool(),
int: strictyaml.Int(),
float: strictyaml.Float(),
str: strictyaml.Str(),
datetime: strictyaml.Datetime()
}
schema = {}
for param_name, param in signature.parameters.items():
optional = False
origin = typing.get_origin(param.annotation)
if origin is not None:
if origin is typing.Union:
arg_subtypes = typing.get_args(param.annotation)
optional = (arg_subtypes[-1] is type(None))
if issubclass(origin, collections.abc.Mapping):
key_type, value_type = typing.get_args(param.annotation)
new_validator = strictyaml.MapPattern(type_hint_map[key_type], type_hint_map[value_type])
elif issubclass(origin, collections.abc.Sequence):
value_type, = typing.get_args(param.annotation)
new_validator = strictyaml.Seq(type_hint_map[value_type])
elif issubclass(origin, collections.abc.Set):
value_type, = typing.get_args(param.annotation)
new_validator = strictyaml.UniqueSeq(type_hint_map[value_type])
else:
raise ValueError(f"Unknown typing format '{param}'. "
"If you think this is a valid type, please consider filing a bug report.")
else:
new_validator = type_hint_map[param.annotation]
if param.default != inspect.Parameter.empty:
schema[strictyaml.Optional(param_name, default=param.default)] = new_validator
elif optional:
schema[strictyaml.Optional(param_name, default=None)] = new_validator
else:
schema[param_name] = new_validator
return strictyaml.Map(schema)
If anybody would like to suggest what I can improve or state that I lost my sanity, please go ahead.
You don't seem to be using .revalidate( ) to revalidate but other than that it all seems pretty much as I'd do it.
I did something similar in the hitchstory package.
On Thu, 20 Feb 2020, 12:07 orangelynx, [email protected] wrote:
In my code, I wish to parse function parameters from a YAML configuration file, something like this:
modules:
- type: MyFirstFunc
- args:
- people:
- Claire
- Frank
- hi
- 2
- type: MySecondFunc
- args:
- True
- 25.5
Because the argument list is dynamic, I have to use strictyaml.MapPattern with strictyaml.Any() as key-type to parse the args in this initial config correctly. After inspecting type I can inspect the type-hints on the functions and theoretically revalidate the args using information from the type-hints.
I wrote this prototype function for it:
def _build_strictyaml_schema_from_type_hints(type_hints): type_hint_map = { bool: strictyaml.Bool(), int: strictyaml.Int(), float: strictyaml.Float(), str: strictyaml.Str(), datetime: strictyaml.Datetime() }
schema = {} for arg_name, arg_type in type_hints.items(): origin = typing.get_origin(arg_type) if origin is not None: if issubclass(origin, collections.abc.Mapping): key_type, value_type = typing.get_args(arg_type) schema[arg_name] = strictyaml.MapPattern(type_hint_map[key_type], type_hint_map[value_type]) elif issubclass(origin, collections.abc.Sequence): value_type, = typing.get_args(arg_type) schema[arg_name] = strictyaml.Seq(type_hint_map[value_type]) elif issubclass(origin, collections.abc.Set): value_type, = typing.get_args(arg_type) schema[arg_name] = strictyaml.UniqueSeq(type_hint_map[value_type]) else: raise ValueError(f"Unknown typing format '{arg_type}'. " "If you think this is a valid type, please consider filing a bug report.") else: schema[arg_name] = type_hint_map[arg_type] return strictyaml.Map(schema)If anybody would like to suggest what I can improve or state that I lost my sanity, please go ahead.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/crdoconnor/strictyaml/issues/89?email_source=notifications&email_token=ABOJKNN2JVVH2HWEXYNNYITRDZW7JA5CNFSM4KYNOYBKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4IO64DPQ, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABOJKNL56BVBEIIBC6LDLA3RDZW7JANCNFSM4KYNOYBA .