Commits

Philip Jenvey committed ed9ae55

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

Comments (0)

Files changed (3)

lib-python/3/json/__init__.py

 
 __author__ = 'Bob Ippolito <bob@redivi.com>'
 
+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
 
     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:

pypy/module/_pypyjson/interp_decoder.py

         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)
             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 != ':':

pypy/module/_pypyjson/test/test__pypyjson.py

         import _pypyjson
         # http://json.org/JSON_checker/test/fail25.json
         s = '["\ttab\tcharacter\tin\tstring\t"]'
-        raises(ValueError, "_pypyjson.loads(s)")
+        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