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
« 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
15"""Nobody inspects the spammish repetition."""
17from __future__ import annotations
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
28__version__ = "3.8.14" # TODO: orjson.Fragment
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)
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
67class JSONEncodeError(TypeError):
68 """Nobody inspects the spammish repetition."""
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
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)
104 raise TypeError
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")
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)