| 
									
										
										
										
											2022-01-28 01:35:13 +01:00
										 |  |  | from test import support | 
					
						
							| 
									
										
										
										
											2013-08-08 15:03:45 +03:00
										 |  |  | from test.test_json import PyTest, CTest | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class JSONTestObject: | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-14 06:47:51 +03:00
										 |  |  | class TestRecursion: | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  |     def test_listrecursion(self): | 
					
						
							|  |  |  |         x = [] | 
					
						
							|  |  |  |         x.append(x) | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2011-05-14 06:47:51 +03:00
										 |  |  |             self.dumps(x) | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  |         except ValueError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.fail("didn't raise ValueError on list recursion") | 
					
						
							|  |  |  |         x = [] | 
					
						
							|  |  |  |         y = [x] | 
					
						
							|  |  |  |         x.append(y) | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2011-05-14 06:47:51 +03:00
										 |  |  |             self.dumps(x) | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  |         except ValueError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.fail("didn't raise ValueError on alternating list recursion") | 
					
						
							|  |  |  |         y = [] | 
					
						
							|  |  |  |         x = [y, y] | 
					
						
							|  |  |  |         # ensure that the marker is cleared | 
					
						
							| 
									
										
										
										
											2011-05-14 06:47:51 +03:00
										 |  |  |         self.dumps(x) | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_dictrecursion(self): | 
					
						
							|  |  |  |         x = {} | 
					
						
							|  |  |  |         x["test"] = x | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2011-05-14 06:47:51 +03:00
										 |  |  |             self.dumps(x) | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  |         except ValueError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.fail("didn't raise ValueError on dict recursion") | 
					
						
							|  |  |  |         x = {} | 
					
						
							|  |  |  |         y = {"a": x, "b": x} | 
					
						
							|  |  |  |         # ensure that the marker is cleared | 
					
						
							| 
									
										
										
										
											2011-05-14 06:47:51 +03:00
										 |  |  |         self.dumps(x) | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_defaultrecursion(self): | 
					
						
							| 
									
										
										
										
											2011-05-14 06:47:51 +03:00
										 |  |  |         class RecursiveJSONEncoder(self.json.JSONEncoder): | 
					
						
							|  |  |  |             recurse = False | 
					
						
							|  |  |  |             def default(self, o): | 
					
						
							|  |  |  |                 if o is JSONTestObject: | 
					
						
							|  |  |  |                     if self.recurse: | 
					
						
							|  |  |  |                         return [JSONTestObject] | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         return 'JSONTestObject' | 
					
						
							| 
									
										
										
										
											2020-05-15 01:02:10 +02:00
										 |  |  |                 return self.json.JSONEncoder.default(o) | 
					
						
							| 
									
										
										
										
											2011-05-14 06:47:51 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  |         enc = RecursiveJSONEncoder() | 
					
						
							| 
									
										
										
										
											2010-11-21 01:30:29 +00:00
										 |  |  |         self.assertEqual(enc.encode(JSONTestObject), '"JSONTestObject"') | 
					
						
							| 
									
										
										
										
											2008-05-08 14:29:10 +00:00
										 |  |  |         enc.recurse = True | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             enc.encode(JSONTestObject) | 
					
						
							|  |  |  |         except ValueError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.fail("didn't raise ValueError on default recursion") | 
					
						
							| 
									
										
										
										
											2011-05-07 17:58:09 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-11 01:02:56 +03:00
										 |  |  |     def test_highly_nested_objects_decoding(self): | 
					
						
							| 
									
										
										
										
											2011-05-07 17:58:09 +03:00
										 |  |  |         # test that loading highly-nested objects doesn't segfault when C | 
					
						
							|  |  |  |         # accelerations are used. See #12017 | 
					
						
							| 
									
										
										
										
											2015-07-03 01:04:23 -04:00
										 |  |  |         with self.assertRaises(RecursionError): | 
					
						
							| 
									
										
										
										
											2022-01-28 01:35:13 +01:00
										 |  |  |             with support.infinite_recursion(): | 
					
						
							|  |  |  |                 self.loads('{"a":' * 100000 + '1' + '}' * 100000) | 
					
						
							| 
									
										
										
										
											2015-07-03 01:04:23 -04:00
										 |  |  |         with self.assertRaises(RecursionError): | 
					
						
							| 
									
										
										
										
											2022-01-28 01:35:13 +01:00
										 |  |  |             with support.infinite_recursion(): | 
					
						
							|  |  |  |                 self.loads('{"a":' * 100000 + '[1]' + '}' * 100000) | 
					
						
							| 
									
										
										
										
											2015-07-03 01:04:23 -04:00
										 |  |  |         with self.assertRaises(RecursionError): | 
					
						
							| 
									
										
										
										
											2022-01-28 01:35:13 +01:00
										 |  |  |             with support.infinite_recursion(): | 
					
						
							|  |  |  |                 self.loads('[' * 100000 + '1' + ']' * 100000) | 
					
						
							| 
									
										
										
										
											2011-05-07 17:58:09 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-11 01:02:56 +03:00
										 |  |  |     def test_highly_nested_objects_encoding(self): | 
					
						
							|  |  |  |         # See #12051 | 
					
						
							|  |  |  |         l, d = [], {} | 
					
						
							|  |  |  |         for x in range(100000): | 
					
						
							|  |  |  |             l, d = [l], {'k':d} | 
					
						
							| 
									
										
										
										
											2015-07-03 01:04:23 -04:00
										 |  |  |         with self.assertRaises(RecursionError): | 
					
						
							| 
									
										
										
										
											2023-12-22 14:25:25 +00:00
										 |  |  |             with support.infinite_recursion(5000): | 
					
						
							| 
									
										
										
										
											2022-01-28 01:35:13 +01:00
										 |  |  |                 self.dumps(l) | 
					
						
							| 
									
										
										
										
											2015-07-03 01:04:23 -04:00
										 |  |  |         with self.assertRaises(RecursionError): | 
					
						
							| 
									
										
										
										
											2023-12-22 14:25:25 +00:00
										 |  |  |             with support.infinite_recursion(5000): | 
					
						
							| 
									
										
										
										
											2022-01-28 01:35:13 +01:00
										 |  |  |                 self.dumps(d) | 
					
						
							| 
									
										
										
										
											2011-05-11 01:02:56 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_endless_recursion(self): | 
					
						
							|  |  |  |         # See #12051 | 
					
						
							| 
									
										
										
										
											2011-05-14 06:47:51 +03:00
										 |  |  |         class EndlessJSONEncoder(self.json.JSONEncoder): | 
					
						
							|  |  |  |             def default(self, o): | 
					
						
							|  |  |  |                 """If check_circular is False, this will keep adding another list.""" | 
					
						
							|  |  |  |                 return [o] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-03 01:04:23 -04:00
										 |  |  |         with self.assertRaises(RecursionError): | 
					
						
							| 
									
										
										
										
											2023-12-22 14:25:25 +00:00
										 |  |  |             with support.infinite_recursion(1000): | 
					
						
							| 
									
										
										
										
											2022-01-28 01:35:13 +01:00
										 |  |  |                 EndlessJSONEncoder(check_circular=False).encode(5j) | 
					
						
							| 
									
										
										
										
											2011-05-14 06:47:51 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestPyRecursion(TestRecursion, PyTest): pass | 
					
						
							|  |  |  | class TestCRecursion(TestRecursion, CTest): pass |