def validate_attributes(attributes: dict, node: Node) -> None: ''' Validates node attributes for rule compliance. Iterates through the dict of attribute rules and validates whether the node instance complies with the rule. Args: attributes: dict of rule attributes node: Node instance to be validates Returns: None Raises: MetapypeRuleError: Illegal attribute or missing required attribute ''' for attribute in attributes: required = attributes[attribute][0] # Test for required attributes if required and attribute not in node.attributes: msg = f'"{attribute}" is a required attribute of node "{node.name}"' raise MetapypeRuleError(msg) for attribute in node.attributes: # Test for non-allowed attribute if attribute not in attributes: msg = f'"{attribute}" is not a recognized attributes of node "{node.name}"' raise MetapypeRuleError(msg) else: # Test for enumerated list of allowed values if len(attributes[attribute]) > 1 and node.attributes[ attribute] not in attributes[attribute][1:]: msg = f'Node "{node.name}" attribute "{attribute}" must be one of the following: "{attributes[attribute][1:]}"' raise MetapypeRuleError(msg)
def _validate_content(self, content, node: Node): if node.content is not None and type(node.content) is not str: msg = f'Node "{node.name}" content should be type "{TYPE_STR}", not "{type(node.content)}"' raise MetapypeRuleError(msg) if len(node.children) == 0 and node.content is None: msg = f'Node "{node.name}" content should not be empty' raise MetapypeRuleError(msg)
def _validate_content(self, content, node: Node): if node.content is None or type(node.content) is not str: msg = f'Node "{node.name}" content should be type "{TYPE_STR}", not "{type(node.content)}"' raise MetapypeRuleError(msg) if node.content not in PERMISSIONS: msg = f'Node "{node.name}" content should be one of "{PERMISSIONS}", not "{node.content}"' raise MetapypeRuleError(msg)
def validate_children(children: list, node: Node) -> None: ''' Validates node children for rule compliance. Iterates through the list children rules and validates whether the node instance complies with the rules. Args: children: list of lists containing children node: Node instance to be validated Returns: None Raises: MetapypeRuleError: Illegal child, bad sequence or choice, missing child, or wrong child cardinality ''' i = 0 max_i = len(node.children) for child in children: name = child[:-2] min = child[-2] max = child[-1] cnt = 0 while i < max_i: child_name = node.children[i].name if child_name in name: cnt += 1 if max is not INFINITY and cnt > max: msg = f'Maximum occurrence of "{name}" exceeded for "{node.name}"' raise MetapypeRuleError(msg) i += 1 else: break if cnt < min: msg = f'Minimum occurrence of "{name}" not met for "{node.name}"' raise MetapypeRuleError(msg) if i < max_i: child_name = node.children[i].name msg = f'Child "{child_name}" not allowed for "{node.name}"' raise MetapypeRuleError(msg)
def node(node: Node) -> None: ''' Validates a given node for rule compliance. Args: node: Node instance to be validated Returns: None Raises: MetapypeRuleError: An unknown type of node for EML 2.1.1 ''' if node.name not in rule.node_mappings: msg = 'Unknown node: {}'.format(node.name) raise MetapypeRuleError(msg) else: node_rule = rule.get_rule(node.name) node_rule.validate_rule(node)
def _validate_content(self, content, node: Node): if node.content is not None: msg = f'Node "{node.name}" content should be empty' raise MetapypeRuleError(msg)
def _validate_yeardate_content(self, node: Node): val = node.content if val is not None and not Rule.is_yeardate(val): msg = f'Node "{node.name}" format should be year ("YYYY") or date ("YYYY-MM-DD")' raise MetapypeRuleError(msg)
def _validate_str_content(self, node: Node): if node.content is not None and type(node.content) is not str: msg = f'Node "{node.name}" content should be type "{TYPE_STR}", not "{type(node.content)}"' raise MetapypeRuleError(msg)
def _validate_non_empty_content(self, node: Node): if len(node.children) == 0 and node.content is None: msg = f'Node "{node.name}" content should not be empty' raise MetapypeRuleError(msg)
def _validate_float_content(self, node: Node): val = node.content if val is not None and not Rule.is_float(val): msg = f'Node "{node.name}" content should by type "{TYPE_FLOAT}", not "{type(node.content)}"' raise MetapypeRuleError(msg)
def _validate_enum_content(self, node: Node, enum_values: list): if node.content not in enum_values: msg = f'Node "{node.name}" content should be one of "{enum_values}", not "{node.content}"' raise MetapypeRuleError(msg)
def _get_child_position(self, node_name: str): for position in range(0, len(self.children)): if node_name in self.children[position][:-2]: return position msg = f'Child "{node_name}" not allowed' raise MetapypeRuleError(msg)