Author: Philip Jenvey <[email protected]>
Branch: py3k
Changeset: r72474:ed9ae55d00c8
Date: 2014-07-18 16:48 -0700
http://bitbucket.org/pypy/pypy/changeset/ed9ae55d00c8/

Log:    issue1556: cache json object keys (cpython issue7451) in _pypyjson
        and re-enable it now that it fully passes test_json

diff --git a/lib-python/3/json/__init__.py b/lib-python/3/json/__init__.py
--- a/lib-python/3/json/__init__.py
+++ b/lib-python/3/json/__init__.py
@@ -107,6 +107,12 @@
 
 __author__ = 'Bob Ippolito <[email protected]>'
 
+try:
+    # PyPy speedup, the interface is different than CPython's _json
+    import _pypyjson
+except ImportError:
+    _pypyjson = None
+
 from .decoder import JSONDecoder
 from .encoder import JSONEncoder
 
@@ -316,7 +322,7 @@
     if (cls is None and object_hook is None and
             parse_int is None and parse_float is None and
             parse_constant is None and object_pairs_hook is None and not kw):
-        return _default_decoder.decode(s)
+        return _pypyjson.loads(s) if _pypyjson else _default_decoder.decode(s)
     if cls is None:
         cls = JSONDecoder
     if object_hook is not None:
diff --git a/pypy/module/_pypyjson/interp_decoder.py 
b/pypy/module/_pypyjson/interp_decoder.py
--- a/pypy/module/_pypyjson/interp_decoder.py
+++ b/pypy/module/_pypyjson/interp_decoder.py
@@ -56,6 +56,7 @@
         self.end_ptr = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
         self.pos = 0
         self.last_type = TYPE_UNKNOWN
+        self.memo = {}
 
     def close(self):
         rffi.free_charp(self.ll_chars)
@@ -261,6 +262,8 @@
             w_name = self.decode_any(i)
             if self.last_type != TYPE_STRING:
                 self._raise("Key name must be string for object starting at 
char %d", start)
+            w_name = self.memo.setdefault(self.space.unicode_w(w_name), w_name)
+
             i = self.skip_whitespace(self.pos)
             ch = self.ll_chars[i]
             if ch != ':':
diff --git a/pypy/module/_pypyjson/test/test__pypyjson.py 
b/pypy/module/_pypyjson/test/test__pypyjson.py
--- a/pypy/module/_pypyjson/test/test__pypyjson.py
+++ b/pypy/module/_pypyjson/test/test__pypyjson.py
@@ -187,4 +187,12 @@
         import _pypyjson
         # http://json.org/JSON_checker/test/fail25.json
         s = '["\ttab\tcharacter\tin\tstring\t"]'
-        raises(ValueError, "_pypyjson.loads(s)")
\ No newline at end of file
+        raises(ValueError, "_pypyjson.loads(s)")
+
+    def test_keys_reuse(self):
+        import _pypyjson
+        s = '[{"a_key": 1, "b_\xe9": 2}, {"a_key": 3, "b_\xe9": 4}]'
+        rval = _pypyjson.loads(s)
+        (a, b), (c, d) = sorted(rval[0]), sorted(rval[1])
+        assert a is c
+        assert b is d
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to