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-standalone Show documentation
Show all versions of jython-standalone 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
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")
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)
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)
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