ramonhagenaars / jsons

🐍 A Python lib for (de)serializing Python objects to/from JSON
https://jsons.readthedocs.io
MIT License
288 stars 40 forks source link

DeserializationError with datetime or type hint #29

Closed ThierryPfeiffer closed 5 years ago

ThierryPfeiffer commented 5 years ago

I'm a beginner with Python. So I'm not sure if I use jsons wrong.

The first exemple below works well.

import jsons
from dataclasses import dataclass

@dataclass
class ChatUser:
    uid: str
    name: str

dumped = jsons.dumps(ChatUser('012451', 'Casimir'), strip_privates=True, strip_microseconds=True, verbose=True)
print(dumped)
instance = jsons.loads(dumped, ChatUser)
print(instance)

Both following examples fail with DeserializationError. Can someone help?

import jsons
from dataclasses import dataclass
import datetime

@dataclass
class ChatUser:
    uid: datetime
    name: str

dumped = jsons.dumps(ChatUser(datetime.datetime.now(), 'Casimir'), strip_privates=True, strip_microseconds=True, verbose=True)
print(dumped)
instance = jsons.loads(dumped, ChatUser)
print(instance)`
import jsons
from dataclasses import dataclass
from typing import List, NewType
Uid = NewType("Uid", str)

@dataclass
class ChatUser:
    uid: Uid
    name: str

dumped = jsons.dumps(ChatUser(Uid('012451'), 'Casimir'), strip_privates=True, strip_microseconds=True, verbose=True)
print(dumped)
instance = jsons.loads(dumped, ChatUser)
print(instance)
ramonhagenaars commented 5 years ago

Hi Titounnosaure.

In your second example, you've used a module instead of a class as a type hint.

import datetime

@dataclass
class ChatUser:
    uid: datetime  # <-- this should be datetime.datetime OR import datetime from datetime
    name: str

The error is somewhat cryptic I confess. I'll see if that can be improved.

Your third example uses a NewType for a type hint. That is not supported by jsons (yet). For the time being, you could instead do:

from dataclasses import dataclass

import jsons

class Uid(str):
    pass

@dataclass
class ChatUser:
    uid: Uid
    name: str

dumped = jsons.dumps(ChatUser(Uid('012451'), 'Casimir'), strip_privates=True, strip_microseconds=True, verbose=True)
print(dumped)
instance = jsons.loads(dumped, ChatUser)
print(instance)

Edit: I've opened Issue#30 and Issue#31 for this.

ThierryPfeiffer commented 5 years ago

Thank you very much Ramon for this clear and quick answer. Everything works well now. :thumbsup: I didn't noticed the "subtlety" with datetime. :flushed: