예제 #1
0
 def to_yaml(self, data: typing.Any) -> str:
     if isinstance(data, Sequence):
         if len(data) != 3:
             raise YAMLSerializationError(
                 f"expected a sequence of 3 elements, got {len(data)} elements"
             )
         for item in data:
             if not isinstance(item, int):
                 raise YAMLSerializationError(
                     f"expected int, got '{item}' of type '{type(item).__name__}'"
                 )
             if item < 0:
                 raise YAMLSerializationError(
                     f"expected non-negative int, got {item}")
         return ".".join(str(segment) for segment in data)
     if is_string(data):
         # we just validated that it's a string
         version_string = typing.cast(str, data)
         if self.REGEX.fullmatch(version_string) is None:
             raise YAMLSerializationError(
                 "expected Python version (MAJOR.MINOR.MICRO),"
                 f" got '{version_string}'")
         return version_string
     raise YAMLSerializationError(
         "expected string or sequence,"
         f" got '{data}' of type '{type(data).__name__}'")
예제 #2
0
def schema_from_data(data, allow_empty):
    if isinstance(data, dict):
        if len(data) == 0:
            if allow_empty:
                return EmptyDict()
            raise YAMLSerializationError(
                "Empty dicts are not serializable to StrictYAML unless schema is used."
            )
        return Map({
            key: schema_from_data(value, allow_empty)
            for key, value in data.items()
        })
    elif isinstance(data, list):
        if len(data) == 0:
            if allow_empty:
                return EmptyList()
            raise YAMLSerializationError(
                "Empty lists are not serializable to StrictYAML unless schema is used."
            )
        return FixedSeq([schema_from_data(item, allow_empty) for item in data])
    elif isinstance(data, bool):
        return Bool()
    elif isinstance(data, int):
        return Int()
    elif isinstance(data, float):
        return Float()
    else:
        return Str()
예제 #3
0
 def _should_be_mapping(self, data):
     if not isinstance(data, dict):
         raise YAMLSerializationError(
             "Expected a dict, found '{}'".format(data))
     if len(data) == 0:
         raise YAMLSerializationError(
             ("Expected a non-empty dict, found an empty dict.\n"
              "Use EmptyDict validator to serialize empty dicts."))
예제 #4
0
 def _should_be_list(self, data):
     if not isinstance(data, list):
         raise YAMLSerializationError(
             "Expected a list, found '{}'".format(data))
     if len(data) == 0:
         raise YAMLSerializationError(
             ("Expected a non-empty list, found an empty list.\n"
              "Use EmptyList validator to serialize empty lists."))
예제 #5
0
 def to_yaml(self, data):
     if isinstance(data, datetime):
         return data.isoformat()
     if utils.is_string(data):
         try:
             dateutil.parser.parse(data)
             return data
         except ValueError:
             raise YAMLSerializationError(
                 "expected a datetime, got '{}'".format(data))
     raise YAMLSerializationError(
         "expected a datetime, got '{}' of type '{}'".format(
             data,
             type(data).__name__))
예제 #6
0
 def to_yaml(self, data):
     if utils.has_number_type(data):
         return str(data)
     if utils.is_string(data) and utils.is_decimal(data):
         return data
     raise YAMLSerializationError(
         "when expecting a float, got '{}'".format(data))
예제 #7
0
def schema_from_data(data):
    if isinstance(data, dict):
        if len(data) == 0:
            raise YAMLSerializationError(
                "Empty dicts are not serializable to StrictYAML unless schema is used."
            )
        return Map(
            {key: schema_from_data(value)
             for key, value in data.items()})
    elif isinstance(data, list):
        if len(data) == 0:
            raise YAMLSerializationError(
                "Empty lists are not serializable to StrictYAML unless schema is used."
            )
        return FixedSeq([schema_from_data(item) for item in data])
    else:
        return Str()
예제 #8
0
 def to_yaml(self, data):
     if not isinstance(data, bool):
         if str(data).lower() in constants.BOOL_VALUES:
             return data
         else:
             raise YAMLSerializationError("Not a boolean")
     else:
         return u"yes" if data else u"no"
예제 #9
0
    def to_yaml(self, data):
        self._should_be_list(data)

        if len(set(data)) < len(data):
            raise YAMLSerializationError(
                ("Expecting all unique items, "
                 "but duplicates were found in '{}'.".format(data)))

        return CommentedSeq([self._validator.to_yaml(item) for item in data])
예제 #10
0
 def to_yaml(self, data):
     if isinstance(data, list):
         return ", ".join(
             [self._item_validator.to_yaml(item) for item in data])
     elif utils.is_string(data):
         for item in data.split(","):
             self._item_validator.to_yaml(item)
         return data
     else:
         raise YAMLSerializationError(
             "expected string or list, got '{}' of type '{}'".format(
                 data,
                 type(data).__name__))
예제 #11
0
    def __setitem__(self, index, value):
        strictindex = self._strictindex(index)

        # Generate nice error messages - first, copy our whole node's data
        # and use ``to_yaml()`` to determine if the resulting data would
        # validate our schema.  Must replace whole current node to support
        # complex types, e.g. ``EmptyList() | Seq(Str())``.
        if isinstance(value, YAML):
            yaml_value = self._chunk.fork(strictindex, value)
            new_value = self._validator(yaml_value)
        else:
            old_data = self.data
            if isinstance(old_data, dict):
                old_data[index] = value
            elif isinstance(old_data, list):
                if len(old_data) <= index:
                    raise YAMLSerializationError(
                        "cannot extend list via __setitem__.  "
                        "Instead, replace whole list on parent "
                        "node.")
                old_data[index] = value
            else:
                raise NotImplementedError(repr(old_data))
            yaml_value = YAMLChunk(self._validator.to_yaml(old_data))
            yaml_value_repr = self._validator(yaml_value)

            # Now that the new content is properly validated, create a valid
            # chunk with the new information.
            forked_chunk = self._chunk.fork(strictindex,
                                            yaml_value_repr[strictindex])
            new_value = self._validator(forked_chunk)

        # Now, overwrite our chunk and value with the new information.
        old_chunk = self._chunk  # Needed for reference to pre-fork ruamel
        self._chunk = new_value._chunk
        self._value = new_value._value
        self._text = new_value._text
        self._selected_validator = new_value._selected_validator
        # Update any parent ruamel links to point to our new chunk.
        self._chunk.pointer.set(old_chunk, "_ruamelparsed",
                                new_value._chunk.contents)
        self._chunk.pointer.set(old_chunk,
                                "_strictparsed",
                                self,
                                strictdoc=True)
        # forked chunk made a deep copy of the original document, but we just
        # updated pointers in the original document.  So, restore our chunk to
        # pointing at the original document.
        self._chunk._ruamelparsed = old_chunk._ruamelparsed
        self._chunk._strictparsed = old_chunk._strictparsed
예제 #12
0
 def to_yaml(self, data):
     if not utils.is_string(data):
         raise YAMLSerializationError("'{}' is not a string".format(data))
     if "\n" in data:
         return PreservedScalarString(data)
     return data
예제 #13
0
 def to_yaml(self, data):
     if data not in self._restricted_to:
         raise YAMLSerializationError(
             "Got '{0}' when  expecting one of: {1}".format(
                 data, ", ".join(self._restricted_to)))
     return self._item_validator.to_yaml(data)
예제 #14
0
 def should_be_string(self, data, message):
     if not utils.is_string(data):
         raise YAMLSerializationError("{0} got '{1}' of type {2}.".format(
             message, data,
             type(data).__name__))
예제 #15
0
 def to_yaml(self, data):
     if data == []:
         return u""
     raise YAMLSerializationError("expected empty list, got '{}'")
예제 #16
0
 def to_yaml(self, data):
     if data == {}:
         return u""
     raise YAMLSerializationError("Not an empty dict")
예제 #17
0
 def to_yaml(self, data):
     self.should_be_string(data, self._matching_message)
     if re.compile(self._regex).match(data) is None:
         raise YAMLSerializationError("{} found '{}'".format(
             self._matching_message, data))
     return data
예제 #18
0
 def to_yaml(self, data):
     if utils.is_string(data) or isinstance(data, int):
         if utils.is_integer(str(data)):
             return str(data)
     raise YAMLSerializationError("'{}' not an integer.".format(data))
예제 #19
0
 def to_yaml(self, data):
     if not utils.is_string(data):
         raise YAMLSerializationError("'{}' is not a string".format(data))
     return str(data)
예제 #20
0
 def to_yaml(self, data):
     if data is None:
         return u""
     raise YAMLSerializationError("expected None, got '{}'")
예제 #21
0
 def to_yaml(self, data):
     if not isinstance(data, self._enum):
         raise YAMLSerializationError(
             "Got '{0}' when  expecting one of: {1}".format(
                 data, ", ".join(str(elem) for elem in self._enum)))
     return data.name