mirror of
https://github.com/yaml/pyyaml.git
synced 2025-10-19 11:03:18 +00:00
Allow to turn off sorting keys in Dumper
This commit is contained in:
parent
611ba39507
commit
07c88c6c1b
14 changed files with 110 additions and 35 deletions
|
@ -256,7 +256,7 @@ def dump_all(documents, stream=None, Dumper=Dumper,
|
|||
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.
|
||||
|
@ -274,7 +274,7 @@ def dump_all(documents, stream=None, Dumper=Dumper,
|
|||
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:
|
||||
|
|
|
@ -55,14 +55,14 @@ class CBaseDumper(CEmitter, BaseRepresenter, BaseResolver):
|
|||
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):
|
||||
|
@ -72,14 +72,14 @@ class CSafeDumper(CEmitter, SafeRepresenter, Resolver):
|
|||
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):
|
||||
|
@ -89,13 +89,13 @@ class CDumper(CEmitter, Serializer, Representer, Resolver):
|
|||
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)
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver):
|
|||
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 @@ class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver):
|
|||
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 @@ class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver):
|
|||
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 @@ class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver):
|
|||
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 @@ class Dumper(Emitter, Serializer, Representer, Resolver):
|
|||
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 @@ class Dumper(Emitter, Serializer, Representer, Resolver):
|
|||
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)
|
||||
|
||||
|
|
|
@ -17,9 +17,10 @@ class BaseRepresenter(object):
|
|||
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,6 +118,7 @@ class BaseRepresenter(object):
|
|||
best_style = True
|
||||
if hasattr(mapping, 'items'):
|
||||
mapping = mapping.items()
|
||||
if self.sort_keys:
|
||||
mapping.sort()
|
||||
for item_key, item_value in mapping:
|
||||
node_key = self.represent_data(item_key)
|
||||
|
|
|
@ -254,7 +254,7 @@ def dump_all(documents, stream=None, Dumper=Dumper,
|
|||
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.
|
||||
|
@ -271,7 +271,7 @@ def dump_all(documents, stream=None, Dumper=Dumper,
|
|||
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:
|
||||
|
|
|
@ -55,14 +55,14 @@ class CBaseDumper(CEmitter, BaseRepresenter, BaseResolver):
|
|||
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):
|
||||
|
@ -72,14 +72,14 @@ class CSafeDumper(CEmitter, SafeRepresenter, Resolver):
|
|||
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):
|
||||
|
@ -89,13 +89,13 @@ class CDumper(CEmitter, Serializer, Representer, Resolver):
|
|||
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)
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver):
|
|||
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 @@ class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver):
|
|||
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 @@ class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver):
|
|||
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 @@ class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver):
|
|||
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 @@ class Dumper(Emitter, Serializer, Representer, Resolver):
|
|||
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 @@ class Dumper(Emitter, Serializer, Representer, Resolver):
|
|||
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)
|
||||
|
||||
|
|
|
@ -15,8 +15,9 @@ class BaseRepresenter:
|
|||
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,6 +108,7 @@ class BaseRepresenter:
|
|||
best_style = True
|
||||
if hasattr(mapping, 'items'):
|
||||
mapping = list(mapping.items())
|
||||
if self.sort_keys:
|
||||
try:
|
||||
mapping = sorted(mapping)
|
||||
except TypeError:
|
||||
|
|
6
tests/data/mapping.sort
Normal file
6
tests/data/mapping.sort
Normal file
|
@ -0,0 +1,6 @@
|
|||
z: 1
|
||||
a: 2
|
||||
y: 3
|
||||
b: 4
|
||||
x: 5
|
||||
c: 6
|
6
tests/data/mapping.sorted
Normal file
6
tests/data/mapping.sorted
Normal file
|
@ -0,0 +1,6 @@
|
|||
a: 2
|
||||
b: 4
|
||||
c: 6
|
||||
x: 5
|
||||
y: 3
|
||||
z: 1
|
28
tests/lib/test_sort_keys.py
Normal file
28
tests/lib/test_sort_keys.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
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, Loader=yaml.FullLoader)
|
||||
dump_sorted = yaml.dump(data, default_flow_style=False, sort_keys=True)
|
||||
dump_unsorted = yaml.dump(data, default_flow_style=False, sort_keys=False)
|
||||
dump_unsorted = yaml.dump(data, default_flow_style=False, sort_keys=False, Dumper=yaml.SafeDumper)
|
||||
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())
|
||||
|
|
@ -11,6 +11,7 @@ from test_emitter import *
|
|||
from test_representer import *
|
||||
from test_recursive import *
|
||||
from test_input_output import *
|
||||
from test_sort_keys import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
import test_appliance
|
||||
|
|
29
tests/lib3/test_sort_keys.py
Normal file
29
tests/lib3/test_sort_keys.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
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, Loader=yaml.FullLoader)
|
||||
dump_sorted = yaml.dump(data, default_flow_style=False, sort_keys=True)
|
||||
dump_unsorted = yaml.dump(data, default_flow_style=False, sort_keys=False)
|
||||
dump_unsorted_safe = yaml.dump(data, default_flow_style=False, sort_keys=False, Dumper=yaml.SafeDumper)
|
||||
if verbose:
|
||||
print("INPUT:")
|
||||
print(input)
|
||||
print("DATA:")
|
||||
print(data)
|
||||
|
||||
assert dump_sorted == sorted
|
||||
|
||||
if sys.version_info>=(3,7):
|
||||
assert dump_unsorted == input
|
||||
assert dump_unsorted_safe == input
|
||||
|
||||
test_sort_keys.unittest = ['.sort', '.sorted']
|
||||
|
||||
if __name__ == '__main__':
|
||||
import test_appliance
|
||||
test_appliance.run(globals())
|
||||
|
|
@ -11,6 +11,7 @@ from test_emitter import *
|
|||
from test_representer import *
|
||||
from test_recursive import *
|
||||
from test_input_output import *
|
||||
from test_sort_keys import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
import test_appliance
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue