diff -r 3fbfa61634de Lib/json/decoder.py --- a/Lib/json/decoder.py Thu Jul 19 00:14:35 2012 -0500 +++ b/Lib/json/decoder.py Fri Jul 20 15:25:15 2012 +0300 @@ -359,13 +359,16 @@ """Decode a JSON document from ``s`` (a ``str`` beginning with a JSON document) and return a 2-tuple of the Python representation and the index in ``s`` where the document ended. + Optionally, ``idx`` can be used to specify an offset in ``s`` + where the document begins. This can be used to decode a JSON document from a string that may have extraneous data at the end. """ + _w = WHITESPACE.match try: - obj, end = self.scan_once(s, idx) + obj, end = self.scan_once(s, idx=_w(s, idx).end()) except StopIteration: raise ValueError("No JSON object could be decoded") return obj, end diff -r 3fbfa61634de Lib/test/json_tests/test_decode.py --- a/Lib/test/json_tests/test_decode.py Thu Jul 19 00:14:35 2012 -0500 +++ b/Lib/test/json_tests/test_decode.py Fri Jul 20 15:25:15 2012 +0300 @@ -55,5 +55,21 @@ self.check_keys_reuse(s, self.json.decoder.JSONDecoder().decode) +class TestRawDecode: + def test_whitespace(self): + decoder = self.json.JSONDecoder() + self.assertEqual(decoder.raw_decode(' {}'), ({}, 3)) + self.assertEqual(decoder.raw_decode(' []'), ([], 4)) + self.assertEqual(decoder.raw_decode(' ""'), ('', 5)) + s = ' { "key" : "value" , "k":"v" } \n' \ + ' { "key": "value", "k" :"v"} ' + val1, n1 = decoder.raw_decode(s) + val2, n2 = decoder.raw_decode(s[n1:]) + self.assertEqual(val1, {"key":"value", "k":"v"}) + self.assertEqual(val2, {"key":"value", "k":"v"}) + + class TestPyDecode(TestDecode, PyTest): pass class TestCDecode(TestDecode, CTest): pass +class TestPyRawDecode(TestRawDecode, PyTest): pass +class TestCRawDecode(TestRawDecode, CTest): pass