Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #18023 -- Removed bundled simplejson.

And started the deprecation path for django.utils.simplejson.

Thanks Alex Ogier, Clueless, and other contributors for their
work on the patch.
  • Loading branch information...
commit cec6bd5a59547dc97fe98975c570fc27a1e970be 1 parent ee0a7c7
Aymeric Augustin authored April 29, 2012
1  MANIFEST.in
@@ -6,7 +6,6 @@ include MANIFEST.in
6 6
 include django/contrib/gis/gdal/LICENSE
7 7
 include django/contrib/gis/geos/LICENSE
8 8
 include django/dispatch/license.txt
9  
-include django/utils/simplejson/LICENSE.txt
10 9
 recursive-include docs *
11 10
 recursive-include scripts *
12 11
 recursive-include extras *
3  django/contrib/formtools/wizard/storage/cookie.py
... ...
@@ -1,6 +1,7 @@
4  django/contrib/gis/geometry/test_data.py
@@ -3,10 +3,10 @@
3 3
 for the GEOS and GDAL tests.
4 4
 """
5 5
 import gzip
  6
+import json
6 7
 import os
7 8
 
8 9
 from django.contrib import gis
9  
-from django.utils import simplejson
10 10
 
11 11
 
12 12
 # This global used to store reference geometry data.
@@ -100,6 +100,6 @@ def geometries(self):
100 100
         if GEOMETRIES is None:
101 101
             # Load up the test geometry data from fixture into global.
102 102
             gzf = gzip.GzipFile(os.path.join(TEST_DATA, 'geometries.json.gz'))
103  
-            geometries = simplejson.loads(gzf.read())
  103
+            geometries = json.loads(gzf.read())
104 104
             GEOMETRIES = TestGeomSet(**strconvert(geometries))
105 105
         return GEOMETRIES
3  django/contrib/messages/storage/cookie.py
... ...
@@ -1,7 +1,8 @@
3  django/contrib/messages/tests/cookie.py
... ...
@@ -1,10 +1,11 @@
13  django/core/serializers/json.py
@@ -2,14 +2,17 @@
2 2
 Serialize data to/from JSON
3 3
 """
4 4
 
  5
+# Avoid shadowing the standard library json module
  6
+from __future__ import absolute_import
  7
+
5 8
 import datetime
6 9
 import decimal
  10
+import json
7 11
 from StringIO import StringIO
8 12
 
9 13
 from django.core.serializers.base import DeserializationError
10 14
 from django.core.serializers.python import Serializer as PythonSerializer
11 15
 from django.core.serializers.python import Deserializer as PythonDeserializer
12  
-from django.utils import simplejson
13 16
 from django.utils.timezone import is_aware
14 17
 
15 18
 class Serializer(PythonSerializer):
@@ -19,10 +22,10 @@ class Serializer(PythonSerializer):
19 22
     internal_use_only = False
20 23
 
21 24
     def end_serialization(self):
22  
-        if simplejson.__version__.split('.') >= ['2', '1', '3']:
  25
+        if json.__version__.split('.') >= ['2', '1', '3']:
23 26
             # Use JS strings to represent Python Decimal instances (ticket #16850)
24 27
             self.options.update({'use_decimal': False})
25  
-        simplejson.dump(self.objects, self.stream, cls=DjangoJSONEncoder, **self.options)
  28
+        json.dump(self.objects, self.stream, cls=DjangoJSONEncoder, **self.options)
26 29
 
27 30
     def getvalue(self):
28 31
         if callable(getattr(self.stream, 'getvalue', None)):
@@ -38,7 +41,7 @@ def Deserializer(stream_or_string, **options):
38 41
     else:
39 42
         stream = stream_or_string
40 43
     try:
41  
-        for obj in PythonDeserializer(simplejson.load(stream), **options):
  44
+        for obj in PythonDeserializer(json.load(stream), **options):
42 45
             yield obj
43 46
     except GeneratorExit:
44 47
         raise
@@ -47,7 +50,7 @@ def Deserializer(stream_or_string, **options):
47 50
         raise DeserializationError(e)
48 51
 
49 52
 
50  
-class DjangoJSONEncoder(simplejson.JSONEncoder):
  53
+class DjangoJSONEncoder(json.JSONEncoder):
51 54
     """
52 55
     JSONEncoder subclass that knows how to encode date/time and decimal types.
53 56
     """
9  django/core/signing.py
@@ -33,12 +33,13 @@
33 33
 These functions make use of all of them.
34 34
 """
35 35
 import base64
  36
+import json
36 37
 import time
37 38
 import zlib
38 39
 
39 40
 from django.conf import settings
40 41
 from django.core.exceptions import ImproperlyConfigured
41  
-from django.utils import baseconv, simplejson
  42
+from django.utils import baseconv
42 43
 from django.utils.crypto import constant_time_compare, salted_hmac
43 44
 from django.utils.encoding import force_unicode, smart_str
44 45
 from django.utils.importlib import import_module
@@ -89,14 +90,14 @@ def get_cookie_signer(salt='django.core.signing.get_cookie_signer'):
89 90
 
90 91
 class JSONSerializer(object):
91 92
     """
92  
-    Simple wrapper around simplejson to be used in signing.dumps and
  93
+    Simple wrapper around json to be used in signing.dumps and
93 94
     signing.loads.
94 95
     """
95 96
     def dumps(self, obj):
96  
-        return simplejson.dumps(obj, separators=(',', ':'))
  97
+        return json.dumps(obj, separators=(',', ':'))
97 98
 
98 99
     def loads(self, data):
99  
-        return simplejson.loads(data)
  100
+        return json.loads(data)
100 101
 
101 102
 
102 103
 def dumps(obj, key=None, salt='django.core.signing', serializer=JSONSerializer, compress=False):
7  django/test/testcases.py
... ...
@@ -1,4 +1,5 @@
1 1
 import difflib
  2
+import json
2 3
 import os
3 4
 import re
4 5
 import sys
@@ -33,7 +34,7 @@
33 34
 from django.test.utils import (get_warnings_state, restore_warnings_state,
34 35
     override_settings)
35 36
 from django.test.utils import ContextList
36  
-from django.utils import simplejson, unittest as ut2
  37
+from django.utils import unittest as ut2
37 38
 from django.utils.encoding import smart_str, force_unicode
38 39
 from django.utils.unittest.util import safe_repr
39 40
 from django.views.static import serve
@@ -189,8 +190,8 @@ def check_output_json(self, want, got, optionsflags):
189 190
         """
190 191
         want, got = self._strip_quotes(want, got)
191 192
         try:
192  
-            want_json = simplejson.loads(want)
193  
-            got_json = simplejson.loads(got)
  193
+            want_json = json.loads(want)
  194
+            got_json = json.loads(got)
194 195
         except Exception:
195 196
             return False
196 197
         return want_json == got_json
31  django/utils/simplejson.py
... ...
@@ -0,0 +1,31 @@
  1
+# Django 1.5 only supports Python >= 2.6, where the standard library includes
  2
+# the json module. Previous version of Django shipped a copy for Python < 2.6.
  3
+
  4
+# For backwards compatibility, we're keeping an importable json module
  5
+# at this location, with the same lookup sequence.
  6
+
  7
+# Avoid shadowing the simplejson module
  8
+from __future__ import absolute_import
  9
+
  10
+import warnings
  11
+warnings.warn("django.utils.simplejson is deprecated; use json instead.",
  12
+              PendingDeprecationWarning)
  13
+
  14
+try:
  15
+    import simplejson
  16
+except ImportError:
  17
+    use_simplejson = False
  18
+else:
  19
+    # The system-installed version has priority providing it is either not an
  20
+    # earlier version or it contains the C speedups.
  21
+    from json import __version__ as stdlib_json_version
  22
+    use_simplejson = (hasattr(simplejson, '_speedups') or
  23
+        simplejson.__version__.split('.') >= stdlib_json_version.split('.'))
  24
+
  25
+# Make sure we copy over the version. See #17071
  26
+if use_simplejson:
  27
+    from simplejson import *
  28
+    from simplejson import __version__
  29
+else:
  30
+    from json import *
  31
+    from json import __version__
19  django/utils/simplejson/LICENSE.txt
... ...
@@ -1,19 +0,0 @@
1  
-Copyright (c) 2006 Bob Ippolito
2  
-
3  
-Permission is hereby granted, free of charge, to any person obtaining a copy of
4  
-this software and associated documentation files (the "Software"), to deal in
5  
-the Software without restriction, including without limitation the rights to
6  
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7  
-of the Software, and to permit persons to whom the Software is furnished to do
8  
-so, subject to the following conditions:
9  
-
10  
-The above copyright notice and this permission notice shall be included in all
11  
-copies or substantial portions of the Software.
12  
-
13  
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19  
-SOFTWARE.
354  django/utils/simplejson/__init__.py
... ...
@@ -1,354 +0,0 @@
1  
-r"""JSON (JavaScript Object Notation) <http://json.org> is a subset of
2  
-JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
3  
-interchange format.
4  
-
5  
-:mod:`simplejson` exposes an API familiar to users of the standard library
6  
-:mod:`marshal` and :mod:`pickle` modules. It is the externally maintained
7  
-version of the :mod:`json` library contained in Python 2.6, but maintains
8  
-compatibility with Python 2.4 and Python 2.5 and (currently) has
9  
-significant performance advantages, even without using the optional C
10  
-extension for speedups.
11  
-
12  
-Encoding basic Python object hierarchies::
13  
-
14  
-    >>> import simplejson as json
15  
-    >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
16  
-    '["foo", {"bar": ["baz", null, 1.0, 2]}]'
17  
-    >>> print json.dumps("\"foo\bar")
18  
-    "\"foo\bar"
19  
-    >>> print json.dumps(u'\u1234')
20  
-    "\u1234"
21  
-    >>> print json.dumps('\\')
22  
-    "\\"
23  
-    >>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
24  
-    {"a": 0, "b": 0, "c": 0}
25  
-    >>> from StringIO import StringIO
26  
-    >>> io = StringIO()
27  
-    >>> json.dump(['streaming API'], io)
28  
-    >>> io.getvalue()
29  
-    '["streaming API"]'
30  
-
31  
-Compact encoding::
32  
-
33  
-    >>> import simplejson as json
34  
-    >>> json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':'))
35  
-    '[1,2,3,{"4":5,"6":7}]'
36  
-
37  
-Pretty printing::
38  
-
39  
-    >>> import simplejson as json
40  
-    >>> s = json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
41  
-    >>> print '\n'.join([l.rstrip() for l in  s.splitlines()])
42  
-    {
43  
-        "4": 5,
44  
-        "6": 7
45  
-    }
46  
-
47  
-Decoding JSON::
48  
-
49  
-    >>> import simplejson as json
50  
-    >>> obj = [u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
51  
-    >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj
52  
-    True
53  
-    >>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar'
54  
-    True
55  
-    >>> from StringIO import StringIO
56  
-    >>> io = StringIO('["streaming API"]')
57  
-    >>> json.load(io)[0] == 'streaming API'
58  
-    True
59  
-
60  
-Specializing JSON object decoding::
61  
-
62  
-    >>> import simplejson as json
63  
-    >>> def as_complex(dct):
64  
-    ...     if '__complex__' in dct:
65  
-    ...         return complex(dct['real'], dct['imag'])
66  
-    ...     return dct
67  
-    ...
68  
-    >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
69  
-    ...     object_hook=as_complex)
70  
-    (1+2j)
71  
-    >>> import decimal
72  
-    >>> json.loads('1.1', parse_float=decimal.Decimal) == decimal.Decimal('1.1')
73  
-    True
74  
-
75  
-Specializing JSON object encoding::
76  
-
77  
-    >>> import simplejson as json
78  
-    >>> def encode_complex(obj):
79  
-    ...     if isinstance(obj, complex):
80  
-    ...         return [obj.real, obj.imag]
81  
-    ...     raise TypeError("%r is not JSON serializable" % (o,))
82  
-    ...
83  
-    >>> json.dumps(2 + 1j, default=encode_complex)
84  
-    '[2.0, 1.0]'
85  
-    >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j)
86  
-    '[2.0, 1.0]'
87  
-    >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j))
88  
-    '[2.0, 1.0]'
89  
-
90  
-
91  
-Using simplejson.tool from the shell to validate and pretty-print::
92  
-
93  
-    $ echo '{"json":"obj"}' | python -msimplejson.tool
94  
-    {
95  
-        "json": "obj"
96  
-    }
97  
-    $ echo '{ 1.2:3.4}' | python -msimplejson.tool
98  
-    Expecting property name: line 1 column 2 (char 2)
99  
-"""
100  
-
101  
-# Django modification: try to use the system version first, providing it's
102  
-# either of a later version of has the C speedups in place. Otherwise, fall
103  
-# back to our local copy.
104  
-
105  
-__version__ = '2.0.7'
106  
-
107  
-use_system_version = False
108  
-try:
109  
-    # The system-installed version has priority providing it is either not an
110  
-    # earlier version or it contains the C speedups.
111  
-    import simplejson
112  
-    if (simplejson.__version__.split('.') >= __version__.split('.') or
113  
-            hasattr(simplejson, '_speedups')):
114  
-        from simplejson import *
115  
-        use_system_version = True
116  
-        # Make sure we copy over the version. See #17071
117  
-        __version__ = simplejson.__version__
118  
-except ImportError:
119  
-    pass
120  
-
121  
-if not use_system_version:
122  
-    try:
123  
-        from json import *      # Python 2.6 preferred over local copy.
124  
-
125  
-        # There is a "json" package around that is not Python's "json", so we
126  
-        # check for something that is only in the namespace of the version we
127  
-        # want.
128  
-        JSONDecoder
129  
-
130  
-        use_system_version = True
131  
-        # Make sure we copy over the version. See #17071
132  
-        from json import __version__ as json_version
133  
-        __version__ = json_version
134  
-    except (ImportError, NameError):
135  
-        pass
136  
-
137  
-# If all else fails, we have a bundled version that can be used.
138  
-if not use_system_version:
139  
-    __all__ = [
140  
-        'dump', 'dumps', 'load', 'loads',
141  
-        'JSONDecoder', 'JSONEncoder',
142  
-    ]
143  
-
144  
-    from django.utils.simplejson.decoder import JSONDecoder
145  
-    from django.utils.simplejson.encoder import JSONEncoder
146  
-
147  
-    _default_encoder = JSONEncoder(
148  
-        skipkeys=False,
149  
-        ensure_ascii=True,
150  
-        check_circular=True,
151  
-        allow_nan=True,
152  
-        indent=None,
153  
-        separators=None,
154  
-        encoding='utf-8',
155  
-        default=None,
156  
-    )
157  
-
158  
-    def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
159  
-            allow_nan=True, cls=None, indent=None, separators=None,
160  
-            encoding='utf-8', default=None, **kw):
161  
-        """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
162  
-        ``.write()``-supporting file-like object).
163  
-
164  
-        If ``skipkeys`` is ``True`` then ``dict`` keys that are not basic types
165  
-        (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
166  
-        will be skipped instead of raising a ``TypeError``.
167  
-
168  
-        If ``ensure_ascii`` is ``False``, then the some chunks written to ``fp``
169  
-        may be ``unicode`` instances, subject to normal Python ``str`` to
170  
-        ``unicode`` coercion rules. Unless ``fp.write()`` explicitly
171  
-        understands ``unicode`` (as in ``codecs.getwriter()``) this is likely
172  
-        to cause an error.
173  
-
174  
-        If ``check_circular`` is ``False``, then the circular reference check
175  
-        for container types will be skipped and a circular reference will
176  
-        result in an ``OverflowError`` (or worse).
177  
-
178  
-        If ``allow_nan`` is ``False``, then it will be a ``ValueError`` to
179  
-        serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
180  
-        in strict compliance of the JSON specification, instead of using the
181  
-        JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
182  
-
183  
-        If ``indent`` is a non-negative integer, then JSON array elements and object
184  
-        members will be pretty-printed with that indent level. An indent level
185  
-        of 0 will only insert newlines. ``None`` is the most compact representation.
186  
-
187  
-        If ``separators`` is an ``(item_separator, dict_separator)`` tuple
188  
-        then it will be used instead of the default ``(', ', ': ')`` separators.
189  
-        ``(',', ':')`` is the most compact JSON representation.
190  
-
191  
-        ``encoding`` is the character encoding for str instances, default is UTF-8.
192  
-
193  
-        ``default(obj)`` is a function that should return a serializable version
194  
-        of obj or raise TypeError. The default simply raises TypeError.
195  
-
196  
-        To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
197  
-        ``.default()`` method to serialize additional types), specify it with
198  
-        the ``cls`` kwarg.
199  
-
200  
-        """
201  
-        # cached encoder
202  
-        if (skipkeys is False and ensure_ascii is True and
203  
-            check_circular is True and allow_nan is True and
204  
-            cls is None and indent is None and separators is None and
205  
-            encoding == 'utf-8' and default is None and not kw):
206  
-            iterable = _default_encoder.iterencode(obj)
207  
-        else:
208  
-            if cls is None:
209  
-                cls = JSONEncoder
210  
-            iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
211  
-                check_circular=check_circular, allow_nan=allow_nan, indent=indent,
212  
-                separators=separators, encoding=encoding,
213  
-                default=default, **kw).iterencode(obj)
214  
-        # could accelerate with writelines in some versions of Python, at
215  
-        # a debuggability cost
216  
-        for chunk in iterable:
217  
-            fp.write(chunk)
218  
-
219  
-
220  
-    def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
221  
-            allow_nan=True, cls=None, indent=None, separators=None,
222  
-            encoding='utf-8', default=None, **kw):
223  
-        """Serialize ``obj`` to a JSON formatted ``str``.
224  
-
225  
-        If ``skipkeys`` is ``True`` then ``dict`` keys that are not basic types
226  
-        (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
227  
-        will be skipped instead of raising a ``TypeError``.
228  
-
229  
-        If ``ensure_ascii`` is ``False``, then the return value will be a
230  
-        ``unicode`` instance subject to normal Python ``str`` to ``unicode``
231  
-        coercion rules instead of being escaped to an ASCII ``str``.
232  
-
233  
-        If ``check_circular`` is ``False``, then the circular reference check
234  
-        for container types will be skipped and a circular reference will
235  
-        result in an ``OverflowError`` (or worse).
236  
-
237  
-        If ``allow_nan`` is ``False``, then it will be a ``ValueError`` to
238  
-        serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
239  
-        strict compliance of the JSON specification, instead of using the
240  
-        JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
241  
-
242  
-        If ``indent`` is a non-negative integer, then JSON array elements and
243  
-        object members will be pretty-printed with that indent level. An indent
244  
-        level of 0 will only insert newlines. ``None`` is the most compact
245  
-        representation.
246  
-
247  
-        If ``separators`` is an ``(item_separator, dict_separator)`` tuple
248  
-        then it will be used instead of the default ``(', ', ': ')`` separators.
249  
-        ``(',', ':')`` is the most compact JSON representation.
250  
-
251  
-        ``encoding`` is the character encoding for str instances, default is UTF-8.
252  
-
253  
-        ``default(obj)`` is a function that should return a serializable version
254  
-        of obj or raise TypeError. The default simply raises TypeError.
255  
-
256  
-        To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
257  
-        ``.default()`` method to serialize additional types), specify it with
258  
-        the ``cls`` kwarg.
259  
-
260  
-        """
261  
-        # cached encoder
262  
-        if (skipkeys is False and ensure_ascii is True and
263  
-            check_circular is True and allow_nan is True and
264  
-            cls is None and indent is None and separators is None and
265  
-            encoding == 'utf-8' and default is None and not kw):
266  
-            return _default_encoder.encode(obj)
267  
-        if cls is None:
268  
-            cls = JSONEncoder
269  
-        return cls(
270  
-            skipkeys=skipkeys, ensure_ascii=ensure_ascii,
271  
-            check_circular=check_circular, allow_nan=allow_nan, indent=indent,
272  
-            separators=separators, encoding=encoding, default=default,
273  
-            **kw).encode(obj)
274  
-
275  
-
276  
-    _default_decoder = JSONDecoder(encoding=None, object_hook=None)
277  
-
278  
-
279  
-    def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
280  
-            parse_int=None, parse_constant=None, **kw):
281  
-        """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
282  
-        a JSON document) to a Python object.
283  
-
284  
-        If the contents of ``fp`` is encoded with an ASCII based encoding other
285  
-        than utf-8 (e.g. latin-1), then an appropriate ``encoding`` name must
286  
-        be specified. Encodings that are not ASCII based (such as UCS-2) are
287  
-        not allowed, and should be wrapped with
288  
-        ``codecs.getreader(fp)(encoding)``, or simply decoded to a ``unicode``
289  
-        object and passed to ``loads()``
290  
-
291  
-        ``object_hook`` is an optional function that will be called with the
292  
-        result of any object literal decode (a ``dict``). The return value of
293  
-        ``object_hook`` will be used instead of the ``dict``. This feature
294  
-        can be used to implement custom decoders (e.g. JSON-RPC class hinting).
295  
-
296  
-        To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
297  
-        kwarg.
298  
-
299  
-        """
300  
-        return loads(fp.read(),
301  
-            encoding=encoding, cls=cls, object_hook=object_hook,
302  
-            parse_float=parse_float, parse_int=parse_int,
303  
-            parse_constant=parse_constant, **kw)
304  
-
305  
-
306  
-    def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
307  
-            parse_int=None, parse_constant=None, **kw):
308  
-        """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON
309  
-        document) to a Python object.
310  
-
311  
-        If ``s`` is a ``str`` instance and is encoded with an ASCII based encoding
312  
-        other than utf-8 (e.g. latin-1) then an appropriate ``encoding`` name
313  
-        must be specified. Encodings that are not ASCII based (such as UCS-2)
314  
-        are not allowed and should be decoded to ``unicode`` first.
315  
-
316  
-        ``object_hook`` is an optional function that will be called with the
317  
-        result of any object literal decode (a ``dict``). The return value of
318  
-        ``object_hook`` will be used instead of the ``dict``. This feature
319  
-        can be used to implement custom decoders (e.g. JSON-RPC class hinting).
320  
-
321  
-        ``parse_float``, if specified, will be called with the string
322  
-        of every JSON float to be decoded. By default this is equivalent to
323  
-        float(num_str). This can be used to use another datatype or parser
324  
-        for JSON floats (e.g. decimal.Decimal).
325  
-
326  
-        ``parse_int``, if specified, will be called with the string
327  
-        of every JSON int to be decoded. By default this is equivalent to
328  
-        int(num_str). This can be used to use another datatype or parser
329  
-        for JSON integers (e.g. float).
330  
-
331  
-        ``parse_constant``, if specified, will be called with one of the
332  
-        following strings: -Infinity, Infinity, NaN, null, true, false.
333  
-        This can be used to raise an exception if invalid JSON numbers
334  
-        are encountered.
335  
-
336  
-        To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
337  
-        kwarg.
338  
-
339  
-        """
340  
-        if (cls is None and encoding is None and object_hook is None and
341  
-                parse_int is None and parse_float is None and
342  
-                parse_constant is None and not kw):
343  
-            return _default_decoder.decode(s)
344  
-        if cls is None:
345  
-            cls = JSONDecoder
346  
-        if object_hook is not None:
347  
-            kw['object_hook'] = object_hook
348  
-        if parse_float is not None:
349  
-            kw['parse_float'] = parse_float
350  
-        if parse_int is not None:
351  
-            kw['parse_int'] = parse_int
352  
-        if parse_constant is not None:
353  
-            kw['parse_constant'] = parse_constant
354  
-        return cls(encoding=encoding, **kw).decode(s)
345  django/utils/simplejson/decoder.py
... ...
@@ -1,345 +0,0 @@
1  
-"""Implementation of JSONDecoder
2  
-"""
3  
-import re
4  
-import sys
5  
-import struct
6  
-
7  
-from django.utils.simplejson.scanner import make_scanner
8  
-c_scanstring = None
9  
-
10  
-__all__ = ['JSONDecoder']
11  
-
12  
-FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL
13  
-
14  
-def _floatconstants():
15  
-    _BYTES = '7FF80000000000007FF0000000000000'.decode('hex')
16  
-    if sys.byteorder != 'big':
17  
-        _BYTES = _BYTES[:8][::-1] + _BYTES[8:][::-1]
18  
-    nan, inf = struct.unpack('dd', _BYTES)
19  
-    return nan, inf, -inf
20  
-
21  
-NaN, PosInf, NegInf = _floatconstants()
22  
-
23  
-
24  
-def linecol(doc, pos):
25  
-    lineno = doc.count('\n', 0, pos) + 1
26  
-    if lineno == 1:
27  
-        colno = pos
28  
-    else:
29  
-        colno = pos - doc.rindex('\n', 0, pos)
30  
-    return lineno, colno
31  
-
32  
-
33  
-def errmsg(msg, doc, pos, end=None):
34  
-    # Note that this function is called from _speedups
35  
-    lineno, colno = linecol(doc, pos)
36  
-    if end is None:
37  
-        return '%s: line %d column %d (char %d)' % (msg, lineno, colno, pos)
38  
-    endlineno, endcolno = linecol(doc, end)
39  
-    return '%s: line %d column %d - line %d column %d (char %d - %d)' % (
40  
-        msg, lineno, colno, endlineno, endcolno, pos, end)
41  
-
42  
-
43  
-_CONSTANTS = {
44  
-    '-Infinity': NegInf,
45  
-    'Infinity': PosInf,
46  
-    'NaN': NaN,
47  
-}
48  
-
49  
-STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS)
50  
-BACKSLASH = {
51  
-    '"': u'"', '\\': u'\\', '/': u'/',
52  
-    'b': u'\b', 'f': u'\f', 'n': u'\n', 'r': u'\r', 't': u'\t',
53  
-}
54  
-
55  
-DEFAULT_ENCODING = "utf-8"
56  
-
57  
-def py_scanstring(s, end, encoding=None, strict=True, _b=BACKSLASH, _m=STRINGCHUNK.match):
58  
-    """Scan the string s for a JSON string. End is the index of the
59  
-    character in s after the quote that started the JSON string.
60  
-    Unescapes all valid JSON string escape sequences and raises ValueError
61  
-    on attempt to decode an invalid string. If strict is False then literal
62  
-    control characters are allowed in the string.
63  
-    
64  
-    Returns a tuple of the decoded string and the index of the character in s
65  
-    after the end quote."""
66  
-    if encoding is None:
67  
-        encoding = DEFAULT_ENCODING
68  
-    chunks = []
69  
-    _append = chunks.append
70  
-    begin = end - 1
71  
-    while 1:
72  
-        chunk = _m(s, end)
73  
-        if chunk is None:
74  
-            raise ValueError(
75  
-                errmsg("Unterminated string starting at", s, begin))
76  
-        end = chunk.end()
77  
-        content, terminator = chunk.groups()
78  
-        # Content is contains zero or more unescaped string characters
79  
-        if content:
80  
-            if not isinstance(content, unicode):
81  
-                content = unicode(content, encoding)
82  
-            _append(content)
83  
-        # Terminator is the end of string, a literal control character,
84  
-        # or a backslash denoting that an escape sequence follows
85  
-        if terminator == '"':
86  
-            break
87  
-        elif terminator != '\\':
88  
-            if strict:
89  
-                msg = "Invalid control character %r at" % (terminator,)
90  
-                raise ValueError(msg, s, end)
91  
-            else:
92  
-                _append(terminator)
93  
-                continue
94  
-        try:
95  
-            esc = s[end]
96  
-        except IndexError:
97  
-            raise ValueError(
98  
-                errmsg("Unterminated string starting at", s, begin))
99  
-        # If not a unicode escape sequence, must be in the lookup table
100  
-        if esc != 'u':
101  
-            try:
102  
-                char = _b[esc]
103  
-            except KeyError:
104  
-                raise ValueError(
105  
-                    errmsg("Invalid \\escape: %r" % (esc,), s, end))
106  
-            end += 1
107  
-        else:
108  
-            # Unicode escape sequence
109  
-            esc = s[end + 1:end + 5]
110  
-            next_end = end + 5
111  
-            if len(esc) != 4:
112  
-                msg = "Invalid \\uXXXX escape"
113  
-                raise ValueError(errmsg(msg, s, end))
114  
-            uni = int(esc, 16)
115  
-            # Check for surrogate pair on UCS-4 systems
116  
-            if 0xd800 <= uni <= 0xdbff and sys.maxunicode > 65535:
117  
-                msg = "Invalid \\uXXXX\\uXXXX surrogate pair"
118  
-                if not s[end + 5:end + 7] == '\\u':
119  
-                    raise ValueError(errmsg(msg, s, end))
120  
-                esc2 = s[end + 7:end + 11]
121  
-                if len(esc2) != 4:
122  
-                    raise ValueError(errmsg(msg, s, end))
123  
-                uni2 = int(esc2, 16)
124  
-                uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))
125  
-                next_end += 6
126  
-            char = unichr(uni)
127  
-            end = next_end
128  
-        # Append the unescaped character
129  
-        _append(char)
130  
-    return u''.join(chunks), end
131  
-
132  
-
133  
-# Use speedup if available
134  
-scanstring = c_scanstring or py_scanstring
135  
-
136  
-WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS)
137  
-WHITESPACE_STR = ' \t\n\r'
138  
-
139  
-def JSONObject((s, end), encoding, strict, scan_once, object_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
140  
-    pairs = {}
141  
-    # Use a slice to prevent IndexError from being raised, the following
142  
-    # check will raise a more specific ValueError if the string is empty
143  
-    nextchar = s[end:end + 1]
144  
-    # Normally we expect nextchar == '"'
145  
-    if nextchar != '"':
146  
-        if nextchar in _ws:
147  
-            end = _w(s, end).end()
148  
-            nextchar = s[end:end + 1]
149  
-        # Trivial empty object
150  
-        if nextchar == '}':
151  
-            return pairs, end + 1
152  
-        elif nextchar != '"':
153  
-            raise ValueError(errmsg("Expecting property name", s, end))
154  
-    end += 1
155  
-    while True:
156  
-        key, end = scanstring(s, end, encoding, strict)
157  
-
158  
-        # To skip some function call overhead we optimize the fast paths where
159  
-        # the JSON key separator is ": " or just ":".
160  
-        if s[end:end + 1] != ':':
161  
-            end = _w(s, end).end()
162  
-            if s[end:end + 1] != ':':
163  
-                raise ValueError(errmsg("Expecting : delimiter", s, end))
164  
-
165  
-        end += 1
166  
-
167  
-        try:
168  
-            if s[end] in _ws:
169  
-                end += 1
170  
-                if s[end] in _ws:
171  
-                    end = _w(s, end + 1).end()
172  
-        except IndexError:
173  
-            pass
174  
-
175  
-        try:
176  
-            value, end = scan_once(s, end)
177  
-        except StopIteration:
178  
-            raise ValueError(errmsg("Expecting object", s, end))
179  
-        pairs[key] = value
180  
-
181  
-        try:
182  
-            nextchar = s[end]
183  
-            if nextchar in _ws:
184  
-                end = _w(s, end + 1).end()
185  
-                nextchar = s[end]
186  
-        except IndexError:
187  
-            nextchar = ''
188  
-        end += 1
189  
-
190  
-        if nextchar == '}':
191  
-            break
192  
-        elif nextchar != ',':
193  
-            raise ValueError(errmsg("Expecting , delimiter", s, end - 1))
194  
-
195  
-        try:
196  
-            nextchar = s[end]
197  
-            if nextchar in _ws:
198  
-                end += 1
199  
-                nextchar = s[end]
200  
-                if nextchar in _ws:
201  
-                    end = _w(s, end + 1).end()
202  
-                    nextchar = s[end]
203  
-        except IndexError:
204  
-            nextchar = ''
205  
-
206  
-        end += 1
207  
-        if nextchar != '"':
208  
-            raise ValueError(errmsg("Expecting property name", s, end - 1))
209  
-
210  
-    if object_hook is not None:
211  
-        pairs = object_hook(pairs)
212  
-    return pairs, end
213  
-
214  
-def JSONArray((s, end), scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
215  
-    values = []
216  
-    nextchar = s[end:end + 1]
217  
-    if nextchar in _ws:
218  
-        end = _w(s, end + 1).end()
219  
-        nextchar = s[end:end + 1]
220  
-    # Look-ahead for trivial empty array
221  
-    if nextchar == ']':
222  
-        return values, end + 1
223  
-    _append = values.append
224  
-    while True:
225  
-        try:
226  
-            value, end = scan_once(s, end)
227  
-        except StopIteration:
228  
-            raise ValueError(errmsg("Expecting object", s, end))
229  
-        _append(value)
230  
-        nextchar = s[end:end + 1]
231  
-        if nextchar in _ws:
232  
-            end = _w(s, end + 1).end()
233  
-            nextchar = s[end:end + 1]
234  
-        end += 1
235  
-        if nextchar == ']':
236  
-            break
237  
-        elif nextchar != ',':
238  
-            raise ValueError(errmsg("Expecting , delimiter", s, end))
239  
-
240  
-        try:
241  
-            if s[end] in _ws:
242  
-                end += 1
243  
-                if s[end] in _ws:
244  
-                    end = _w(s, end + 1).end()
245  
-        except IndexError:
246  
-            pass
247  
-
248  
-    return values, end
249  
-
250  
-class JSONDecoder(object):
251  
-    """Simple JSON <http://json.org> decoder
252  
-
253  
-    Performs the following translations in decoding by default:
254  
-
255  
-    +---------------+-------------------+
256  
-    | JSON          | Python            |
257  
-    +===============+===================+
258  
-    | object        | dict              |
259  
-    +---------------+-------------------+
260  
-    | array         | list              |
261  
-    +---------------+-------------------+
262  
-    | string        | unicode           |
263  
-    +---------------+-------------------+
264  
-    | number (int)  | int, long         |
265  
-    +---------------+-------------------+
266  
-    | number (real) | float             |
267  
-    +---------------+-------------------+
268  
-    | true          | True              |
269  
-    +---------------+-------------------+
270  
-    | false         | False             |
271  
-    +---------------+-------------------+
272  
-    | null          | None              |
273  
-    +---------------+-------------------+
274  
-
275  
-    It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as
276  
-    their corresponding ``float`` values, which is outside the JSON spec.
277  
-
278  
-    """
279  
-
280  
-    def __init__(self, encoding=None, object_hook=None, parse_float=None,
281  
-            parse_int=None, parse_constant=None, strict=True):
282  
-        """``encoding`` determines the encoding used to interpret any ``str``
283  
-        objects decoded by this instance (utf-8 by default).  It has no
284  
-        effect when decoding ``unicode`` objects.
285  
-
286  
-        Note that currently only encodings that are a superset of ASCII work,
287  
-        strings of other encodings should be passed in as ``unicode``.
288  
-
289  
-        ``object_hook``, if specified, will be called with the result
290  
-        of every JSON object decoded and its return value will be used in
291  
-        place of the given ``dict``.  This can be used to provide custom
292  
-        deserializations (e.g. to support JSON-RPC class hinting).
293  
-
294  
-        ``parse_float``, if specified, will be called with the string
295  
-        of every JSON float to be decoded. By default this is equivalent to
296  
-        float(num_str). This can be used to use another datatype or parser
297  
-        for JSON floats (e.g. decimal.Decimal).
298  
-
299  
-        ``parse_int``, if specified, will be called with the string
300  
-        of every JSON int to be decoded. By default this is equivalent to
301  
-        int(num_str). This can be used to use another datatype or parser
302  
-        for JSON integers (e.g. float).
303  
-
304  
-        ``parse_constant``, if specified, will be called with one of the
305  
-        following strings: -Infinity, Infinity, NaN.
306  
-        This can be used to raise an exception if invalid JSON numbers
307  
-        are encountered.
308  
-
309  
-        """
310  
-        self.encoding = encoding
311  
-        self.object_hook = object_hook
312  
-        self.parse_float = parse_float or float
313  
-        self.parse_int = parse_int or int
314  
-        self.parse_constant = parse_constant or _CONSTANTS.__getitem__
315  
-        self.strict = strict
316  
-        self.parse_object = JSONObject
317  
-        self.parse_array = JSONArray
318  
-        self.parse_string = scanstring
319  
-        self.scan_once = make_scanner(self)
320  
-
321  
-    def decode(self, s, _w=WHITESPACE.match):
322  
-        """Return the Python representation of ``s`` (a ``str`` or ``unicode``
323  
-        instance containing a JSON document)
324  
-
325  
-        """
326  
-        obj, end = self.raw_decode(s, idx=_w(s, 0).end())
327  
-        end = _w(s, end).end()
328  
-        if end != len(s):
329  
-            raise ValueError(errmsg("Extra data", s, end, len(s)))
330  
-        return obj
331  
-
332  
-    def raw_decode(self, s, idx=0):
333  
-        """Decode a JSON document from ``s`` (a ``str`` or ``unicode`` beginning
334  
-        with a JSON document) and return a 2-tuple of the Python
335  
-        representation and the index in ``s`` where the document ended.
336  
-
337  
-        This can be used to decode a JSON document from a string that may
338  
-        have extraneous data at the end.
339  
-
340  
-        """
341  
-        try:
342  
-            obj, end = self.scan_once(s, idx)
343  
-        except StopIteration:
344  
-            raise ValueError("No JSON object could be decoded")
345  
-        return obj, end
430  django/utils/simplejson/encoder.py
... ...
@@ -1,430 +0,0 @@
1  
-"""Implementation of JSONEncoder
2  
-"""
3  
-import re
4  
-
5  
-c_encode_basestring_ascii = None
6  
-c_make_encoder = None
7  
-
8  
-ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]')
9  
-ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
10  
-HAS_UTF8 = re.compile(r'[\x80-\xff]')
11  
-ESCAPE_DCT = {
12  
-    '\\': '\\\\',
13  
-    '"': '\\"',
14  
-    '\b': '\\b',
15  
-    '\f': '\\f',
16  
-    '\n': '\\n',
17  
-    '\r': '\\r',
18  
-    '\t': '\\t',
19  
-}
20  
-for i in range(0x20):
21  
-    ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,))
22  
-
23  
-# Assume this produces an infinity on all machines (probably not guaranteed)
24  
-INFINITY = float('1e66666')
25  
-FLOAT_REPR = repr
26  
-
27  
-def encode_basestring(s):
28  
-    """Return a JSON representation of a Python string
29  
-
30  
-    """
31  
-    def replace(match):
32  
-        return ESCAPE_DCT[match.group(0)]
33  
-    return '"' + ESCAPE.sub(replace, s) + '"'
34  
-
35  
-
36  
-def py_encode_basestring_ascii(s):
37  
-    """Return an ASCII-only JSON representation of a Python string
38  
-
39  
-    """
40  
-    if isinstance(s, str) and HAS_UTF8.search(s) is not None:
41  
-        s = s.decode('utf-8')
42  
-    def replace(match):
43  
-        s = match.group(0)
44  
-        try:
45  
-            return ESCAPE_DCT[s]
46  
-        except KeyError:
47  
-            n = ord(s)
48  
-            if n < 0x10000:
49  
-                return '\\u%04x' % (n,)
50  
-            else:
51  
-                # surrogate pair
52  
-                n -= 0x10000
53  
-                s1 = 0xd800 | ((n >> 10) & 0x3ff)
54  
-                s2 = 0xdc00 | (n & 0x3ff)
55  
-                return '\\u%04x\\u%04x' % (s1, s2)
56  
-    return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"'
57  
-
58  
-
59  
-encode_basestring_ascii = c_encode_basestring_ascii or py_encode_basestring_ascii
60  
-
61  
-class JSONEncoder(object):
62  
-    """Extensible JSON <http://json.org> encoder for Python data structures.
63  
-
64  
-    Supports the following objects and types by default:
65  
-
66  
-    +-------------------+---------------+
67  
-    | Python            | JSON          |
68  
-    +===================+===============+
69  
-    | dict              | object        |
70  
-    +-------------------+---------------+
71  
-    | list, tuple       | array         |
72  
-    +-------------------+---------------+
73  
-    | str, unicode      | string        |
74  
-    +-------------------+---------------+
75  
-    | int, long, float  | number        |
76  
-    +-------------------+---------------+
77  
-    | True              | true          |
78  
-    +-------------------+---------------+
79  
-    | False             | false         |
80  
-    +-------------------+---------------+
81  
-    | None              | null          |
82  
-    +-------------------+---------------+
83  
-
84  
-    To extend this to recognize other objects, subclass and implement a
85  
-    ``.default()`` method with another method that returns a serializable
86  
-    object for ``o`` if possible, otherwise it should call the superclass
87  
-    implementation (to raise ``TypeError``).
88  
-
89  
-    """
90  
-    item_separator = ', '
91  
-    key_separator = ': '
92  
-    def __init__(self, skipkeys=False, ensure_ascii=True,
93  
-            check_circular=True, allow_nan=True, sort_keys=False,
94  
-            indent=None, separators=None, encoding='utf-8', default=None):
95  
-        """Constructor for JSONEncoder, with sensible defaults.
96  
-
97  
-        If skipkeys is False, then it is a TypeError to attempt
98  
-        encoding of keys that are not str, int, long, float or None.  If
99  
-        skipkeys is True, such items are simply skipped.
100  
-
101  
-        If ensure_ascii is True, the output is guaranteed to be str
102  
-        objects with all incoming unicode characters escaped.  If
103  
-        ensure_ascii is false, the output will be unicode object.
104  
-
105  
-        If check_circular is True, then lists, dicts, and custom encoded
106  
-        objects will be checked for circular references during encoding to
107  
-        prevent an infinite recursion (which would cause an OverflowError).
108  
-        Otherwise, no such check takes place.
109  
-
110  
-        If allow_nan is True, then NaN, Infinity, and -Infinity will be
111  
-        encoded as such.  This behavior is not JSON specification compliant,
112  
-        but is consistent with most JavaScript based encoders and decoders.
113  
-        Otherwise, it will be a ValueError to encode such floats.
114  
-
115  
-        If sort_keys is True, then the output of dictionaries will be
116  
-        sorted by key; this is useful for regression tests to ensure
117  
-        that JSON serializations can be compared on a day-to-day basis.
118  
-
119  
-        If indent is a non-negative integer, then JSON array
120  
-        elements and object members will be pretty-printed with that
121  
-        indent level.  An indent level of 0 will only insert newlines.
122  
-        None is the most compact representation.
123  
-
124  
-        If specified, separators should be a (item_separator, key_separator)
125  
-        tuple.  The default is (', ', ': ').  To get the most compact JSON
126  
-        representation you should specify (',', ':') to eliminate whitespace.
127  
-
128  
-        If specified, default is a function that gets called for objects
129  
-        that can't otherwise be serialized.  It should return a JSON encodable
130  
-        version of the object or raise a ``TypeError``.
131  
-
132  
-        If encoding is not None, then all input strings will be
133  
-        transformed into unicode using that encoding prior to JSON-encoding.
134  
-        The default is UTF-8.
135  
-
136  
-        """
137  
-
138  
-        self.skipkeys = skipkeys
139  
-        self.ensure_ascii = ensure_ascii
140  
-        self.check_circular = check_circular
141  
-        self.allow_nan = allow_nan
142  
-        self.sort_keys = sort_keys
143  
-        self.indent = indent
144  
-        if separators is not None:
145  
-            self.item_separator, self.key_separator = separators
146  
-        if default is not None:
147  
-            self.default = default
148  
-        self.encoding = encoding
149  
-
150  
-    def default(self, o):
151  
-        """Implement this method in a subclass such that it returns
152  
-        a serializable object for ``o``, or calls the base implementation
153  
-        (to raise a ``TypeError``).
154  
-
155  
-        For example, to support arbitrary iterators, you could
156  
-        implement default like this::
157  
-
158  
-            def default(self, o):
159  
-                try:
160  
-                    iterable = iter(o)
161  
-                except TypeError:
162  
-                    pass
163  
-                else:
164  
-                    return list(iterable)
165  
-                return JSONEncoder.default(self, o)
166  
-
167  
-        """
168  
-        raise TypeError("%r is not JSON serializable" % (o,))
169  
-
170  
-    def encode(self, o):
171  
-        """Return a JSON string representation of a Python data structure.
172  
-
173  
-        >>> JSONEncoder().encode({"foo": ["bar", "baz"]})
174  
-        '{"foo": ["bar", "baz"]}'
175  
-
176  
-        """
177  
-        # This is for extremely simple cases and benchmarks.
178  
-        if isinstance(o, basestring):
179  
-            if isinstance(o, str):
180  
-                _encoding = self.encoding
181  
-                if (_encoding is not None
182  
-                        and not (_encoding == 'utf-8')):
183  
-                    o = o.decode(_encoding)