Created
May 25, 2016 19:01
-
-
Save djoeman84/5729422677fa87ddd4f6a900d5b36aad to your computer and use it in GitHub Desktop.
Map Python object to ECMA-JSON compliant objects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math | |
class JSONECMACompliance(object): | |
@classmethod | |
def make_standards_compliant(cls, json_serializable_obj, inf_value='Infinity', | |
negative_inf_value='-Infinity', nan_value='NaN'): | |
""" | |
Python decided it wouldn't conform to ECMA JSON standard. | |
This converts illegal values (Infinity, -Infinity, NaN) to strings with the same values. | |
JSON spec: http://www.json.org/ | |
:param json_serializable_obj: object which will be json serialized | |
:param inf_value: value to replace infinite values with. Must be an ECMA compliant value | |
:param negative_inf_value: value to replace negative infinite values with. | |
Must be an ECMA compliant value | |
:param nan_value: value to replace NaN values with. Must be an ECMA compliant value | |
:return: json serializable object which will serialize in a standards compliant manner | |
""" | |
mapper = cls._get_json_value_mapper(inf_value, negative_inf_value, nan_value) | |
return cls._deep_map_values(json_serializable_obj, mapper) | |
@classmethod | |
def _deep_map_values(cls, obj, callback): | |
if isinstance(obj, dict): | |
return {v_name: cls._deep_map_values(v, callback) for v_name, v in obj.iteritems()} | |
elif isinstance(obj, list): | |
return [cls._deep_map_values(v, callback) for i, v in enumerate(obj)] | |
else: | |
return callback(obj) | |
@classmethod | |
def _get_json_value_mapper(cls, inf_value, negative_inf_value, nan_value): | |
def _map_json_serializable_values(v): | |
if isinstance(v, float): | |
if math.isinf(v): | |
return inf_value if v > 0 else negative_inf_value | |
elif math.isnan(v): | |
return nan_value | |
else: | |
return v | |
else: | |
return v | |
return _map_json_serializable_values |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment