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