mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 17:33:54 +00:00
Handle lower msgpack versions which can't handle OrderedDict
's. Fixes #5017.
Dictionary subclasses were only added to msgpack after 0.2.0(inclusive). Since `isinstance(OrderedDict(), dict)` returns true, of course, msgpack's custom type handling cannot be used. The solution is to iterate through the data and convert `OrderedDict`'s to `dict`'s since that's what msgpack also does. For now, the iteration is a top level one, ie, only first child descendants are evaluated. We won't go deeper unless we get the same failure a little deeper in the nested data.
This commit is contained in:
parent
16042592ee
commit
f68b3ace7d
@ -12,6 +12,7 @@ import salt.log
|
||||
import salt.crypt
|
||||
from salt.exceptions import SaltReqTimeoutError
|
||||
from salt._compat import pickle
|
||||
from salt.utils.odict import OrderedDict
|
||||
|
||||
# Import third party libs
|
||||
import zmq
|
||||
@ -106,7 +107,33 @@ class Serial(object):
|
||||
if self.serial == 'pickle':
|
||||
return pickle.dumps(msg)
|
||||
else:
|
||||
return msgpack.dumps(msg)
|
||||
try:
|
||||
return msgpack.dumps(msg)
|
||||
except TypeError:
|
||||
if msgpack.version >= (0, 2, 0):
|
||||
# Should support OrderedDict serialization, so, let's
|
||||
# raise the exception
|
||||
raise
|
||||
|
||||
# msgpack is < 0.2.0, let's make it's life easier
|
||||
# Since OrderedDict is identified as a dictionary, we can't
|
||||
# make use of msgpack custom types, we will need to convert by
|
||||
# hand.
|
||||
# This means iterating through all elements of a dictionary or
|
||||
# list/tuple
|
||||
def odict_encoder(obj):
|
||||
if isinstance(obj, OrderedDict):
|
||||
return dict(obj)
|
||||
return obj
|
||||
|
||||
if isinstance(msg, dict):
|
||||
for k, v in msg.copy().iteritems():
|
||||
msg[k] = odict_encoder(v)
|
||||
elif isinstance(msg, (list, tuple)):
|
||||
msg = list(msg)
|
||||
for idx, entry in enumerate(msg):
|
||||
msg[idx] = odict_encoder(entry)
|
||||
return msgpack.dumps(msg)
|
||||
|
||||
def dump(self, msg, fn_):
|
||||
'''
|
||||
|
Loading…
Reference in New Issue
Block a user