Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3006.x] fix yaml output #66783

Merged
merged 2 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
)
Loading