Here's a simple JSON encoder that convert float values to string:
class NestedEncoder(json.JSONEncoder):
'''
A JSON Encoder that converts floats/decimals to strings and allows nested objects
'''
def default(self, obj):
if isinstance(obj, float) or obj.__class__.__name__ == "float32":
return self.floattostr(obj)
elif obj.__class__.__name__ == "type":
return str(obj)
elif hasattr(obj, 'repr_json'):
return obj.repr_json()
else:
return json.JSONEncoder.default(self, obj)
def floattostr(self,o,_inf=float('Inf'), _neginf=-float('-Inf'),nan_str="None"):
if o != o:
text = nan_str
elif o == _inf:
text = 'Infinity'
elif o == _neginf:
text = '-Infinity'
else:
return o.__repr__()
return text
Now here's two tests. The first creates a Infinity valued float and encodes it using the custom encoder. Test passes.
def test_inf():
inf = float('Inf')
as_json = json.dumps(inf,cls=NestedEncoder)
assert as_json == "Infinity"
The second test does the same but puts the float in a dictionary:
def test_inf_dic():
inf = float('Inf')
as_json = json.dumps({'key':inf},cls=NestedEncoder)
assert as_json == "{'key':'Infinity'}"
OUTPUT:
=================================== FAILURES ===================================
_________________________________ test_inf_dic _________________________________
def test_inf_dic():
inf = float('Inf')
as_json = json.dumps({'key':inf},cls=NestedEncoder)
> assert as_json == "{'key':'Infinity'}"
E assert '{"key": Infinity}' == "{'key':'Infinity'}"
E - {"key": Infinity}
E ? ^ ^ ^
E + {'key':'Infinity'}
E ? ^ ^ ^ +
EDIT:
The custom encoder only gets called for the first test, not the second.
float('Inf').__class__.__name__, so it won't match your first conditional. You are also trying to compare a string to a dict in your test.float('Inf').__class__.__name__issue you pointed to isn't relevant since it's an OR conditional