salt/salt/utils/yamlencoding.py
Erik Johnson 002aa88a97
Replace yaml usage with a helper to ensure unicode is handled properly
Without allow_unicode=True, unicode characters are processed through the
str representer and on Python 2 are dumped as a Unicode code point (i.e.
a literal \u0414). This commit makes allow_unicode=True the default in
our salt.utils.yamlloader.safe_dump() helper. It also adds a new
salt.utils.yamlloader.dump() helper which wraps yaml.dump() and also
makes allow_unicode=True the default.

To make importing and using our custom yaml loader/dumper easier, a
convenience module called salt.utils.yaml has been added, which does a
wildcard import from both salt.utils.yamldumper and
salt.utils.yamlloader.

Refs to yaml.load/dump and yaml.safe_load/safe_dump have been updated to
salt.utils.yaml, to ensure that unicode is handled properly.
2018-01-03 14:14:21 -06:00

64 lines
1.7 KiB
Python

# -*- coding: utf-8 -*-
'''
Functions for adding yaml encoding to the jinja context
'''
# Import Python libs
from __future__ import absolute_import
import io
# Import 3rd-party libs
import yaml # pylint: disable=blacklisted-import
from salt.ext import six
# Import salt libs
from salt.utils.decorators.jinja import jinja_filter
@jinja_filter()
def yaml_dquote(text):
'''
Make text into a double-quoted YAML string with correct escaping
for special characters. Includes the opening and closing double
quote characters.
'''
with io.StringIO() as ostream:
yemitter = yaml.emitter.Emitter(ostream, width=six.MAXSIZE)
yemitter.write_double_quoted(six.text_type(text))
return ostream.getvalue()
@jinja_filter()
def yaml_squote(text):
'''
Make text into a single-quoted YAML string with correct escaping
for special characters. Includes the opening and closing single
quote characters.
'''
with io.StringIO() as ostream:
yemitter = yaml.emitter.Emitter(ostream, width=six.MAXSIZE)
yemitter.write_single_quoted(six.text_type(text))
return ostream.getvalue()
@jinja_filter()
def yaml_encode(data):
'''
A simple YAML encode that can take a single-element datatype and return
a string representation.
'''
yrepr = yaml.representer.SafeRepresenter()
ynode = yrepr.represent_data(data)
if not isinstance(ynode, yaml.ScalarNode):
raise TypeError(
"yaml_encode() only works with YAML scalar data;"
" failed for {0}".format(type(data))
)
tag = ynode.tag.rsplit(':', 1)[-1]
ret = ynode.value
if tag == "str":
ret = yaml_dquote(ynode.value)
return ret