Coverage for an_website/fake_orjson.py: 0.000%

55 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2024-11-16 19:56 +0000

1# This program is free software: you can redistribute it and/or modify 

2# it under the terms of the GNU Affero General Public License as 

3# published by the Free Software Foundation, either version 3 of the 

4# License, or (at your option) any later version. 

5# 

6# This program is distributed in the hope that it will be useful, 

7# but WITHOUT ANY WARRANTY; without even the implied warranty of 

8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

9# GNU Affero General Public License for more details. 

10# 

11# You should have received a copy of the GNU Affero General Public License 

12# along with this program. If not, see <https://www.gnu.org/licenses/>. 

13# pylint: disable=preferred-module 

14 

15"""Nobody inspects the spammish repetition.""" 

16 

17from __future__ import annotations 

18 

19from collections.abc import Callable 

20from dataclasses import fields, is_dataclass 

21from datetime import date, datetime, time, timezone 

22from enum import Enum 

23from functools import partial 

24from json import JSONDecodeError, dumps as _dumps, loads as _loads 

25from typing import Any 

26from uuid import UUID 

27 

28__version__ = "3.8.14" # TODO: orjson.Fragment 

29 

30__all__ = ( 

31 "dumps", 

32 "loads", 

33 "JSONDecodeError", 

34 "JSONEncodeError", 

35 "OPT_APPEND_NEWLINE", 

36 "OPT_INDENT_2", 

37 "OPT_NAIVE_UTC", 

38 "OPT_NON_STR_KEYS", 

39 "OPT_OMIT_MICROSECONDS", 

40 "OPT_PASSTHROUGH_DATACLASS", 

41 "OPT_PASSTHROUGH_DATETIME", 

42 "OPT_PASSTHROUGH_SUBCLASS", 

43 "OPT_SERIALIZE_DATACLASS", 

44 "OPT_SERIALIZE_NUMPY", 

45 "OPT_SERIALIZE_UUID", 

46 "OPT_SORT_KEYS", 

47 "OPT_STRICT_INTEGER", 

48 "OPT_UTC_Z", 

49) 

50 

51OPT_APPEND_NEWLINE = 1 << 10 

52OPT_INDENT_2 = 1 << 0 

53OPT_NAIVE_UTC = 1 << 1 

54OPT_NON_STR_KEYS = 1 << 2 # TODO: require for non-string keys 

55OPT_OMIT_MICROSECONDS = 1 << 3 

56OPT_PASSTHROUGH_DATACLASS = 1 << 11 

57OPT_PASSTHROUGH_DATETIME = 1 << 9 

58OPT_PASSTHROUGH_SUBCLASS = 1 << 8 # TODO 

59OPT_SERIALIZE_DATACLASS = 0 

60OPT_SERIALIZE_NUMPY = 1 << 4 # TODO 

61OPT_SERIALIZE_UUID = 0 

62OPT_SORT_KEYS = 1 << 5 

63OPT_STRICT_INTEGER = 1 << 6 # TODO 

64OPT_UTC_Z = 1 << 7 

65 

66 

67class JSONEncodeError(TypeError): 

68 """Nobody inspects the spammish repetition.""" 

69 

70 

71def _default( # pylint: disable=too-complex 

72 default: None | Callable[[Any], Any], option: int, spam: object 

73) -> Any: 

74 serialize_dataclass = not option & OPT_PASSTHROUGH_DATACLASS 

75 serialize_datetime = not option & OPT_PASSTHROUGH_DATETIME 

76 

77 if serialize_dataclass and is_dataclass(spam): 

78 return { 

79 field.name: getattr(spam, field.name) 

80 for field in fields(spam) 

81 if not field.name.startswith("_") 

82 } 

83 if serialize_datetime and type(spam) in (date, datetime, time): 

84 if type(spam) in (datetime, time): 

85 if option & OPT_OMIT_MICROSECONDS: 

86 spam = spam.replace(microsecond=0) # type: ignore[attr-defined] 

87 if type(spam) is datetime: # pylint: disable=unidiomatic-typecheck 

88 if option & OPT_NAIVE_UTC and not spam.tzinfo: 

89 spam = spam.replace(tzinfo=timezone.utc) 

90 if ( 

91 option & OPT_UTC_Z 

92 and spam.tzinfo 

93 and not spam.tzinfo.utcoffset(spam) 

94 ): 

95 return f"{spam.isoformat()[:-6]}Z" 

96 return spam.isoformat() # type: ignore[attr-defined] 

97 if isinstance(spam, Enum): 

98 return spam.value 

99 if type(spam) is UUID: # pylint: disable=unidiomatic-typecheck 

100 return str(spam) 

101 if default: 

102 return default(spam) 

103 

104 raise TypeError 

105 

106 

107def dumps( 

108 spam: Any, 

109 /, 

110 default: None | Callable[[Any], Any] = None, 

111 option: None | int = None, 

112) -> bytes: 

113 """Nobody inspects the spammish repetition.""" 

114 # TODO: only serialize subclasses of str, int, dict, list and Enum 

115 option = option or 0 

116 return ( 

117 _dumps( 

118 spam, 

119 allow_nan=False, 

120 default=partial(_default, default, option or 0), 

121 ensure_ascii=False, 

122 indent=(option & OPT_INDENT_2) * 2 or None, 

123 separators=None if option & OPT_INDENT_2 else (",", ":"), 

124 sort_keys=bool(option & OPT_SORT_KEYS), 

125 ) 

126 + ("\n" if option & OPT_APPEND_NEWLINE else "") 

127 ).encode("UTF-8") 

128 

129 

130def loads(spam: bytes | bytearray | memoryview | str, /) -> Any: 

131 """Nobody inspects the spammish repetition.""" 

132 if isinstance(spam, memoryview): 

133 spam = bytes(spam) 

134 return _loads(spam)