Ticket #18023: remove_simplejson.diff

File remove_simplejson.diff, 48.3 KB (added by Alex Ogier, 12 years ago)
  • deleted file django/utils/simplejson/LICENSE.txt

    diff --git a/django/utils/simplejson/LICENSE.txt b/django/utils/simplejson/LICENSE.txt
    deleted file mode 100644
    index ad95f29..0000000
    + -  
    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.
  • django/utils/simplejson/__init__.py

    diff --git a/django/utils/simplejson/__init__.py b/django/utils/simplejson/__init__.py
    index a9418da..ea45572 100644
    a b  
    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.
     1import warnings
    42
    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.
     3warnings.warn(
     4    "The 'django.utils.simplejson' module is deprecated, "
     5    "use 'json' from the standard library instead; "
     6    "please see the Django 1.5 release notes "
     7    "(https://docs.djangoproject.com/en/dev/releases/1.5/).",
     8    PendingDeprecationWarning)
    119
    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
     10# Try to use the system simplejson first. If that fails, use python's standard
     11# json module.
    10812try:
    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__
     13    # This file must reside at simplejson/__init__.py or else these lines
     14    # can cause a circular self-import.
     15    from simplejson import *
     16    from simplejson import __version__
    11817except ImportError:
    119     pass
     18    from json import *
     19    from json import __version__
    12020
    121 if not use_system_version:
    12221    try:
    123         from json import *      # Python 2.6 preferred over local copy.
    124 
    12522        # There is a "json" package around that is not Python's "json", so we
    12623        # check for something that is only in the namespace of the version we
    12724        # want.
    12825        JSONDecoder
    129 
    130         use_system_version = True
    131         # Make sure we copy over the version. See #17071
    132         __version__ = json.__version__
    133     except (ImportError, NameError):
    134         pass
    135 
    136 # If all else fails, we have a bundled version that can be used.
    137 if not use_system_version:
    138     __all__ = [
    139         'dump', 'dumps', 'load', 'loads',
    140         'JSONDecoder', 'JSONEncoder',
    141     ]
    142 
    143     from django.utils.simplejson.decoder import JSONDecoder
    144     from django.utils.simplejson.encoder import JSONEncoder
    145 
    146     _default_encoder = JSONEncoder(
    147         skipkeys=False,
    148         ensure_ascii=True,
    149         check_circular=True,
    150         allow_nan=True,
    151         indent=None,
    152         separators=None,
    153         encoding='utf-8',
    154         default=None,
    155     )
    156 
    157     def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
    158             allow_nan=True, cls=None, indent=None, separators=None,
    159             encoding='utf-8', default=None, **kw):
    160         """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
    161         ``.write()``-supporting file-like object).
    162 
    163         If ``skipkeys`` is ``True`` then ``dict`` keys that are not basic types
    164         (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
    165         will be skipped instead of raising a ``TypeError``.
    166 
    167         If ``ensure_ascii`` is ``False``, then the some chunks written to ``fp``
    168         may be ``unicode`` instances, subject to normal Python ``str`` to
    169         ``unicode`` coercion rules. Unless ``fp.write()`` explicitly
    170         understands ``unicode`` (as in ``codecs.getwriter()``) this is likely
    171         to cause an error.
    172 
    173         If ``check_circular`` is ``False``, then the circular reference check
    174         for container types will be skipped and a circular reference will
    175         result in an ``OverflowError`` (or worse).
    176 
    177         If ``allow_nan`` is ``False``, then it will be a ``ValueError`` to
    178         serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
    179         in strict compliance of the JSON specification, instead of using the
    180         JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
    181 
    182         If ``indent`` is a non-negative integer, then JSON array elements and object
    183         members will be pretty-printed with that indent level. An indent level
    184         of 0 will only insert newlines. ``None`` is the most compact representation.
    185 
    186         If ``separators`` is an ``(item_separator, dict_separator)`` tuple
    187         then it will be used instead of the default ``(', ', ': ')`` separators.
    188         ``(',', ':')`` is the most compact JSON representation.
    189 
    190         ``encoding`` is the character encoding for str instances, default is UTF-8.
    191 
    192         ``default(obj)`` is a function that should return a serializable version
    193         of obj or raise TypeError. The default simply raises TypeError.
    194 
    195         To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
    196         ``.default()`` method to serialize additional types), specify it with
    197         the ``cls`` kwarg.
    198 
    199         """
    200         # cached encoder
    201         if (skipkeys is False and ensure_ascii is True and
    202             check_circular is True and allow_nan is True and
    203             cls is None and indent is None and separators is None and
    204             encoding == 'utf-8' and default is None and not kw):
    205             iterable = _default_encoder.iterencode(obj)
    206         else:
    207             if cls is None:
    208                 cls = JSONEncoder
    209             iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
    210                 check_circular=check_circular, allow_nan=allow_nan, indent=indent,
    211                 separators=separators, encoding=encoding,
    212                 default=default, **kw).iterencode(obj)
    213         # could accelerate with writelines in some versions of Python, at
    214         # a debuggability cost
    215         for chunk in iterable:
    216             fp.write(chunk)
    217 
    218 
    219     def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
    220             allow_nan=True, cls=None, indent=None, separators=None,
    221             encoding='utf-8', default=None, **kw):
    222         """Serialize ``obj`` to a JSON formatted ``str``.
    223 
    224         If ``skipkeys`` is ``True`` then ``dict`` keys that are not basic types
    225         (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
    226         will be skipped instead of raising a ``TypeError``.
    227 
    228         If ``ensure_ascii`` is ``False``, then the return value will be a
    229         ``unicode`` instance subject to normal Python ``str`` to ``unicode``
    230         coercion rules instead of being escaped to an ASCII ``str``.
    231 
    232         If ``check_circular`` is ``False``, then the circular reference check
    233         for container types will be skipped and a circular reference will
    234         result in an ``OverflowError`` (or worse).
    235 
    236         If ``allow_nan`` is ``False``, then it will be a ``ValueError`` to
    237         serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
    238         strict compliance of the JSON specification, instead of using the
    239         JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
    240 
    241         If ``indent`` is a non-negative integer, then JSON array elements and
    242         object members will be pretty-printed with that indent level. An indent
    243         level of 0 will only insert newlines. ``None`` is the most compact
    244         representation.
    245 
    246         If ``separators`` is an ``(item_separator, dict_separator)`` tuple
    247         then it will be used instead of the default ``(', ', ': ')`` separators.
    248         ``(',', ':')`` is the most compact JSON representation.
    249 
    250         ``encoding`` is the character encoding for str instances, default is UTF-8.
    251 
    252         ``default(obj)`` is a function that should return a serializable version
    253         of obj or raise TypeError. The default simply raises TypeError.
    254 
    255         To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
    256         ``.default()`` method to serialize additional types), specify it with
    257         the ``cls`` kwarg.
    258 
    259         """
    260         # cached encoder
    261         if (skipkeys is False and ensure_ascii is True and
    262             check_circular is True and allow_nan is True and
    263             cls is None and indent is None and separators is None and
    264             encoding == 'utf-8' and default is None and not kw):
    265             return _default_encoder.encode(obj)
    266         if cls is None:
    267             cls = JSONEncoder
    268         return cls(
    269             skipkeys=skipkeys, ensure_ascii=ensure_ascii,
    270             check_circular=check_circular, allow_nan=allow_nan, indent=indent,
    271             separators=separators, encoding=encoding, default=default,
    272             **kw).encode(obj)
    273 
    274 
    275     _default_decoder = JSONDecoder(encoding=None, object_hook=None)
    276 
    277 
    278     def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
    279             parse_int=None, parse_constant=None, **kw):
    280         """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
    281         a JSON document) to a Python object.
    282 
    283         If the contents of ``fp`` is encoded with an ASCII based encoding other
    284         than utf-8 (e.g. latin-1), then an appropriate ``encoding`` name must
    285         be specified. Encodings that are not ASCII based (such as UCS-2) are
    286         not allowed, and should be wrapped with
    287         ``codecs.getreader(fp)(encoding)``, or simply decoded to a ``unicode``
    288         object and passed to ``loads()``
    289 
    290         ``object_hook`` is an optional function that will be called with the
    291         result of any object literal decode (a ``dict``). The return value of
    292         ``object_hook`` will be used instead of the ``dict``. This feature
    293         can be used to implement custom decoders (e.g. JSON-RPC class hinting).
    294 
    295         To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
    296         kwarg.
    297 
    298         """
    299         return loads(fp.read(),
    300             encoding=encoding, cls=cls, object_hook=object_hook,
    301             parse_float=parse_float, parse_int=parse_int,
    302             parse_constant=parse_constant, **kw)
    303 
    304 
    305     def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
    306             parse_int=None, parse_constant=None, **kw):
    307         """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON
    308         document) to a Python object.
    309 
    310         If ``s`` is a ``str`` instance and is encoded with an ASCII based encoding
    311         other than utf-8 (e.g. latin-1) then an appropriate ``encoding`` name
    312         must be specified. Encodings that are not ASCII based (such as UCS-2)
    313         are not allowed and should be decoded to ``unicode`` first.
    314 
    315         ``object_hook`` is an optional function that will be called with the
    316         result of any object literal decode (a ``dict``). The return value of
    317         ``object_hook`` will be used instead of the ``dict``. This feature
    318         can be used to implement custom decoders (e.g. JSON-RPC class hinting).
    319 
    320         ``parse_float``, if specified, will be called with the string
    321         of every JSON float to be decoded. By default this is equivalent to
    322         float(num_str). This can be used to use another datatype or parser
    323         for JSON floats (e.g. decimal.Decimal).
    324 
    325         ``parse_int``, if specified, will be called with the string
    326         of every JSON int to be decoded. By default this is equivalent to
    327         int(num_str). This can be used to use another datatype or parser
    328         for JSON integers (e.g. float).
    329 
    330         ``parse_constant``, if specified, will be called with one of the
    331         following strings: -Infinity, Infinity, NaN, null, true, false.
    332         This can be used to raise an exception if invalid JSON numbers
    333         are encountered.
    334 
    335         To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
    336         kwarg.
    337 
    338         """
    339         if (cls is None and encoding is None and object_hook is None and
    340                 parse_int is None and parse_float is None and
    341                 parse_constant is None and not kw):
    342             return _default_decoder.decode(s)
    343         if cls is None:
    344             cls = JSONDecoder
    345         if object_hook is not None:
    346             kw['object_hook'] = object_hook
    347         if parse_float is not None:
    348             kw['parse_float'] = parse_float
    349         if parse_int is not None:
    350             kw['parse_int'] = parse_int
    351         if parse_constant is not None:
    352             kw['parse_constant'] = parse_constant
    353         return cls(encoding=encoding, **kw).decode(s)
     26    except NameError:
     27        raise ImportError("Module 'json' is not from python's standard library")
  • deleted file django/utils/simplejson/decoder.py

    diff --git a/django/utils/simplejson/decoder.py b/django/utils/simplejson/decoder.py
    deleted file mode 100644
    index 5a845cc..0000000
    + -  
    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
  • deleted file django/utils/simplejson/encoder.py

    diff --git a/django/utils/simplejson/encoder.py b/django/utils/simplejson/encoder.py
    deleted file mode 100644
    index 06ebe62..0000000
    + -  
    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)
    184             if self.ensure_ascii:
    185                 return encode_basestring_ascii(o)
    186             else:
    187                 return encode_basestring(o)
    188         # This doesn't pass the iterator directly to ''.join() because the
    189         # exceptions aren't as detailed.  The list call should be roughly
    190         # equivalent to the PySequence_Fast that ''.join() would do.
    191         chunks = self.iterencode(o, _one_shot=True)
    192         if not isinstance(chunks, (list, tuple)):
    193             chunks = list(chunks)
    194         return ''.join(chunks)
    195 
    196     def iterencode(self, o, _one_shot=False):
    197         """Encode the given object and yield each string
    198         representation as available.
    199 
    200         For example::
    201 
    202             for chunk in JSONEncoder().iterencode(bigobject):
    203                 mysocket.write(chunk)
    204 
    205         """
    206         if self.check_circular:
    207             markers = {}
    208         else:
    209             markers = None
    210         if self.ensure_ascii:
    211             _encoder = encode_basestring_ascii
    212         else:
    213             _encoder = encode_basestring
    214         if self.encoding != 'utf-8':
    215             def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding):
    216                 if isinstance(o, str):
    217                     o = o.decode(_encoding)
    218                 return _orig_encoder(o)
    219 
    220         def floatstr(o, allow_nan=self.allow_nan, _repr=FLOAT_REPR, _inf=INFINITY, _neginf=-INFINITY):
    221             # Check for specials.  Note that this type of test is processor- and/or
    222             # platform-specific, so do tests which don't depend on the internals.
    223 
    224             if o != o:
    225                 text = 'NaN'
    226             elif o == _inf:
    227                 text = 'Infinity'
    228             elif o == _neginf:
    229                 text = '-Infinity'
    230             else:
    231                 return _repr(o)
    232 
    233             if not allow_nan:
    234                 raise ValueError("Out of range float values are not JSON compliant: %r"
    235                     % (o,))
    236 
    237             return text
    238 
    239 
    240         if _one_shot and c_make_encoder is not None and not self.indent and not self.sort_keys:
    241             _iterencode = c_make_encoder(
    242                 markers, self.default, _encoder, self.indent,
    243                 self.key_separator, self.item_separator, self.sort_keys,
    244                 self.skipkeys, self.allow_nan)
    245         else:
    246             _iterencode = _make_iterencode(
    247                 markers, self.default, _encoder, self.indent, floatstr,
    248                 self.key_separator, self.item_separator, self.sort_keys,
    249                 self.skipkeys, _one_shot)
    250         return _iterencode(o, 0)
    251 
    252 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
    253         ## HACK: hand-optimized bytecode; turn globals into locals
    254         False=False,
    255         True=True,
    256         ValueError=ValueError,
    257         basestring=basestring,
    258         dict=dict,
    259         float=float,
    260         id=id,
    261         int=int,
    262         isinstance=isinstance,
    263         list=list,
    264         long=long,
    265         str=str,
    266         tuple=tuple,
    267     ):
    268 
    269     def _iterencode_list(lst, _current_indent_level):
    270         if not lst:
    271             yield '[]'
    272             return
    273         if markers is not None:
    274             markerid = id(lst)
    275             if markerid in markers:
    276                 raise ValueError("Circular reference detected")
    277             markers[markerid] = lst
    278         buf = '['
    279         if _indent is not None:
    280             _current_indent_level += 1
    281             newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
    282             separator = _item_separator + newline_indent
    283             buf += newline_indent
    284         else:
    285             newline_indent = None
    286             separator = _item_separator
    287         first = True
    288         for value in lst:
    289             if first:
    290                 first = False
    291             else:
    292                 buf = separator
    293             if isinstance(value, basestring):
    294                 yield buf + _encoder(value)
    295             elif value is None:
    296                 yield buf + 'null'
    297             elif value is True:
    298                 yield buf + 'true'
    299             elif value is False:
    300                 yield buf + 'false'
    301             elif isinstance(value, (int, long)):
    302                 yield buf + str(value)
    303             elif isinstance(value, float):
    304                 yield buf + _floatstr(value)
    305             else:
    306                 yield buf
    307                 if isinstance(value, (list, tuple)):
    308                     chunks = _iterencode_list(value, _current_indent_level)
    309                 elif isinstance(value, dict):
    310                     chunks = _iterencode_dict(value, _current_indent_level)
    311                 else:
    312                     chunks = _iterencode(value, _current_indent_level)
    313                 for chunk in chunks:
    314                     yield chunk
    315         if newline_indent is not None:
    316             _current_indent_level -= 1
    317             yield '\n' + (' ' * (_indent * _current_indent_level))
    318         yield ']'
    319         if markers is not None:
    320             del markers[markerid]
    321 
    322     def _iterencode_dict(dct, _current_indent_level):
    323         if not dct:
    324             yield '{}'
    325             return
    326         if markers is not None:
    327             markerid = id(dct)
    328             if markerid in markers:
    329                 raise ValueError("Circular reference detected")
    330             markers[markerid] = dct
    331         yield '{'
    332         if _indent is not None:
    333             _current_indent_level += 1
    334             newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
    335             item_separator = _item_separator + newline_indent
    336             yield newline_indent
    337         else:
    338             newline_indent = None
    339             item_separator = _item_separator
    340         first = True
    341         if _sort_keys:
    342             items = dct.items()
    343             items.sort(key=lambda kv: kv[0])
    344         else:
    345             items = dct.iteritems()
    346         for key, value in items:
    347             if isinstance(key, basestring):
    348                 pass
    349             # JavaScript is weakly typed for these, so it makes sense to
    350             # also allow them.  Many encoders seem to do something like this.
    351             elif isinstance(key, float):
    352                 key = _floatstr(key)
    353             elif isinstance(key, (int, long)):
    354                 key = str(key)
    355             elif key is True:
    356                 key = 'true'
    357             elif key is False:
    358                 key = 'false'
    359             elif key is None:
    360                 key = 'null'
    361             elif _skipkeys:
    362                 continue
    363             else:
    364                 raise TypeError("key %r is not a string" % (key,))
    365             if first:
    366                 first = False
    367             else:
    368                 yield item_separator
    369             yield _encoder(key)
    370             yield _key_separator
    371             if isinstance(value, basestring):
    372                 yield _encoder(value)
    373             elif value is None:
    374                 yield 'null'
    375             elif value is True:
    376                 yield 'true'
    377             elif value is False:
    378                 yield 'false'
    379             elif isinstance(value, (int, long)):
    380                 yield str(value)
    381             elif isinstance(value, float):
    382                 yield _floatstr(value)
    383             else:
    384                 if isinstance(value, (list, tuple)):
    385                     chunks = _iterencode_list(value, _current_indent_level)
    386                 elif isinstance(value, dict):
    387                     chunks = _iterencode_dict(value, _current_indent_level)
    388                 else:
    389                     chunks = _iterencode(value, _current_indent_level)
    390                 for chunk in chunks:
    391                     yield chunk
    392         if newline_indent is not None:
    393             _current_indent_level -= 1
    394             yield '\n' + (' ' * (_indent * _current_indent_level))
    395         yield '}'
    396         if markers is not None:
    397             del markers[markerid]
    398 
    399     def _iterencode(o, _current_indent_level):
    400         if isinstance(o, basestring):
    401             yield _encoder(o)
    402         elif o is None:
    403             yield 'null'
    404         elif o is True:
    405             yield 'true'
    406         elif o is False:
    407             yield 'false'
    408         elif isinstance(o, (int, long)):
    409             yield str(o)
    410         elif isinstance(o, float):
    411             yield _floatstr(o)
    412         elif isinstance(o, (list, tuple)):
    413             for chunk in _iterencode_list(o, _current_indent_level):
    414                 yield chunk
    415         elif isinstance(o, dict):
    416             for chunk in _iterencode_dict(o, _current_indent_level):
    417                 yield chunk
    418         else:
    419             if markers is not None:
    420                 markerid = id(o)
    421                 if markerid in markers:
    422                     raise ValueError("Circular reference detected")
    423                 markers[markerid] = o
    424             o = _default(o)
    425             for chunk in _iterencode(o, _current_indent_level):
    426                 yield chunk
    427             if markers is not None:
    428                 del markers[markerid]
    429 
    430     return _iterencode
  • deleted file django/utils/simplejson/scanner.py

    diff --git a/django/utils/simplejson/scanner.py b/django/utils/simplejson/scanner.py
    deleted file mode 100644
    index adbc6ec..0000000
    + -  
    1 """JSON token scanner
    2 """
    3 import re
    4 try:
    5     from simplejson._speedups import make_scanner as c_make_scanner
    6 except ImportError:
    7     c_make_scanner = None
    8 
    9 __all__ = ['make_scanner']
    10 
    11 NUMBER_RE = re.compile(
    12     r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',
    13     (re.VERBOSE | re.MULTILINE | re.DOTALL))
    14 
    15 def py_make_scanner(context):
    16     parse_object = context.parse_object
    17     parse_array = context.parse_array
    18     parse_string = context.parse_string
    19     match_number = NUMBER_RE.match
    20     encoding = context.encoding
    21     strict = context.strict
    22     parse_float = context.parse_float
    23     parse_int = context.parse_int
    24     parse_constant = context.parse_constant
    25     object_hook = context.object_hook
    26 
    27     def _scan_once(string, idx):
    28         try:
    29             nextchar = string[idx]
    30         except IndexError:
    31             raise StopIteration
    32 
    33         if nextchar == '"':
    34             return parse_string(string, idx + 1, encoding, strict)
    35         elif nextchar == '{':
    36             return parse_object((string, idx + 1), encoding, strict, _scan_once, object_hook)
    37         elif nextchar == '[':
    38             return parse_array((string, idx + 1), _scan_once)
    39         elif nextchar == 'n' and string[idx:idx + 4] == 'null':
    40             return None, idx + 4
    41         elif nextchar == 't' and string[idx:idx + 4] == 'true':
    42             return True, idx + 4
    43         elif nextchar == 'f' and string[idx:idx + 5] == 'false':
    44             return False, idx + 5
    45 
    46         m = match_number(string, idx)
    47         if m is not None:
    48             integer, frac, exp = m.groups()
    49             if frac or exp:
    50                 res = parse_float(integer + (frac or '') + (exp or ''))
    51             else:
    52                 res = parse_int(integer)
    53             return res, m.end()
    54         elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
    55             return parse_constant('NaN'), idx + 3
    56         elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
    57             return parse_constant('Infinity'), idx + 8
    58         elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
    59             return parse_constant('-Infinity'), idx + 9
    60         else:
    61             raise StopIteration
    62 
    63     return _scan_once
    64 
    65 make_scanner = c_make_scanner or py_make_scanner
  • deleted file django/utils/simplejson/tool.py

    diff --git a/django/utils/simplejson/tool.py b/django/utils/simplejson/tool.py
    deleted file mode 100644
    index 74401c2..0000000
    + -  
    1 r"""Using simplejson from the shell to validate and
    2 pretty-print::
    3 
    4     $ echo '{"json":"obj"}' | python -msimplejson.tool
    5     {
    6         "json": "obj"
    7     }
    8     $ echo '{ 1.2:3.4}' | python -msimplejson.tool
    9     Expecting property name: line 1 column 2 (char 2)
    10 """
    11 from django.utils import simplejson
    12 
    13 def main():
    14     import sys
    15     if len(sys.argv) == 1:
    16         infile = sys.stdin
    17         outfile = sys.stdout
    18     elif len(sys.argv) == 2:
    19         infile = open(sys.argv[1], 'rb')
    20         outfile = sys.stdout
    21     elif len(sys.argv) == 3:
    22         infile = open(sys.argv[1], 'rb')
    23         outfile = open(sys.argv[2], 'wb')
    24     else:
    25         raise SystemExit("%s [infile [outfile]]" % (sys.argv[0],))
    26     try:
    27         obj = simplejson.load(infile)
    28     except ValueError, e:
    29         raise SystemExit(e)
    30     simplejson.dump(obj, outfile, sort_keys=True, indent=4)
    31     outfile.write('\n')
    32 
    33 
    34 if __name__ == '__main__':
    35     main()
Back to Top