Validation facilities.
parselglossy.validation.
check_predicates
(incoming: Dict[str, Any], *, predicates: Dict[str, Any]) → None[source]¶Run predicates on input tree with fixed defaults.
incoming (JSONDict) – The input dict
. This is supposed to be the result of fix_defaults()
.
predicates (JSONDict) – A view-by-predicates of the template dict
.
Notes
This is porcelain over recursive function _rec_check_predicates()
.
parselglossy.validation.
fix_defaults
(incoming: Dict[str, Any], *, types: Dict[str, Any]) → Dict[str, Any][source]¶Fix default values and perform type checking.
incoming (JSONDict) – The input dict
. This is supposed to be the one obtained by merging
user and template dict
-s.
types (JSONDict) – Types of all keywords in the input. Generated from view_by_types()
.
outgoing – A dictionary with all default values fixed.
JSONDict
Notes
Since we allow callables to appear as defaults, we need to run them to determine the actual default values.
This operation must be done with some care, to avoid false negatives or ambiguous type checks. For example:
If the type is str
and the default a callable, the type will
match, but the default will make no sense.
If the type is numerical, e.g. int
, the type will not match.
However, by design the callables must refer to some other field in the input tree, hence they must contain the reserved token “user”. This allows us to disambiguate a callable as default from a value as default.
The final strategy adopted is then:
1. Perform type checking with type_matches()
. If successful, we
coerce the type.
2. If types did not match, we further check whether the value is a string,
containing the reserved token “value”. This means the default value is
actually a callable. We run the callable, which internally coerces the type
of the result to the expected one.
3. If even this check was unsuccessful, types really were unmatched. We
report the error and move on.
This is porcelain over recursive function _rec_fix_defaults()
.
parselglossy.validation.
is_template_valid
(template: Dict[str, Any]) → Dict[str, Any][source]¶Checks a template dict
is well-formed.
A template dict
is well-formed if:
All keywords have:
An allowed type.
A non-empty docstring.
A default callable that is valid Python, if present.
Predicates that are valid Python, if present.
Note that the latter two criteria can only be checked later on.
No sections are nested under keywords.
All sections have a non-empty docstring.
Reorders keywords according to their dependencies.
template (JSONDict) –
ordered
JSONDict
Notes
This is porcelain over the recursive _rec_is_template_valid()
.
parselglossy.validation.
merge_ours
(*, theirs: Dict[str, Any], ours: Dict[str, Any]) → Dict[str, Any][source]¶Recursively merge two dict-s with “ours” strategy.
theirs (JSONDict) –
ours (JSONDict) –
outgoing
JSONDict
Notes
The theirs
dictionary is supposed to be the view by defaults of the
validation specification, whereas ours
is the dictionary from user
input. The recursive merge action will generate a complete, but not
validated, input dictionary by using default values where these are not
overridden by user input, hence the naming “ours” for the merge strategy.
This is porcelain over the recursive function _rec_merge_ours()
.
parselglossy.validation.
validate_from_dicts
(*, ir: Dict[str, Any], template: Dict[str, Any], fr_file: Union[str, pathlib.Path] = None) → Dict[str, Any][source]¶Validate intermediate representation into final representation.
dumpir (bool) – Whether to serialize FR to JSON. Location and name of file are determined based on the input file.
ir (JSONDict) – Intermediate representation of the input file.
fr_file (Union[str, Path]) – File to write final representation to (JSON format). None by default, which means file is not written out.
fr – The validated input.
JSONDict