Lib.json.tests.test_recursion.py Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython Show documentation
Show all versions of jython Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
from json.tests import PyTest, CTest
import unittest
from test import test_support
class JSONTestObject:
pass
class TestRecursion(object):
def test_listrecursion(self):
x = []
x.append(x)
try:
self.dumps(x)
except ValueError:
pass
else:
self.fail("didn't raise ValueError on list recursion")
x = []
y = [x]
x.append(y)
try:
self.dumps(x)
except ValueError:
pass
else:
self.fail("didn't raise ValueError on alternating list recursion")
y = []
x = [y, y]
# ensure that the marker is cleared
self.dumps(x)
def test_dictrecursion(self):
x = {}
x["test"] = x
try:
self.dumps(x)
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
self.dumps(x)
def test_defaultrecursion(self):
class RecursiveJSONEncoder(self.json.JSONEncoder):
recurse = False
def default(self, o):
if o is JSONTestObject:
if self.recurse:
return [JSONTestObject]
else:
return 'JSONTestObject'
return pyjson.JSONEncoder.default(o)
enc = RecursiveJSONEncoder()
self.assertEqual(enc.encode(JSONTestObject), '"JSONTestObject"')
enc.recurse = True
try:
enc.encode(JSONTestObject)
except ValueError:
pass
else:
self.fail("didn't raise ValueError on default recursion")
@unittest.skipIf(test_support.is_jython, "See http://bugs.jython.org/issue2536.")
def test_highly_nested_objects_decoding(self):
# test that loading highly-nested objects doesn't segfault when C
# accelerations are used. See #12017
# str
with self.assertRaises(RuntimeError):
self.loads('{"a":' * 100000 + '1' + '}' * 100000)
with self.assertRaises(RuntimeError):
self.loads('{"a":' * 100000 + '[1]' + '}' * 100000)
with self.assertRaises(RuntimeError):
self.loads('[' * 100000 + '1' + ']' * 100000)
# unicode
with self.assertRaises(RuntimeError):
self.loads(u'{"a":' * 100000 + u'1' + u'}' * 100000)
with self.assertRaises(RuntimeError):
self.loads(u'{"a":' * 100000 + u'[1]' + u'}' * 100000)
with self.assertRaises(RuntimeError):
self.loads(u'[' * 100000 + u'1' + u']' * 100000)
@unittest.skipIf(test_support.is_jython, "See http://bugs.jython.org/issue2536.")
def test_highly_nested_objects_encoding(self):
# See #12051
l, d = [], {}
for x in xrange(100000):
l, d = [l], {'k':d}
with self.assertRaises(RuntimeError):
self.dumps(l)
with self.assertRaises(RuntimeError):
self.dumps(d)
@unittest.skipIf(test_support.is_jython, "See http://bugs.jython.org/issue2536.")
def test_endless_recursion(self):
# See #12051
class EndlessJSONEncoder(self.json.JSONEncoder):
def default(self, o):
"""If check_circular is False, this will keep adding another list."""
return [o]
# NB: Jython interacts with overflows differently than CPython;
# given that the default function normally raises a ValueError upon
# an overflow, this seems reasonable.
with self.assertRaises(Exception) as cm:
EndlessJSONEncoder(check_circular=False).encode(5j)
self.assertIn(type(cm.exception), [RuntimeError, ValueError])
class TestPyRecursion(TestRecursion, PyTest): pass
class TestCRecursion(TestRecursion, CTest): pass