From: Philipp Gesang Date: Tue, 5 Dec 2017 10:38:40 +0000 (+0100) Subject: loosen criteria on CNF object roots X-Git-Tag: v1.4~18^2~10 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=0936b2f2ee48fabd41c5a35f611d3524328b25f3;p=pyi2ncommon loosen criteria on CNF object roots Single CNF_VARs are technically malformed since CNF file is always a list of vars. However, any isolated CNF line can be trivially converted to a valid CNF_VAR by wrapping it in a list ctor, so do that automatically when determining the root of a CNF_VAR. --- diff --git a/src/cnfvar.py b/src/cnfvar.py index d62d6cf..75857c7 100644 --- a/src/cnfvar.py +++ b/src/cnfvar.py @@ -246,13 +246,12 @@ def is_cnf(root): well-formed member of the argument will cause the predicate to bail out with an exception during traversal. """ - t_root = type(root) - if t_root is list: + if isinstance (root, list): cnf = root - elif t_root is dict: - cnf = root["cnf"] else: - raise InvalidCNF(root) + cnf = cnf_root (root) + if cnf is None: + raise InvalidCNF (root) return walk_cnf(cnf, False, is_valid, {}) is not None # @@ -591,10 +590,42 @@ def format_cnf_vars(da, var): return (depth, acc) -def cnf_root(root): +CNF_FIELD_MANDATORY = set ([ "varname", "data", "instance" ]) +CNF_FIELD_OPTIONAL = set ([ "parent", "children", "comment", "number" ]) +CNF_FIELD_KNOWN = CNF_FIELD_MANDATORY | CNF_FIELD_OPTIONAL + + +def is_cnf_var (obj): + """ + Applies if all mandatory fields of a CNF_VAR and no unknown fields are + present. + + .. XXX: validate field types. + """ + assert isinstance (obj, dict) + + for f in CNF_FIELD_MANDATORY: + if obj.get (f, None) is None: + return False + + for f in obj: + if f not in CNF_FIELD_KNOWN: + return False + + return True + + +def cnf_root (root): + """ + Of a given object, return the cnf root. This may be either a list + containing the object itself, if it satisfies the criteria for a CNF_VAR, + or the object contained in its toplevel field *cnf*. + """ if not isinstance(root, dict): raise TypeError( "Expected dictionary of CNF_VARs, got %s." % type(root)) + if is_cnf_var (root): + return [ root ] cnf = root.get("cnf", None) if not isinstance(cnf, list): raise TypeError("Expected list of CNF_VARs, got %s." % type(cnf))