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__}'")
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()
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."))
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."))
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__))
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))
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()
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"
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])
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__))
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
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
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)
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__))
def to_yaml(self, data): if data == []: return u"" raise YAMLSerializationError("expected empty list, got '{}'")
def to_yaml(self, data): if data == {}: return u"" raise YAMLSerializationError("Not an empty dict")
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
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))
def to_yaml(self, data): if not utils.is_string(data): raise YAMLSerializationError("'{}' is not a string".format(data)) return str(data)
def to_yaml(self, data): if data is None: return u"" raise YAMLSerializationError("expected None, got '{}'")
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