Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated JSON serialization of Date and CalendarDate to support None #582

Merged
merged 7 commits into from
Dec 15, 2021
38 changes: 32 additions & 6 deletions param/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1017,10 +1017,15 @@ def _validate(self, val):

@classmethod
def serialize(cls, value):
return list(value) # As JSON has no tuple representation
if value is None:
return 'null'
else:
return list(value) # As JSON has no tuple representation

@classmethod
def deserialize(cls, value):
if value == 'null':
return None
return tuple(value) # As JSON has no tuple representation


Expand Down Expand Up @@ -1474,10 +1479,15 @@ def __init__(self, default=None, **params):

@classmethod
def serialize(cls, value):
return value.tolist()
if value is None:
return 'null'
else:
return value.tolist()

@classmethod
def deserialize(cls, value):
if value == 'null':
return None
from numpy import asarray
return asarray(value)

Expand Down Expand Up @@ -1557,10 +1567,15 @@ def _validate(self, val):

@classmethod
def serialize(cls, value):
return value.to_dict('records')
if value is None:
return 'null'
else:
return value.to_dict('records')

@classmethod
def deserialize(cls, value):
if value == 'null':
return None
from pandas import DataFrame as pdDFrame
return pdDFrame(value)

Expand Down Expand Up @@ -1925,13 +1940,18 @@ def _validate_step(self, val, step):

@classmethod
def serialize(cls, value):
if value is None:
return 'null'
if not isinstance(value, (dt.datetime, dt.date)): # i.e np.datetime64
value = value.astype(dt.datetime)
return value.strftime("%Y-%m-%dT%H:%M:%S.%f")

@classmethod
def deserialize(cls, value):
return dt.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")
if value == 'null':
return None
else:
return dt.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")


class CalendarDate(Number):
Expand Down Expand Up @@ -1959,11 +1979,17 @@ def _validate_step(self, val, step):

@classmethod
def serialize(cls, value):
return value.strftime("%Y-%m-%d")
if value is None:
return 'null'
else:
return value.strftime("%Y-%m-%d")

@classmethod
def deserialize(cls, value):
return dt.datetime.strptime(value, "%Y-%m-%d").date()
if value == 'null':
return None
else:
return dt.datetime.strptime(value, "%Y-%m-%d").date()


class Color(Parameter):
Expand Down
14 changes: 11 additions & 3 deletions tests/API1/testjsonserialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ class TestSet(param.Parameterized):

__test__ = False

numpy_params = ['r']
pandas_params = ['s','t','u']
numpy_params = ['r','y']
pandas_params = ['s','t','u','z']
conditionally_unsafe = ['f', 'o']

a = param.Integer(default=5, doc='Example doc', bounds=(2,30), inclusive_bounds=(True, False))
Expand All @@ -68,6 +68,11 @@ class TestSet(param.Parameterized):
{'A':[1,2,3], 'B':[1.1,2.2,3.3]}), columns=(1,4), rows=(2,5))
u = None if pd is None else param.DataFrame(default=df2, columns=['A', 'B'])
v = param.Dict({'1':2})
w = param.Date(default=None, allow_None=True)
x = param.CalendarDate(default=None, allow_None=True)
y = None if np is None else param.Array(default=None)
z = None if pd is None else param.DataFrame(default=None, allow_None=True)
aa = param.Tuple(default=None, allow_None=True, length=1)


test = TestSet(a=29)
Expand Down Expand Up @@ -184,7 +189,10 @@ def test_pandas_instance_serialization(self):
serialized = test.param.serialize_parameters(subset=test.pandas_params, mode=self.mode)
deserialized = TestSet.param.deserialize_parameters(serialized, mode=self.mode)
for pname in test.pandas_params:
self.assertTrue(getattr(test, pname).equals(deserialized[pname]))
if getattr(test, pname) is None:
self.assertTrue(deserialized[pname] is None)
else:
self.assertTrue(getattr(test, pname).equals(deserialized[pname]))



Expand Down