File: test_error.py

package info (click to toggle)
python-orjson 3.10.7-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,180 kB
  • sloc: ansic: 11,270; python: 6,658; sh: 135; makefile: 9
file content (191 lines) | stat: -rw-r--r-- 5,444 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

import json

import pytest

import orjson

from .util import read_fixture_str

ASCII_TEST = b"""\
{
  "a": "qwe",
  "b": "qweqwe",
  "c": "qweq",
  "d: "qwe"
}
"""

MULTILINE_EMOJI = """[
    "😊",
    "a"
"""


class TestJsonDecodeError:
    def _get_error_infos(self, json_decode_error_exc_info):
        return {
            k: v
            for k, v in json_decode_error_exc_info.value.__dict__.items()
            if k in ("pos", "lineno", "colno")
        }

    def _test(self, data, expected_err_infos):
        with pytest.raises(json.decoder.JSONDecodeError) as json_exc_info:
            json.loads(data)

        with pytest.raises(json.decoder.JSONDecodeError) as orjson_exc_info:
            orjson.loads(data)

        assert (
            self._get_error_infos(json_exc_info)
            == self._get_error_infos(orjson_exc_info)
            == expected_err_infos
        )

    def test_empty(self):
        with pytest.raises(orjson.JSONDecodeError) as json_exc_info:
            orjson.loads("")
        assert str(json_exc_info.value).startswith(
            "Input is a zero-length, empty document:"
        )

    def test_ascii(self):
        self._test(
            ASCII_TEST,
            {"pos": 55, "lineno": 5, "colno": 8},
        )

    def test_latin1(self):
        self._test(
            """["ΓΌΓ½ΓΎΓΏ", "a" """,
            {"pos": 13, "lineno": 1, "colno": 14},
        )

    def test_two_byte_str(self):
        self._test(
            """["東京", "a" """,
            {"pos": 11, "lineno": 1, "colno": 12},
        )

    def test_two_byte_bytes(self):
        self._test(
            b'["\xe6\x9d\xb1\xe4\xba\xac", "a" ',
            {"pos": 11, "lineno": 1, "colno": 12},
        )

    def test_four_byte(self):
        self._test(
            MULTILINE_EMOJI,
            {"pos": 19, "lineno": 4, "colno": 1},
        )

    def test_tab(self):
        data = read_fixture_str("fail26.json", "jsonchecker")
        with pytest.raises(json.decoder.JSONDecodeError) as json_exc_info:
            json.loads(data)

        assert self._get_error_infos(json_exc_info) == {
            "pos": 5,
            "lineno": 1,
            "colno": 6,
        }

        with pytest.raises(json.decoder.JSONDecodeError) as json_exc_info:
            orjson.loads(data)

        assert self._get_error_infos(json_exc_info) == {
            "pos": 6,
            "lineno": 1,
            "colno": 7,
        }


class Custom:
    pass


class CustomException(Exception):
    pass


def default_typeerror(obj):
    raise TypeError


def default_notimplementederror(obj):
    raise NotImplementedError


def default_systemerror(obj):
    raise SystemError


def default_importerror(obj):
    import doesnotexist

    assert doesnotexist


CUSTOM_ERROR_MESSAGE = "zxc"


def default_customerror(obj):
    raise CustomException(CUSTOM_ERROR_MESSAGE)


class TestJsonEncodeError:
    def test_dumps_arg(self):
        with pytest.raises(orjson.JSONEncodeError) as exc_info:
            orjson.dumps()  # type: ignore
        assert exc_info.type == orjson.JSONEncodeError
        assert (
            str(exc_info.value)
            == "dumps() missing 1 required positional argument: 'obj'"
        )
        assert exc_info.value.__cause__ is None

    def test_dumps_chain_none(self):
        with pytest.raises(orjson.JSONEncodeError) as exc_info:
            orjson.dumps(Custom())
        assert exc_info.type == orjson.JSONEncodeError
        assert str(exc_info.value) == "Type is not JSON serializable: Custom"
        assert exc_info.value.__cause__ is None

    def test_dumps_chain_u64(self):
        with pytest.raises(orjson.JSONEncodeError) as exc_info:
            orjson.dumps([18446744073709551615, Custom()])
        assert exc_info.type == orjson.JSONEncodeError
        assert exc_info.value.__cause__ is None

    def test_dumps_chain_default_typeerror(self):
        with pytest.raises(orjson.JSONEncodeError) as exc_info:
            orjson.dumps(Custom(), default=default_typeerror)
        assert exc_info.type == orjson.JSONEncodeError
        assert isinstance(exc_info.value.__cause__, TypeError)

    def test_dumps_chain_default_systemerror(self):
        with pytest.raises(orjson.JSONEncodeError) as exc_info:
            orjson.dumps(Custom(), default=default_systemerror)
        assert exc_info.type == orjson.JSONEncodeError
        assert isinstance(exc_info.value.__cause__, SystemError)

    def test_dumps_chain_default_importerror(self):
        with pytest.raises(orjson.JSONEncodeError) as exc_info:
            orjson.dumps(Custom(), default=default_importerror)
        assert exc_info.type == orjson.JSONEncodeError
        assert isinstance(exc_info.value.__cause__, ImportError)

    def test_dumps_chain_default_customerror(self):
        with pytest.raises(orjson.JSONEncodeError) as exc_info:
            orjson.dumps(Custom(), default=default_customerror)
        assert exc_info.type == orjson.JSONEncodeError
        assert isinstance(exc_info.value.__cause__, CustomException)
        assert str(exc_info.value.__cause__) == CUSTOM_ERROR_MESSAGE

    def test_dumps_normalize_exception(self):
        with pytest.raises(orjson.JSONEncodeError) as exc_info:
            orjson.dumps(10**60)
        assert exc_info.type == orjson.JSONEncodeError
        assert isinstance(exc_info.value.__cause__, OverflowError)