lidatong / dataclasses-json

Easily serialize Data Classes to and from JSON
MIT License
1.34k stars 150 forks source link

[BUG] Decoding incompatible with Freezegun #509

Open s3bw opened 5 months ago

s3bw commented 5 months ago

Description

When datetime is used within the context of freeze_time the check on the field_value is type(field_type) will compare FakeDatetime is datetime and resolve to False. Where-as outside of the freeze_time context datetime is handled correctly.

Code snippet that reproduces the issue

from dataclasses import dataclass, field
from datetime import datetime

from dataclasses_json import config, dataclass_json
from freezegun import freeze_time
import dateutil.parser

def iso8601_datetime(s: str):
    return dateutil.parser.parse(s).replace(tzinfo=None)

DATETIME_CONFIG = config(decoder=iso8601_datetime)

@dataclass_json
@dataclass
class Message:

    dt: datetime = field(metadata=DATETIME_CONFIG)

message = Message.from_dict({"dt": datetime(2023, 1, 24, 11, 36, 21)})
print(message)

with freeze_time("2023-01-09 21:57:32"):

    dt = datetime(2023, 1, 24, 11, 36, 21)
    message = Message.from_dict({"dt": dt})  # Results in `Parser must be a string or character stream, not FakeDatetime`
    print(message)

Describe the results you expected

Ideally FakeDatetime should be treated the same as a datetime and not fallback to passing the FakeDatetime to the decoder as this behaviour doesn't occur with the regular datetime.

Python version you are using

Python 3.9.9

Environment description

freezegun==1.4.0 python-dateutil==2.8.2