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

Serializing Date parameters does not support allow_None #578

Closed
MarcSkovMadsen opened this issue Dec 7, 2021 · 5 comments · Fixed by #655
Closed

Serializing Date parameters does not support allow_None #578

MarcSkovMadsen opened this issue Dec 7, 2021 · 5 comments · Fixed by #655
Assignees
Labels
type-bug Bug report

Comments

@MarcSkovMadsen
Copy link
Collaborator

MarcSkovMadsen commented Dec 7, 2021

Param: 1.12.0

I'm trying to help a user that wants to implement the Pydantic getting started example using Param. https://discourse.holoviz.org/t/creating-an-optional-datetime-parameter-using-param/3147.

He asks how to implement signup_ts: Optional[datetime] = None. I think its not possible with the existing parameters as I get the below error.

$ python 'script.py'
Traceback (most recent call last):
  File "script.py", line 12, in <module>
    deserialized_data = User.param.deserialize_parameters(json_data)
  File "C:\repos\private\panel-ai\.venv\lib\site-packages\param\parameterized.py", line 2100, in deserialize_parameters
    return serializer.deserialize_parameters(self_or_cls, serialization, subset=subset)
  File "C:\repos\private\panel-ai\.venv\lib\site-packages\param\serializer.py", line 113, in deserialize_parameters
    deserialized = pobj.param[name].deserialize(value)
  File "C:\repos\private\panel-ai\.venv\lib\site-packages\param\__init__.py", line 1928, in deserialize
    return dt.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")
TypeError: strptime() argument 1 must be str, not None
import param
import json

class User(param.Parameterized):
    signup_ts = param.Date(allow_None=True, doc="""The sign up time of the user""")


external_data = {
    'signup_ts': None,
}
json_data = json.dumps(external_data)
deserialized_data = User.param.deserialize_parameters(json_data)
User(**deserialized_data)

Additional Context

If you look at the Pydantic getting started example you will realize that its deserializing is much more flexible/ forgiving as it will be able to converts string to ints for integer parameters, not care so much about the date time format for datetime parameters etc.

@MarcSkovMadsen MarcSkovMadsen added type-bug Bug report TRIAGE User-submitted issue that hasn't been triaged yet. labels Dec 7, 2021
@jbednar jbednar changed the title Date does not work with allow_None Serializing Date parameters does not support allow_None Dec 14, 2021
@jbednar
Copy link
Member

jbednar commented Dec 14, 2021

I've changed the title, because Date parameters do support allow_None:

>>> import param, json
>>> class User(param.Parameterized):
        signup_ts = param.Date(allow_None=True, doc="""The sign up time of the user""")
>>> u = User()
>>> print(u.signup_ts)
None

Your example above is specifically about serializing Date Parameters whose value is None, and it does look like there is an issue there. @jlstevens?

If you look at the Pydantic getting started example you will realize that its deserializing is much more flexible/ forgiving as it will be able to converts string to ints for integer parameters, not care so much about the date time format for datetime parameters etc.

Right. As pydantic/pydantic#578 says, Pydantic is a parsing library, not a validation library like Param. Pydantic is designed to ensure that usable values are extracted from what is provided by the user, while Param tries to give feedback to the user that what they provided is not suitable. E.g. sure, the user might have meant 3 when they put in the string " 3" or the float 3.14 for an integer, but are we sure? Should it also be 3 for "3..."? or "3 feet" or "three"? At some point you have to give up and stop making assumptions. Param gives up quickly, rejecting anything that's not clearly the right object, while Pydantic will bend over backwards to make it fit. At a downstream level, code with either approach can rest assured that only the indicated type will be provided, but Param takes the position that users need feedback when they do crazy things, not for the program to blindly go forward with potentially undetected issues.

Param offers a separate mechanism set_in_bounds() that is more forgiving, and we could expand that to be even more forgiving if that's useful, as long as we still catch errors when that's not used.

@jlstevens
Copy link
Contributor

I've not yet investigated deeply but the scheme should be fine as it is implemented like this which means the fix should be trivial None skip when serializing and deserializing dates. I'll make a PR shortly.

@jbednar
Copy link
Member

jbednar commented Dec 15, 2021

BTW, I think the serialization support is a red herring for the specific task of comparison with Pydantic. I've added an equivalent to the Pydantic getting started example to https://discourse.holoviz.org/t/creating-an-optional-datetime-parameter-using-param/3147/10, which does not depend on serialization and does support None.

@MridulS MridulS removed the TRIAGE User-submitted issue that hasn't been triaged yet. label Feb 7, 2022
@hoxbro
Copy link
Member

hoxbro commented Oct 24, 2022

@jlstevens can this issue be closed?

@jlstevens
Copy link
Contributor

Based on the merged PR, I think so...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug Bug report
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants