3
0
Fork 0

fix: add handling for decimal values and lists, in make_json_safe()

This commit is contained in:
Lance Edgar 2024-12-14 23:56:36 -06:00
parent dd1fd8c0ce
commit 30671fcd78
2 changed files with 41 additions and 4 deletions

View file

@ -24,6 +24,7 @@
Web Utilities Web Utilities
""" """
import decimal
import importlib import importlib
import json import json
import logging import logging
@ -525,17 +526,28 @@ def make_json_safe(value, key=None, warn=True):
if value is colander.null: if value is colander.null:
return None return None
# recursively convert dict elif isinstance(value, dict):
if isinstance(value, dict): # recursively convert dict
parent = dict(value) parent = dict(value)
for key, value in parent.items(): for key, value in parent.items():
parent[key] = make_json_safe(value, key=key, warn=warn) parent[key] = make_json_safe(value, key=key, warn=warn)
value = parent value = parent
# convert UUID to str elif isinstance(value, list):
if isinstance(value, _uuid.UUID): # recursively convert list
parent = list(value)
for i, value in enumerate(parent):
parent[i] = make_json_safe(value, key=key, warn=warn)
value = parent
elif isinstance(value, _uuid.UUID):
# convert UUID to str
value = value.hex value = value.hex
elif isinstance(value, decimal.Decimal):
# convert decimal to float
value = float(value)
# ensure JSON-compatibility, warn if problems # ensure JSON-compatibility, warn if problems
try: try:
json.dumps(value) json.dumps(value)

View file

@ -1,5 +1,6 @@
# -*- coding: utf-8; -*- # -*- coding: utf-8; -*-
import decimal
import json import json
import uuid as _uuid import uuid as _uuid
from unittest import TestCase from unittest import TestCase
@ -570,6 +571,12 @@ class TestMakeJsonSafe(TestCase):
value = mod.make_json_safe(uuid) value = mod.make_json_safe(uuid)
self.assertEqual(value, uuid.hex) self.assertEqual(value, uuid.hex)
def test_decimal(self):
value = decimal.Decimal('42.42')
self.assertNotEqual(value, 42.42)
result = mod.make_json_safe(value)
self.assertEqual(result, 42.42)
def test_dict(self): def test_dict(self):
model = self.app.model model = self.app.model
person = model.Person(full_name="Betty Boop") person = model.Person(full_name="Betty Boop")
@ -585,3 +592,21 @@ class TestMakeJsonSafe(TestCase):
'foo': 'bar', 'foo': 'bar',
'person': "Betty Boop", 'person': "Betty Boop",
}) })
def test_list(self):
model = self.app.model
person = model.Person(full_name="Betty Boop")
data = [
'foo',
'bar',
person,
]
self.assertRaises(TypeError, json.dumps, data)
value = mod.make_json_safe(data)
self.assertEqual(value, [
'foo',
'bar',
"Betty Boop",
])