Allow to turn off sorting keys in Dumper
diff --git a/lib/yaml/__init__.py b/lib/yaml/__init__.py index eae5949..d90b4e8 100644 --- a/lib/yaml/__init__.py +++ b/lib/yaml/__init__.py
@@ -165,7 +165,7 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding='utf-8', explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): """ Serialize a sequence of Python objects into a YAML stream. If stream is None, return the produced string instead. @@ -183,7 +183,7 @@ canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break, encoding=encoding, version=version, tags=tags, - explicit_start=explicit_start, explicit_end=explicit_end) + explicit_start=explicit_start, explicit_end=explicit_end, sort_keys=sort_keys) try: dumper.open() for data in documents:
diff --git a/lib/yaml/cyaml.py b/lib/yaml/cyaml.py index 68dcd75..9be4b7f 100644 --- a/lib/yaml/cyaml.py +++ b/lib/yaml/cyaml.py
@@ -39,14 +39,14 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): CEmitter.__init__(self, stream, canonical=canonical, indent=indent, width=width, encoding=encoding, allow_unicode=allow_unicode, line_break=line_break, explicit_start=explicit_start, explicit_end=explicit_end, version=version, tags=tags) Representer.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) + default_flow_style=default_flow_style, sort_keys=sort_keys) Resolver.__init__(self) class CSafeDumper(CEmitter, SafeRepresenter, Resolver): @@ -56,14 +56,14 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): CEmitter.__init__(self, stream, canonical=canonical, indent=indent, width=width, encoding=encoding, allow_unicode=allow_unicode, line_break=line_break, explicit_start=explicit_start, explicit_end=explicit_end, version=version, tags=tags) SafeRepresenter.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) + default_flow_style=default_flow_style, sort_keys=sort_keys) Resolver.__init__(self) class CDumper(CEmitter, Serializer, Representer, Resolver): @@ -73,13 +73,13 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): CEmitter.__init__(self, stream, canonical=canonical, indent=indent, width=width, encoding=encoding, allow_unicode=allow_unicode, line_break=line_break, explicit_start=explicit_start, explicit_end=explicit_end, version=version, tags=tags) Representer.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) + default_flow_style=default_flow_style, sort_keys=sort_keys) Resolver.__init__(self)
diff --git a/lib/yaml/dumper.py b/lib/yaml/dumper.py index f811d2c..6fa7855 100644 --- a/lib/yaml/dumper.py +++ b/lib/yaml/dumper.py
@@ -13,7 +13,7 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): Emitter.__init__(self, stream, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break) @@ -21,7 +21,7 @@ explicit_start=explicit_start, explicit_end=explicit_end, version=version, tags=tags) Representer.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) + default_flow_style=default_flow_style, sort_keys=sort_keys) Resolver.__init__(self) class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver): @@ -31,7 +31,7 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): Emitter.__init__(self, stream, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break) @@ -39,7 +39,7 @@ explicit_start=explicit_start, explicit_end=explicit_end, version=version, tags=tags) SafeRepresenter.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) + default_flow_style=default_flow_style, sort_keys=sort_keys) Resolver.__init__(self) class Dumper(Emitter, Serializer, Representer, Resolver): @@ -49,7 +49,7 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): Emitter.__init__(self, stream, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break) @@ -57,6 +57,6 @@ explicit_start=explicit_start, explicit_end=explicit_end, version=version, tags=tags) Representer.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) + default_flow_style=default_flow_style, sort_keys=sort_keys) Resolver.__init__(self)
diff --git a/lib/yaml/representer.py b/lib/yaml/representer.py index f249f08..3432cc7 100644 --- a/lib/yaml/representer.py +++ b/lib/yaml/representer.py
@@ -17,9 +17,10 @@ yaml_representers = {} yaml_multi_representers = {} - def __init__(self, default_style=None, default_flow_style=None): + def __init__(self, default_style=None, default_flow_style=None, sort_keys=True): self.default_style = default_style self.default_flow_style = default_flow_style + self.sort_keys = sort_keys self.represented_objects = {} self.object_keeper = [] self.alias_key = None @@ -117,7 +118,8 @@ best_style = True if hasattr(mapping, 'items'): mapping = mapping.items() - mapping.sort() + if self.sort_keys: + mapping.sort() for item_key, item_value in mapping: node_key = self.represent_data(item_key) node_value = self.represent_data(item_value)
diff --git a/lib3/yaml/__init__.py b/lib3/yaml/__init__.py index 5a6d851..42184fb 100644 --- a/lib3/yaml/__init__.py +++ b/lib3/yaml/__init__.py
@@ -164,7 +164,7 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): """ Serialize a sequence of Python objects into a YAML stream. If stream is None, return the produced string instead. @@ -181,7 +181,7 @@ canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break, encoding=encoding, version=version, tags=tags, - explicit_start=explicit_start, explicit_end=explicit_end) + explicit_start=explicit_start, explicit_end=explicit_end, sort_keys=sort_keys) try: dumper.open() for data in documents:
diff --git a/lib3/yaml/cyaml.py b/lib3/yaml/cyaml.py index d5cb87e..6c4beaf 100644 --- a/lib3/yaml/cyaml.py +++ b/lib3/yaml/cyaml.py
@@ -39,14 +39,14 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): CEmitter.__init__(self, stream, canonical=canonical, indent=indent, width=width, encoding=encoding, allow_unicode=allow_unicode, line_break=line_break, explicit_start=explicit_start, explicit_end=explicit_end, version=version, tags=tags) Representer.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) + default_flow_style=default_flow_style, sort_keys=sort_keys) Resolver.__init__(self) class CSafeDumper(CEmitter, SafeRepresenter, Resolver): @@ -56,14 +56,14 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): CEmitter.__init__(self, stream, canonical=canonical, indent=indent, width=width, encoding=encoding, allow_unicode=allow_unicode, line_break=line_break, explicit_start=explicit_start, explicit_end=explicit_end, version=version, tags=tags) SafeRepresenter.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) + default_flow_style=default_flow_style, sort_keys=sort_keys) Resolver.__init__(self) class CDumper(CEmitter, Serializer, Representer, Resolver): @@ -73,13 +73,13 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): CEmitter.__init__(self, stream, canonical=canonical, indent=indent, width=width, encoding=encoding, allow_unicode=allow_unicode, line_break=line_break, explicit_start=explicit_start, explicit_end=explicit_end, version=version, tags=tags) Representer.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) + default_flow_style=default_flow_style, sort_keys=sort_keys) Resolver.__init__(self)
diff --git a/lib3/yaml/dumper.py b/lib3/yaml/dumper.py index 0b69128..b17ffa3 100644 --- a/lib3/yaml/dumper.py +++ b/lib3/yaml/dumper.py
@@ -13,7 +13,7 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): Emitter.__init__(self, stream, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break) @@ -21,7 +21,7 @@ explicit_start=explicit_start, explicit_end=explicit_end, version=version, tags=tags) Representer.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) + default_flow_style=default_flow_style, sort_keys=sort_keys) Resolver.__init__(self) class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver): @@ -31,7 +31,7 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): Emitter.__init__(self, stream, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break) @@ -39,7 +39,7 @@ explicit_start=explicit_start, explicit_end=explicit_end, version=version, tags=tags) SafeRepresenter.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) + default_flow_style=default_flow_style, sort_keys=sort_keys) Resolver.__init__(self) class Dumper(Emitter, Serializer, Representer, Resolver): @@ -49,7 +49,7 @@ canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, - version=None, tags=None): + version=None, tags=None, sort_keys=True): Emitter.__init__(self, stream, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break) @@ -57,6 +57,6 @@ explicit_start=explicit_start, explicit_end=explicit_end, version=version, tags=tags) Representer.__init__(self, default_style=default_style, - default_flow_style=default_flow_style) + default_flow_style=default_flow_style, sort_keys=sort_keys) Resolver.__init__(self)
diff --git a/lib3/yaml/representer.py b/lib3/yaml/representer.py index 483005f..2f230bb 100644 --- a/lib3/yaml/representer.py +++ b/lib3/yaml/representer.py
@@ -15,8 +15,9 @@ yaml_representers = {} yaml_multi_representers = {} - def __init__(self, default_style=None, default_flow_style=None): + def __init__(self, default_style=None, default_flow_style=None, sort_keys=True): self.default_style = default_style + self.sort_keys = sort_keys self.default_flow_style = default_flow_style self.represented_objects = {} self.object_keeper = [] @@ -107,10 +108,11 @@ best_style = True if hasattr(mapping, 'items'): mapping = list(mapping.items()) - try: - mapping = sorted(mapping) - except TypeError: - pass + if self.sort_keys: + try: + mapping = sorted(mapping) + except TypeError: + pass for item_key, item_value in mapping: node_key = self.represent_data(item_key) node_value = self.represent_data(item_value)
diff --git a/tests/data/mapping.sort b/tests/data/mapping.sort new file mode 100644 index 0000000..802ba1a --- /dev/null +++ b/tests/data/mapping.sort
@@ -0,0 +1,6 @@ +z: 1 +a: 2 +y: 3 +b: 4 +x: 5 +c: 6
diff --git a/tests/data/mapping.sorted b/tests/data/mapping.sorted new file mode 100644 index 0000000..b3dd346 --- /dev/null +++ b/tests/data/mapping.sorted
@@ -0,0 +1,6 @@ +a: 2 +b: 4 +c: 6 +x: 5 +y: 3 +z: 1
diff --git a/tests/lib/test_sort_keys.py b/tests/lib/test_sort_keys.py new file mode 100644 index 0000000..f347659 --- /dev/null +++ b/tests/lib/test_sort_keys.py
@@ -0,0 +1,27 @@ +import yaml +import pprint +import sys + +def test_sort_keys(input_filename, sorted_filename, verbose=False): + input = open(input_filename, 'rb').read().decode('utf-8') + sorted = open(sorted_filename, 'rb').read().decode('utf-8') + data = yaml.load(input) + dump_sorted = yaml.dump(data, default_flow_style=False, sort_keys=True) + dump_unsorted = yaml.dump(data, default_flow_style=False, sort_keys=False) + if verbose: + print("INPUT:") + print(input) + print("DATA:") + print(data) + + assert dump_sorted == sorted + + + + +test_sort_keys.unittest = ['.sort', '.sorted'] + +if __name__ == '__main__': + import test_appliance + test_appliance.run(globals()) +
diff --git a/tests/lib3/test_sort_keys.py b/tests/lib3/test_sort_keys.py new file mode 100644 index 0000000..519ce5c --- /dev/null +++ b/tests/lib3/test_sort_keys.py
@@ -0,0 +1,27 @@ +import yaml +import pprint +import sys + +def test_sort_keys(input_filename, sorted_filename, verbose=False): + input = open(input_filename, 'rb').read().decode('utf-8') + sorted = open(sorted_filename, 'rb').read().decode('utf-8') + data = yaml.load(input) + dump_sorted = yaml.dump(data, default_flow_style=False, sort_keys=True) + dump_unsorted = yaml.dump(data, default_flow_style=False, sort_keys=False) + if verbose: + print("INPUT:") + print(input) + print("DATA:") + print(data) + + assert dump_sorted == sorted + + if sys.version_info>=(3,7): + assert dump_unsorted == input + +test_sort_keys.unittest = ['.sort', '.sorted'] + +if __name__ == '__main__': + import test_appliance + test_appliance.run(globals()) +