1from io import StringIO
2from test.test_json import PyTest, CTest
3
4from test.support import bigmemtest, _1G
5
6class TestDump:
7    def test_dump(self):
8        sio = StringIO()
9        self.json.dump({}, sio)
10        self.assertEqual(sio.getvalue(), '{}')
11
12    def test_dumps(self):
13        self.assertEqual(self.dumps({}), '{}')
14
15    def test_encode_truefalse(self):
16        self.assertEqual(self.dumps(
17                 {True: False, False: True}, sort_keys=True),
18                 '{"false": true, "true": false}')
19        self.assertEqual(self.dumps(
20                {2: 3.0, 4.0: 5, False: 1, 6: True}, sort_keys=True),
21                '{"false": 1, "2": 3.0, "4.0": 5, "6": true}')
22
23    # Issue 16228: Crash on encoding resized list
24    def test_encode_mutated(self):
25        a = [object()] * 10
26        def crasher(obj):
27            del a[-1]
28        self.assertEqual(self.dumps(a, default=crasher),
29                 '[null, null, null, null, null]')
30
31    # Issue 24094
32    def test_encode_evil_dict(self):
33        class D(dict):
34            def keys(self):
35                return L
36
37        class X:
38            def __hash__(self):
39                del L[0]
40                return 1337
41
42            def __lt__(self, o):
43                return 0
44
45        L = [X() for i in range(1122)]
46        d = D()
47        d[1337] = "true.dat"
48        self.assertEqual(self.dumps(d, sort_keys=True), '{"1337": "true.dat"}')
49
50
51class TestPyDump(TestDump, PyTest): pass
52
53class TestCDump(TestDump, CTest):
54
55    # The size requirement here is hopefully over-estimated (actual
56    # memory consumption depending on implementation details, and also
57    # system memory management, since this may allocate a lot of
58    # small objects).
59
60    @bigmemtest(size=_1G, memuse=1)
61    def test_large_list(self, size):
62        N = int(30 * 1024 * 1024 * (size / _1G))
63        l = [1] * N
64        encoded = self.dumps(l)
65        self.assertEqual(len(encoded), N * 3)
66        self.assertEqual(encoded[:1], "[")
67        self.assertEqual(encoded[-2:], "1]")
68        self.assertEqual(encoded[1:-2], "1, " * (N - 1))
69