Coverage for pyguymer3/serializer.py: 2%

51 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-08 18:47 +0000

1#!/usr/bin/env python3 

2 

3# Define function ... 

4def serializer( 

5 obj, 

6 /, 

7 *, 

8 evaluate = False, 

9): 

10 """Serialize an object into an intrinsic type 

11 

12 Serializer for objects not serializable by Python's default :mod:`json` 

13 code. Converts all non-intrinsic types to intrinsic types. 

14 

15 Parameters 

16 ---------- 

17 obj : anything 

18 object to be serialized 

19 evaluate : bool, optional 

20 evaluate exifread.utils.Ratio objects into floats, otherwise return as string of form "X/Y" (default false) 

21 

22 Notes 

23 ----- 

24 Copyright 2017 Thomas Guymer [1]_ 

25 

26 References 

27 ---------- 

28 .. [1] PyGuymer3, https://github.com/Guymer/PyGuymer3 

29 """ 

30 

31 # Import standard modules ... 

32 import datetime 

33 

34 # Import special modules ... 

35 try: 

36 import exifread 

37 except: 

38 raise Exception("\"exifread\" is not installed; run \"pip install --user ExifRead\"") from None 

39 try: 

40 import numpy 

41 except: 

42 raise Exception("\"numpy\" is not installed; run \"pip install --user numpy\"") from None 

43 

44 # ************************************************************************** 

45 

46 # Check type ... 

47 if isinstance(obj, datetime.date): 

48 # Return serializable answer ... 

49 return obj.isoformat(sep = "T", timespec = "microseconds") 

50 

51 # Check type ... 

52 if isinstance(obj, datetime.time): 

53 # Return serializable answer ... 

54 return obj.isoformat(sep = "T", timespec = "microseconds") 

55 

56 # Check type ... 

57 if isinstance(obj, datetime.datetime): 

58 # Return serializable answer ... 

59 return obj.isoformat(sep = "T", timespec = "microseconds") 

60 

61 # Check type ... 

62 if isinstance(obj, datetime.timedelta): 

63 # Return serializable answer ... 

64 return obj.total_seconds() 

65 

66 # ************************************************************************** 

67 

68 # Check type ... 

69 if isinstance(obj, exifread.utils.Ratio): 

70 # Check if it is an integer mascarading as a fraction ... 

71 if obj.den == 1: 

72 return obj.num 

73 

74 # Check if the user wants to evaluate fractions ... 

75 if evaluate: 

76 # Catch floating-point exceptions ... 

77 if obj.den == 0: 

78 # Check sign ... 

79 if obj.num < 0: 

80 # Return serializable answer ... 

81 return float("-inf") 

82 

83 # Return serializable answer ... 

84 return float("inf") 

85 

86 # Return serializable answer ... 

87 return float(obj.num) / float(obj.den) 

88 

89 # Return serializable answer ... 

90 return f"{obj.num:d}/{obj.den:d}" 

91 

92 # ************************************************************************** 

93 

94 # Check type ... 

95 if isinstance(obj, numpy.int8): 

96 # Return serializable answer ... 

97 return int(obj) 

98 

99 # Check type ... 

100 if isinstance(obj, numpy.int16): 

101 # Return serializable answer ... 

102 return int(obj) 

103 

104 # Check type ... 

105 if isinstance(obj, numpy.int32): 

106 # Return serializable answer ... 

107 return int(obj) 

108 

109 # Check type ... 

110 if isinstance(obj, numpy.int64): 

111 # Return serializable answer ... 

112 return int(obj) 

113 

114 # Check type ... 

115 if isinstance(obj, numpy.uint8): 

116 # Return serializable answer ... 

117 return int(obj) 

118 

119 # Check type ... 

120 if isinstance(obj, numpy.uint16): 

121 # Return serializable answer ... 

122 return int(obj) 

123 

124 # Check type ... 

125 if isinstance(obj, numpy.uint32): 

126 # Return serializable answer ... 

127 return int(obj) 

128 

129 # Check type ... 

130 if isinstance(obj, numpy.uint64): 

131 # Return serializable answer ... 

132 return int(obj) 

133 

134 # Check type ... 

135 if isinstance(obj, numpy.float16): 

136 # Return serializable answer ... 

137 return float(obj) 

138 

139 # Check type ... 

140 if isinstance(obj, numpy.float32): 

141 # Return serializable answer ... 

142 return float(obj) 

143 

144 # Check type ... 

145 if isinstance(obj, numpy.float64): 

146 # Return serializable answer ... 

147 return float(obj) 

148 

149 # ************************************************************************** 

150 

151 # Catch errors ... 

152 raise TypeError("\"obj\" is an unexpected type", type(obj)) from None