예제 #1
0
    def construct_mapping(self, node, deep=False):
        """Overrides default mapper with a version that detects duplicate keys."""

        if not isinstance(node, yaml.nodes.MappingNode):
            raise yaml.constructor.ConstructorError(
                None, None, 'Expected a mapping node, but found %s' % node.id,
                node.start_mark)
        mapping = {}
        for key_node, value_node in node.value:
            key = self.construct_object(key_node, deep=deep)
            try:
                hash(key)
            except TypeError:
                m1 = node.start_mark
                m2 = key_node.start_mark
                ctx = findings_lib.FileContext(m1.name, m1.line, m2.line)
                raise ParseError(findings_lib.IllegalKeyTypeError(key, ctx))
            # check for duplicate keys
            if key in mapping:
                m1 = node.start_mark
                m2 = key_node.start_mark
                ctx = findings_lib.FileContext(m1.name, m1.line, m2.line)
                raise ParseError(findings_lib.DuplicateKeyError(key, ctx))
            value = self.construct_object(value_node, deep=deep)
            mapping[key] = value
        return mapping
예제 #2
0
  def _ValidateType(self, local_field_names):
    """Validates that the entity type is formatted correctly.

    Checks for formatting and duplicate fields and parents.

    Records any errors found.

    Args:
      local_field_names: list of local field names for the type.
    """
    # Make sure the typename is non-empty.
    if not self.typename:
      self.AddFinding(findings_lib.MissingTypenameError(self))
    elif not isinstance(self.typename, str):
      self.AddFinding(
          findings_lib.IllegalKeyTypeError(self.typename, self.file_context))
    elif not ENTITY_TYPE_NAME_REGEX.match(self.typename):
      self.AddFinding(
          findings_lib.IllegalCharacterError(self.typename, self.file_context))

    # Make sure the type description is non-empty.
    if not self.description:
      self.AddFinding(findings_lib.MissingDescriptionWarning(self))

    # Check for duplicate local fields.
    # this check is case insensitive to catch dupes earlier in the event that
    # we stop explicitly rejecting upper case characters
    check_fields = set()
    for field in local_field_names:
      field_lower = field.lower()
      if field_lower in check_fields:
        self.AddFinding(findings_lib.DuplicateFieldError(self, field))
        continue
      check_fields.add(field_lower)

      # TODO(berkoben): Add more checks to validate fields in isolation
      # (in case we don't have a field set to check against)
      # (i.e. check for chirality, formatting. Could use actual Field objects)

      # Check formatting of field name
      if len(field.split('/')) > 2:
        self.AddFinding(findings_lib.UnrecognizedFieldFormatError(self, field))

    # Check for duplicate parent names.
    parent_names_check = set()
    for parent_name in self.unqualified_parent_names:
      if parent_name in parent_names_check:
        self.AddFinding(findings_lib.DuplicateParentError(self, parent_name))
        continue
      parent_names_check.add(parent_name)

      # Check formatting of parent name
      if len(parent_name.split('/')) > 2:
        self.AddFinding(
            findings_lib.UnrecognizedParentFormatError(self, parent_name))

    # Enforce that the inherited_fields_expanded field is not set
    if self.inherited_fields_expanded:
      self.AddFinding(findings_lib.InheritedFieldsSetError(self))
예제 #3
0
    def __init__(self, name, description=None, context=None):
        super(State, self).__init__()
        self.name = name
        self.description = description
        self.context = context

        if not isinstance(name, str):
            self.AddFinding(findings_lib.IllegalKeyTypeError(name, context))
        elif not STATE_NAME_VALIDATOR.match(name):
            self.AddFinding(findings_lib.IllegalCharacterError(name, context))
        if not description:
            self.AddFinding(findings_lib.MissingStateDescriptionWarning(self))
예제 #4
0
    def __init__(self, name, states=None, context=None):
        super(Field, self).__init__()
        self.context = context
        self.name = name
        self.subfields = []
        self.states = states

        if not isinstance(name, str):
            self.AddFinding(findings_lib.IllegalKeyTypeError(name, context))
        elif not FIELD_CHARACTER_REGEX.match(name):
            self.AddFinding(findings_lib.IllegalCharacterError(name, context))
        else:
            self.InitAndValidateSubfields()
            self.ValidateStates()
예제 #5
0
    def __init__(self,
                 name,
                 measurement_type,
                 is_standard=False,
                 context=None):
        super(Unit, self).__init__()
        self.name = name
        self.measurement_type = measurement_type
        self.is_standard = is_standard
        self.context = context

        if not isinstance(name, str):
            self.AddFinding(findings_lib.IllegalKeyTypeError(name, context))
        elif not UNIT_NAME_VALIDATOR.match(name):
            self.AddFinding(findings_lib.IllegalCharacterError(name, context))
예제 #6
0
    def __init__(self, name, category, description=None, context=None):
        super(Subfield, self).__init__()
        self.context = context
        self.name = name
        self.description = description
        self.category = category

        if not isinstance(name, str):
            self.AddFinding(findings_lib.IllegalKeyTypeError(name, context))
        elif not _SUBFIELD_NAME_VALIDATOR.match(name):
            self.AddFinding(findings_lib.IllegalCharacterError(name, context))
        if not self.description:
            self.AddFinding(
                findings_lib.MissingSubfieldDescriptionWarning(
                    self.name, self.context))
예제 #7
0
    def __init__(self,
                 name: str,
                 description: str = None,
                 context: findings_lib.FileContext = None):
        super(Connection, self).__init__()
        self.name = name
        self.description = description
        self.context = context

        if not isinstance(name, str):
            self.AddFinding(findings_lib.IllegalKeyTypeError(name, context))
        elif not CONNECTION_NAME_VALIDATOR.match(name):
            self.AddFinding(findings_lib.IllegalCharacterError(name, context))
        if not description:
            self.AddFinding(
                findings_lib.MissingConnectionDescriptionWarning(self))
예제 #8
0
    def __init__(self, name, is_standard=False, file_context=None):
        """Init.

    Args:
      name: required string name for the unit
      is_standard: whether this is the standard unit for the measurement type
      file_context: optional object with the config file location of this unit.

    Returns:
      Instance of Unit class.
    """
        super(Unit, self).__init__()
        self.name = name
        self.is_standard = is_standard
        self.file_context = file_context

        if not isinstance(name, str):
            self.AddFinding(
                findings_lib.IllegalKeyTypeError(name, file_context))
        elif not UNIT_NAME_VALIDATOR.match(name):
            self.AddFinding(
                findings_lib.InvalidUnitNameError(name, file_context))
예제 #9
0
  def __init__(self, name, states=None, context=None):
    """Init.

    Args:
      name: required string representing the field.
      states: optional list of strings representing valid states for a
        multistate field. Should be None for non-multistate fields.
      context: optional object with the config file location of this field.
    """
    super(Field, self).__init__()
    self.context = context
    self.name = name
    self.subfields = []
    self.states = states

    if not isinstance(name, str):
      self.AddFinding(findings_lib.IllegalKeyTypeError(name, context))
    elif not FIELD_CHARACTER_REGEX.match(name):
      self.AddFinding(findings_lib.IllegalCharacterError(name, context))
    else:
      self.InitAndValidateSubfields()
      self.ValidateStates()
예제 #10
0
    def __init__(self,
                 name,
                 measurement_type,
                 is_standard=False,
                 context=None):
        """Init.

    Args:
      name: required string name for the unit
      measurement_type: required string indicating the unit measurement type
      is_standard: whether this is the standard unit for the measurement type
      context: optional object with the config file location of this unit.
    """
        super(Unit, self).__init__()
        self.name = name
        self.measurement_type = measurement_type
        self.is_standard = is_standard
        self.context = context

        if not isinstance(name, str):
            self.AddFinding(findings_lib.IllegalKeyTypeError(name, context))
        elif not UNIT_NAME_VALIDATOR.match(name):
            self.AddFinding(findings_lib.IllegalCharacterError(name, context))
예제 #11
0
    def __init__(self, name, description=None, file_context=None):
        """Init.

    Args:
      name: required string representing the state.
      description: optional (for now) string semantic definition for the state.
      file_context: optional object with the config file location of this state.

    Returns:
      Instance of State class.
    """
        super(State, self).__init__()
        self.name = name
        self.description = description
        self.file_context = file_context

        if not isinstance(name, str):
            self.AddFinding(
                findings_lib.IllegalKeyTypeError(name, file_context))
        elif not STATE_NAME_VALIDATOR.match(name):
            self.AddFinding(
                findings_lib.InvalidStateNameError(name, file_context))
        if not description:
            self.AddFinding(findings_lib.MissingStateDescriptionWarning(self))