Skip to content

Instantly share code, notes, and snippets.

@djoeman84
Created May 25, 2016 19:01
Show Gist options
  • Save djoeman84/5729422677fa87ddd4f6a900d5b36aad to your computer and use it in GitHub Desktop.
Save djoeman84/5729422677fa87ddd4f6a900d5b36aad to your computer and use it in GitHub Desktop.
Map Python object to ECMA-JSON compliant objects
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