From 4f95a52fe24cd136da5634747d5334c86d400d2d Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Wed, 13 Apr 2011 06:58:29 +0300 Subject: [PATCH 1/4] #9233: skip _json-specific tests when _json is not available. --- Lib/json/tests/test_scanstring.py | 8 +++++++- Lib/json/tests/test_speedups.py | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Lib/json/tests/test_scanstring.py b/Lib/json/tests/test_scanstring.py index d503851e56d..8f5999eff36 100644 --- a/Lib/json/tests/test_scanstring.py +++ b/Lib/json/tests/test_scanstring.py @@ -1,14 +1,20 @@ import sys import decimal -from unittest import TestCase +from unittest import TestCase, skipUnless import json import json.decoder +try: + import _json +except ImportError: + _json = None + class TestScanString(TestCase): def test_py_scanstring(self): self._test_scanstring(json.decoder.py_scanstring) + @skipUnless(_json, 'test requires the _json module') def test_c_scanstring(self): if json.decoder.c_scanstring is not None: self._test_scanstring(json.decoder.c_scanstring) diff --git a/Lib/json/tests/test_speedups.py b/Lib/json/tests/test_speedups.py index 94381548a70..6f34cacc359 100644 --- a/Lib/json/tests/test_speedups.py +++ b/Lib/json/tests/test_speedups.py @@ -1,8 +1,14 @@ import decimal -from unittest import TestCase +from unittest import TestCase, skipUnless from json import decoder, encoder, scanner +try: + import _json +except ImportError: + _json = None + +@skipUnless(_json, 'test requires the _json module') class TestSpeedups(TestCase): def test_scanstring(self): self.assertEqual(decoder.scanstring.__module__, "_json") From c753305180db1e24029be7cfc4d8774167876c00 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Wed, 13 Apr 2011 07:04:18 +0300 Subject: [PATCH 2/4] #9233: Fix json to work properly even when _json is not available. --- Lib/json/decoder.py | 2 +- Lib/json/scanner.py | 1 + Misc/NEWS | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Lib/json/decoder.py b/Lib/json/decoder.py index d606cbd8c0f..7b3d7d54a1a 100644 --- a/Lib/json/decoder.py +++ b/Lib/json/decoder.py @@ -214,7 +214,7 @@ def JSONObject(s_and_end, strict, scan_once, object_hook, object_pairs_hook, pairs = object_hook(pairs) return pairs, end -def JSONArray(s_and_end, scan_once, context, _w=WHITESPACE.match): +def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): s, end = s_and_end values = [] nextchar = s[end:end + 1] diff --git a/Lib/json/scanner.py b/Lib/json/scanner.py index b4f356146fe..f94d2361493 100644 --- a/Lib/json/scanner.py +++ b/Lib/json/scanner.py @@ -22,6 +22,7 @@ def py_make_scanner(context): parse_int = context.parse_int parse_constant = context.parse_constant object_hook = context.object_hook + object_pairs_hook = context.object_pairs_hook def _scan_once(string, idx): try: diff --git a/Misc/NEWS b/Misc/NEWS index 021bcf15c2b..6a4da30c3fa 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -51,9 +51,11 @@ Core and Builtins Library ------- -- Issue #11703 - urllib2.geturl() does not return correct url when the original +- Issue #9233: Fix json to work properly even when _json is not available. + +- Issue #11703: urllib2.geturl() does not return correct url when the original url contains #fragment. - + - Issue #10019: Fixed regression in json module where an indent of 0 stopped adding newlines and acted instead like 'None'. From 42368f9b0cd9e9b00d617e7a52619b82b0101b3f Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Wed, 13 Apr 2011 07:08:17 +0300 Subject: [PATCH 3/4] Remove unnecessary imports and use assertIs instead of assertTrue. --- Lib/json/tests/test_scanstring.py | 1 - Lib/json/tests/test_speedups.py | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Lib/json/tests/test_scanstring.py b/Lib/json/tests/test_scanstring.py index 8f5999eff36..abd325324dd 100644 --- a/Lib/json/tests/test_scanstring.py +++ b/Lib/json/tests/test_scanstring.py @@ -1,5 +1,4 @@ import sys -import decimal from unittest import TestCase, skipUnless import json diff --git a/Lib/json/tests/test_speedups.py b/Lib/json/tests/test_speedups.py index 6f34cacc359..b7c141f7f6f 100644 --- a/Lib/json/tests/test_speedups.py +++ b/Lib/json/tests/test_speedups.py @@ -1,4 +1,3 @@ -import decimal from unittest import TestCase, skipUnless from json import decoder, encoder, scanner @@ -12,12 +11,12 @@ except ImportError: class TestSpeedups(TestCase): def test_scanstring(self): self.assertEqual(decoder.scanstring.__module__, "_json") - self.assertTrue(decoder.scanstring is decoder.c_scanstring) + self.assertIs(decoder.scanstring, decoder.c_scanstring) def test_encode_basestring_ascii(self): self.assertEqual(encoder.encode_basestring_ascii.__module__, "_json") - self.assertTrue(encoder.encode_basestring_ascii is - encoder.c_encode_basestring_ascii) + self.assertIs(encoder.encode_basestring_ascii, + encoder.c_encode_basestring_ascii) class TestDecode(TestCase): def test_make_scanner(self): From d210aa1ad9329661625ca5f0b6754f84ffc25021 Mon Sep 17 00:00:00 2001 From: Ezio Melotti Date: Wed, 13 Apr 2011 07:10:13 +0300 Subject: [PATCH 4/4] #9233: Fix json.loads({}) to return a dict (instead of a list), when _json is not available. --- Lib/json/decoder.py | 6 ++++++ Lib/json/tests/test_decode.py | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/Lib/json/decoder.py b/Lib/json/decoder.py index 7b3d7d54a1a..12fa81542b4 100644 --- a/Lib/json/decoder.py +++ b/Lib/json/decoder.py @@ -161,6 +161,12 @@ def JSONObject(s_and_end, strict, scan_once, object_hook, object_pairs_hook, nextchar = s[end:end + 1] # Trivial empty object if nextchar == '}': + if object_pairs_hook is not None: + result = object_pairs_hook(pairs) + return result, end + pairs = {} + if object_hook is not None: + pairs = object_hook(pairs) return pairs, end + 1 elif nextchar != '"': raise ValueError(errmsg("Expecting property name", s, end)) diff --git a/Lib/json/tests/test_decode.py b/Lib/json/tests/test_decode.py index 74d886ac26e..bf65e4696ce 100644 --- a/Lib/json/tests/test_decode.py +++ b/Lib/json/tests/test_decode.py @@ -16,6 +16,11 @@ class TestDecode(TestCase): self.assertTrue(isinstance(rval, float)) self.assertEqual(rval, 1.0) + def test_empty_objects(self): + self.assertEqual(json.loads('{}'), {}) + self.assertEqual(json.loads('[]'), []) + self.assertEqual(json.loads('""'), "") + def test_object_pairs_hook(self): s = '{"xkd":1, "kcw":2, "art":3, "hxm":4, "qrt":5, "pad":6, "hoy":7}' p = [("xkd", 1), ("kcw", 2), ("art", 3), ("hxm", 4),