Remove object_hook usage from (almost) all json loading

To explain this change, it's necessary to first understand the history
of `object_hook` usage in Salt.

Initially, the function used as the object hook wherever we used it was
(incorrectly) named `encode_dict`, despite the fact that the code was
*decoding* the contents of the dictionary to unicode. This function was
renamed to `decode_dict`, and a counterpart which *actually* encodes was
put in its place. At this time *most* of the `object_hook` usage was
changed so that `decode_dict` was used, but some references were left
using `encode_dict` (likely because I wasn't sure whether or not
changing them would break things).

However, if the desire is to have unicode values after loading JSON,
there is actually no need to use an object hook, since loading JSON in
Python always produces unicode results even with a POSIX locale!

[root@2719cd6224d3 /]# locale
LANG=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
[root@2719cd6224d3 /]# python
Python 2.7.5 (default, Nov  6 2016, 00:28:07)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> json.loads('{"foo": "bar"}')
{u'foo': u'bar'}
>>> json.loads('{"foo": "Д"}')
{u'foo': u'\u0414'}
>>>

Therefore, this commit removes all `object_hook` usage where
`decode_dict` was the hook being used, since it is redundant. It also
removes one use of `encode_dict` as an object hook that was still left
in code used by salt-thin.

The only `object_hook` left is in some of our ioflo code. I left the
`encode_dict` there, but _only for Python 2_, because if I remember
correctly ioflo needs str types, and encoding a string in Python 2
produces a str type.
This commit is contained in:
Erik Johnson 2018-02-16 14:32:43 -06:00
parent f09db38f63
commit 03b0591f06
No known key found for this signature in database
GPG Key ID: 5E5583C437808F3F
8 changed files with 16 additions and 13 deletions

View File

@ -125,7 +125,7 @@ class FunctionWrapper(object):
'stderr': stderr,
'retcode': retcode}
try:
ret = salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
ret = salt.utils.json.loads(stdout)
if len(ret) < 2 and 'local' in ret:
ret = ret['local']
ret = ret.get('return', {})

View File

@ -197,7 +197,7 @@ def sls(mods, saltenv='base', test=None, exclude=None, **kwargs):
# Read in the JSON data and return the data structure
try:
return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
return salt.utils.json.loads(stdout)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(six.text_type(e))
@ -341,7 +341,7 @@ def low(data, **kwargs):
# Read in the JSON data and return the data structure
try:
return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
return salt.utils.json.loads(stdout)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(six.text_type(e))
@ -432,7 +432,7 @@ def high(data, **kwargs):
# Read in the JSON data and return the data structure
try:
return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
return salt.utils.json.loads(stdout)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(six.text_type(e))
@ -677,7 +677,7 @@ def highstate(test=None, **kwargs):
# Read in the JSON data and return the data structure
try:
return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
return salt.utils.json.loads(stdout)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(six.text_type(e))
@ -760,7 +760,7 @@ def top(topfn, test=None, **kwargs):
# Read in the JSON data and return the data structure
try:
return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
return salt.utils.json.loads(stdout)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(six.text_type(e))
@ -1133,7 +1133,7 @@ def single(fun, name, test=None, **kwargs):
# Read in the JSON data and return the data structure
try:
return salt.utils.json.loads(stdout, object_hook=salt.utils.data.decode_dict)
return salt.utils.json.loads(stdout)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(six.text_type(e))

View File

@ -823,7 +823,7 @@ def query(params=None):
content = request.text
result = salt.utils.json.loads(content, object_hook=salt.utils.data.encode_dict)
result = salt.utils.json.loads(content)
if 'Code' in result:
raise SaltCloudSystemExit(
pprint.pformat(result.get('Message', {}))

View File

@ -188,7 +188,7 @@ def query(params=None):
log.debug(request.url)
content = request.text
result = salt.utils.json.loads(content, object_hook=salt.utils.data.encode_dict)
result = salt.utils.json.loads(content)
# print('response:')
# pprint.pprint(result)

View File

@ -62,7 +62,10 @@ def jobber_check(self):
rms.append(jid)
data = self.shells.value[jid]
stdout, stderr = data['proc'].communicate()
ret = salt.utils.json.loads(stdout, object_hook=salt.utils.data.encode_dict)['local']
ret = salt.utils.json.loads(
stdout,
object_hook=salt.utils.data.encode_dict if six.PY2 else None
)['local']
route = {'src': (self.stack.value.local.name, 'manor', 'jid_ret'),
'dst': (data['msg']['route']['src'][0], None, 'remote_cmd')}
ret['cmd'] = '_return'

View File

@ -42,7 +42,7 @@ def create(name, profile):
cmd = 'salt-cloud --out json -p {0} {1}'.format(profile, name)
out = __salt__['cmd.run_stdout'](cmd, python_shell=False)
try:
ret = salt.utils.json.loads(out, object_hook=salt.utils.data.encode_dict)
ret = salt.utils.json.loads(out)
except ValueError:
ret = {}
return ret

View File

@ -2017,7 +2017,7 @@ def pkg(pkg_path,
roster_grains_json = os.path.join(root, 'roster_grains.json')
if os.path.isfile(roster_grains_json):
with salt.utils.files.fopen(roster_grains_json, 'r') as fp_:
roster_grains = salt.utils.json.load(fp_, object_hook=salt.utils.data.encode_dict)
roster_grains = salt.utils.json.load(fp_)
if os.path.isfile(roster_grains_json):
popts['grains'] = roster_grains

View File

@ -28,7 +28,7 @@ def find_json(raw):
for ind, _ in enumerate(raw):
working = '\n'.join(raw.splitlines()[ind:])
try:
ret = json.loads(working, object_hook=salt.utils.data.decode_dict) # future lint: blacklisted-function
ret = json.loads(working) # future lint: blacklisted-function
except ValueError:
continue
if ret: