Skip to content

Commit

Permalink
utils: teach our json serializer to handle more types (apache#1907)
Browse files Browse the repository at this point in the history
Namely datetime.time and numpy.bool_

Refs: apache#1900
Refs: apache#1903
  • Loading branch information
xrmx authored and Saleh Hindi committed Jun 9, 2017
1 parent 8893664 commit 6f47292
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 25 deletions.
6 changes: 5 additions & 1 deletion superset/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from __future__ import unicode_literals

from builtins import object
from datetime import date, datetime
from datetime import date, datetime, time
import decimal
import functools
import json
Expand Down Expand Up @@ -216,6 +216,8 @@ def base_json_conv(obj):

if isinstance(obj, numpy.int64):
return int(obj)
elif isinstance(obj, numpy.bool_):
return bool(obj)
elif isinstance(obj, set):
return list(obj)
elif isinstance(obj, decimal.Decimal):
Expand All @@ -239,6 +241,8 @@ def json_iso_dttm_ser(obj):
obj = obj.isoformat()
elif isinstance(obj, date):
obj = obj.isoformat()
elif isinstance(obj, time):
obj = obj.isoformat()
else:
raise TypeError(
"Unserializable object {} of type {}".format(obj, type(obj))
Expand Down
71 changes: 47 additions & 24 deletions tests/utils_tests.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,47 @@
from datetime import datetime, date, timedelta
from superset import utils
import unittest

from mock import Mock, patch

class UtilsTestCase(unittest.TestCase):
def test_json_int_dttm_ser(self):
dttm = datetime(2020, 1, 1)
ts = 1577836800000.0
json_int_dttm_ser = utils.json_int_dttm_ser
assert json_int_dttm_ser(dttm) == ts
assert json_int_dttm_ser(date(2020, 1, 1)) == ts
assert json_int_dttm_ser(datetime(1970, 1, 1)) == 0
assert json_int_dttm_ser(date(1970, 1, 1)) == 0
assert json_int_dttm_ser(dttm + timedelta(milliseconds=1)) == (ts + 1)

with self.assertRaises(TypeError):
utils.json_int_dttm_ser("this is not a date")

@patch('superset.utils.datetime')
def test_parse_human_timedelta(self, mock_now):
mock_now.return_value = datetime(2016, 12, 1)
self.assertEquals(utils.parse_human_timedelta('now'), timedelta(0))
from datetime import datetime, date, timedelta, time
from decimal import Decimal
from superset.utils import (
json_int_dttm_ser, json_iso_dttm_ser, base_json_conv, parse_human_timedelta
)
import unittest
import uuid

from mock import Mock, patch
import numpy


class UtilsTestCase(unittest.TestCase):
def test_json_int_dttm_ser(self):
dttm = datetime(2020, 1, 1)
ts = 1577836800000.0
assert json_int_dttm_ser(dttm) == ts
assert json_int_dttm_ser(date(2020, 1, 1)) == ts
assert json_int_dttm_ser(datetime(1970, 1, 1)) == 0
assert json_int_dttm_ser(date(1970, 1, 1)) == 0
assert json_int_dttm_ser(dttm + timedelta(milliseconds=1)) == (ts + 1)

with self.assertRaises(TypeError):
json_int_dttm_ser("this is not a date")

def test_json_iso_dttm_ser(self):
dttm = datetime(2020, 1, 1)
dt = date(2020, 1, 1)
t = time()
assert json_iso_dttm_ser(dttm) == dttm.isoformat()
assert json_iso_dttm_ser(dt) == dt.isoformat()
assert json_iso_dttm_ser(t) == t.isoformat()

with self.assertRaises(TypeError):
json_iso_dttm_ser("this is not a date")

def test_base_json_conv(self):
assert isinstance(base_json_conv(numpy.bool_(1)), bool) == True
assert isinstance(base_json_conv(numpy.int64(1)), int) == True
assert isinstance(base_json_conv(set([1])), list) == True
assert isinstance(base_json_conv(Decimal('1.0')), float) == True
assert isinstance(base_json_conv(uuid.uuid4()), str) == True

@patch('superset.utils.datetime')
def test_parse_human_timedelta(self, mock_now):
mock_now.return_value = datetime(2016, 12, 1)
self.assertEquals(parse_human_timedelta('now'), timedelta(0))

0 comments on commit 6f47292

Please sign in to comment.