[pypy-commit] pypy faster-json: use identity_dict and factor out common infrastructure

fijal noreply at buildbot.pypy.org
Wed Oct 19 13:29:24 CEST 2011


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: faster-json
Changeset: r48228:e562bb829fbf
Date: 2011-10-19 13:29 +0200
http://bitbucket.org/pypy/pypy/changeset/e562bb829fbf/

Log:	use identity_dict and factor out common infrastructure

diff --git a/lib-python/modified-2.7/json/encoder.py b/lib-python/modified-2.7/json/encoder.py
--- a/lib-python/modified-2.7/json/encoder.py
+++ b/lib-python/modified-2.7/json/encoder.py
@@ -2,6 +2,8 @@
 """
 import re
 
+from __pypy__ import identity_dict
+
 ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]')
 ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
 HAS_UTF8 = re.compile(r'[\x80-\xff]')
@@ -206,7 +208,7 @@
 
         """
         if self.check_circular:
-            markers = {}
+            markers = identity_dict()
         else:
             markers = None
         if self.ensure_ascii:
@@ -242,15 +244,21 @@
 
         return text
 
+    def _mark_markers(self, markers, o):
+        if markers is not None:
+            if o in markers:
+                raise ValueError("Circular reference detected")
+            markers[o] = None
+
+    def _remove_markers(self, markers, o):
+        if markers is not None:
+            del markers[o]
+
     def _iterencode_list(self, lst, markers, _current_indent_level):
         if not lst:
             yield '[]'
             return
-        if markers is not None:
-            markerid = id(lst)
-            if markerid in markers:
-                raise ValueError("Circular reference detected")
-            markers[markerid] = lst
+        self._mark_markers(markers, lst)
         buf = '['
         if self.indent is not None:
             _current_indent_level += 1
@@ -296,18 +304,13 @@
             _current_indent_level -= 1
             yield '\n' + (' ' * (self.indent * _current_indent_level))
         yield ']'
-        if markers is not None:
-            del markers[markerid]
+        self._remove_markers(markers, lst)
 
     def _iterencode_dict(self, dct, markers, _current_indent_level):
         if not dct:
             yield '{}'
             return
-        if markers is not None:
-            markerid = id(dct)
-            if markerid in markers:
-                raise ValueError("Circular reference detected")
-            markers[markerid] = dct
+        self._mark_markers(markers, dct)
         yield '{'
         if self.indent is not None:
             _current_indent_level += 1
@@ -376,8 +379,7 @@
             _current_indent_level -= 1
             yield '\n' + (' ' * (self.indent * _current_indent_level))
         yield '}'
-        if markers is not None:
-            del markers[markerid]
+        self._remove_markers(markers, dct)
 
     def _iterencode(self, o, markers, _current_indent_level):
         if isinstance(o, basestring):
@@ -401,15 +403,9 @@
                                                _current_indent_level):
                 yield chunk
         else:
-            if markers is not None:
-                markerid = id(o)
-                if markerid in markers:
-                    raise ValueError("Circular reference detected")
-                markers[markerid] = o
-            o = self.default(o)
-            for chunk in self._iterencode(o, markers,
+            self._mark_markers(markers, o)
+            obj = self.default(o)
+            for chunk in self._iterencode(obj, markers,
                                           _current_indent_level):
                 yield chunk
-            if markers is not None:
-                del markers[markerid]
-
+            self._remove_markers(markers, o)


More information about the pypy-commit mailing list