Home | History | Annotate | Download | only in test_json
      1 from test.test_json import PyTest, CTest
      2 
      3 
      4 class JSONTestObject:
      5     pass
      6 
      7 
      8 class TestRecursion:
      9     def test_listrecursion(self):
     10         x = []
     11         x.append(x)
     12         try:
     13             self.dumps(x)
     14         except ValueError:
     15             pass
     16         else:
     17             self.fail("didn't raise ValueError on list recursion")
     18         x = []
     19         y = [x]
     20         x.append(y)
     21         try:
     22             self.dumps(x)
     23         except ValueError:
     24             pass
     25         else:
     26             self.fail("didn't raise ValueError on alternating list recursion")
     27         y = []
     28         x = [y, y]
     29         # ensure that the marker is cleared
     30         self.dumps(x)
     31 
     32     def test_dictrecursion(self):
     33         x = {}
     34         x["test"] = x
     35         try:
     36             self.dumps(x)
     37         except ValueError:
     38             pass
     39         else:
     40             self.fail("didn't raise ValueError on dict recursion")
     41         x = {}
     42         y = {"a": x, "b": x}
     43         # ensure that the marker is cleared
     44         self.dumps(x)
     45 
     46     def test_defaultrecursion(self):
     47         class RecursiveJSONEncoder(self.json.JSONEncoder):
     48             recurse = False
     49             def default(self, o):
     50                 if o is JSONTestObject:
     51                     if self.recurse:
     52                         return [JSONTestObject]
     53                     else:
     54                         return 'JSONTestObject'
     55                 return pyjson.JSONEncoder.default(o)
     56 
     57         enc = RecursiveJSONEncoder()
     58         self.assertEqual(enc.encode(JSONTestObject), '"JSONTestObject"')
     59         enc.recurse = True
     60         try:
     61             enc.encode(JSONTestObject)
     62         except ValueError:
     63             pass
     64         else:
     65             self.fail("didn't raise ValueError on default recursion")
     66 
     67 
     68     def test_highly_nested_objects_decoding(self):
     69         # test that loading highly-nested objects doesn't segfault when C
     70         # accelerations are used. See #12017
     71         with self.assertRaises(RecursionError):
     72             self.loads('{"a":' * 100000 + '1' + '}' * 100000)
     73         with self.assertRaises(RecursionError):
     74             self.loads('{"a":' * 100000 + '[1]' + '}' * 100000)
     75         with self.assertRaises(RecursionError):
     76             self.loads('[' * 100000 + '1' + ']' * 100000)
     77 
     78     def test_highly_nested_objects_encoding(self):
     79         # See #12051
     80         l, d = [], {}
     81         for x in range(100000):
     82             l, d = [l], {'k':d}
     83         with self.assertRaises(RecursionError):
     84             self.dumps(l)
     85         with self.assertRaises(RecursionError):
     86             self.dumps(d)
     87 
     88     def test_endless_recursion(self):
     89         # See #12051
     90         class EndlessJSONEncoder(self.json.JSONEncoder):
     91             def default(self, o):
     92                 """If check_circular is False, this will keep adding another list."""
     93                 return [o]
     94 
     95         with self.assertRaises(RecursionError):
     96             EndlessJSONEncoder(check_circular=False).encode(5j)
     97 
     98 
     99 class TestPyRecursion(TestRecursion, PyTest): pass
    100 class TestCRecursion(TestRecursion, CTest): pass
    101