Coverage for /Users/davegaeddert/Development/dropseed/plain/plain/plain/json.py: 30%

30 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-10-16 22:04 -0500

1import datetime 

2import decimal 

3import json 

4import uuid 

5 

6from plain.utils.duration import duration_iso_string 

7from plain.utils.functional import Promise 

8from plain.utils.timezone import is_aware 

9 

10 

11class PlainJSONEncoder(json.JSONEncoder): 

12 """ 

13 JSONEncoder subclass that knows how to encode date/time, decimal types, and 

14 UUIDs. 

15 """ 

16 

17 def default(self, o): 

18 # See "Date Time String Format" in the ECMA-262 specification. 

19 if isinstance(o, datetime.datetime): 

20 r = o.isoformat() 

21 if o.microsecond: 

22 r = r[:23] + r[26:] 

23 if r.endswith("+00:00"): 

24 r = r.removesuffix("+00:00") + "Z" 

25 return r 

26 elif isinstance(o, datetime.date): 

27 return o.isoformat() 

28 elif isinstance(o, datetime.time): 

29 if is_aware(o): 

30 raise ValueError("JSON can't represent timezone-aware times.") 

31 r = o.isoformat() 

32 if o.microsecond: 

33 r = r[:12] 

34 return r 

35 elif isinstance(o, datetime.timedelta): 

36 return duration_iso_string(o) 

37 elif isinstance(o, decimal.Decimal | uuid.UUID | Promise): 

38 return str(o) 

39 else: 

40 return super().default(o)