Skip to content

Commit

Permalink
fix yaml output
Browse files Browse the repository at this point in the history
In b9be2de, OrderedDict was replaced with HashableOrderedDict.
Add logic to yamldumper to handle the new type.
  • Loading branch information
Tom Doherty authored and dwoz committed Sep 20, 2024
1 parent 9922b1a commit caf62f9
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 7 deletions.
1 change: 1 addition & 0 deletions changelog/66783.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fix yaml output
7 changes: 1 addition & 6 deletions salt/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
from salt.serializers.msgpack import deserialize as msgpack_deserialize
from salt.serializers.msgpack import serialize as msgpack_serialize
from salt.template import compile_template, compile_template_str
from salt.utils.odict import DefaultOrderedDict, OrderedDict
from salt.utils.odict import DefaultOrderedDict, HashableOrderedDict

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -127,11 +127,6 @@
).union(STATE_RUNTIME_KEYWORDS)


class HashableOrderedDict(OrderedDict):
def __hash__(self):
return id(self)


def split_low_tag(tag):
"""
Take a low tag and split it back into the low dict that it came from
Expand Down
5 changes: 5 additions & 0 deletions salt/utils/odict.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,8 @@ def __repr__(self, _repr_running={}): # pylint: disable=W0102
return "DefaultOrderedDict({}, {})".format(
self.default_factory, super().__repr__()
)


class HashableOrderedDict(OrderedDict):
def __hash__(self):
return id(self)
4 changes: 3 additions & 1 deletion salt/utils/yamldumper.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import yaml # pylint: disable=blacklisted-import

import salt.utils.context
from salt.utils.odict import OrderedDict
from salt.utils.odict import HashableOrderedDict, OrderedDict

try:
from yaml import CDumper as Dumper
Expand Down Expand Up @@ -71,7 +71,9 @@ def represent_undefined(dumper, data):


OrderedDumper.add_representer(OrderedDict, represent_ordereddict)
OrderedDumper.add_representer(HashableOrderedDict, represent_ordereddict)
SafeOrderedDumper.add_representer(OrderedDict, represent_ordereddict)
SafeOrderedDumper.add_representer(HashableOrderedDict, represent_ordereddict)
SafeOrderedDumper.add_representer(None, represent_undefined)

OrderedDumper.add_representer(
Expand Down
81 changes: 81 additions & 0 deletions tests/unit/utils/test_yamldumper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
Unit tests for salt.utils.yamldumper
"""

from collections import OrderedDict, defaultdict

import salt.utils.yamldumper
from salt.utils.context import NamespacedDictWrapper
from salt.utils.odict import HashableOrderedDict
from tests.support.unit import TestCase


Expand Down Expand Up @@ -35,3 +39,80 @@ def test_yaml_safe_dump(self):
salt.utils.yamldumper.safe_dump(data, default_flow_style=False)
== "foo: bar\n"
)

def test_yaml_ordered_dump(self):
"""
Test yaml.dump with OrderedDict
"""
data = OrderedDict([("foo", "bar"), ("baz", "qux")])
exp_yaml = "{foo: bar, baz: qux}\n"
assert (
salt.utils.yamldumper.dump(data, Dumper=salt.utils.yamldumper.OrderedDumper)
== exp_yaml
)

def test_yaml_safe_ordered_dump(self):
"""
Test yaml.safe_dump with OrderedDict
"""
data = OrderedDict([("foo", "bar"), ("baz", "qux")])
exp_yaml = "{foo: bar, baz: qux}\n"
assert salt.utils.yamldumper.safe_dump(data) == exp_yaml

def test_yaml_indent_safe_ordered_dump(self):
"""
Test yaml.dump with IndentedSafeOrderedDumper
"""
data = OrderedDict([("foo", ["bar", "baz"]), ("qux", "quux")])
exp_yaml = "foo:\n- bar\n- baz\nqux: quux\n"
assert (
salt.utils.yamldumper.dump(
data,
Dumper=salt.utils.yamldumper.IndentedSafeOrderedDumper,
default_flow_style=False,
)
== exp_yaml
)

def test_yaml_defaultdict_dump(self):
"""
Test yaml.dump with defaultdict
"""
data = defaultdict(list)
data["foo"].append("bar")
exp_yaml = "foo: [bar]\n"
assert salt.utils.yamldumper.safe_dump(data) == exp_yaml

def test_yaml_namespaced_dict_wrapper_dump(self):
"""
Test yaml.dump with NamespacedDictWrapper
"""
data = NamespacedDictWrapper({"test": {"foo": "bar"}}, "test")
exp_yaml = (
"!!python/object/new:salt.utils.context.NamespacedDictWrapper\n"
"dictitems: {foo: bar}\n"
"state:\n"
" _NamespacedDictWrapper__dict:\n"
" test: {foo: bar}\n"
" pre_keys: !!python/tuple [test]\n"
)
assert salt.utils.yamldumper.dump(data) == exp_yaml

def test_yaml_undefined_dump(self):
"""
Test yaml.safe_dump with None
"""
data = {"foo": None}
exp_yaml = "{foo: null}\n"
assert salt.utils.yamldumper.safe_dump(data) == exp_yaml

def test_yaml_hashable_ordered_dict_dump(self):
"""
Test yaml.dump with HashableOrderedDict
"""
data = HashableOrderedDict([("foo", "bar"), ("baz", "qux")])
exp_yaml = "{foo: bar, baz: qux}\n"
assert (
salt.utils.yamldumper.dump(data, Dumper=salt.utils.yamldumper.OrderedDumper)
== exp_yaml
)

0 comments on commit caf62f9

Please sign in to comment.