summaryrefslogtreecommitdiff
path: root/simplejson/decoder.py
diff options
context:
space:
mode:
authorBob Ippolito <bob@redivi.com>2009-03-29 21:38:28 +0000
committerBob Ippolito <bob@redivi.com>2009-03-29 21:38:28 +0000
commit2e0050046dc4c35508758669ec02b5f8c8b091cf (patch)
tree01e8e8d8c1d63b211c106d7a7e02c717d0eb191d /simplejson/decoder.py
parent0d9f46d682a4af5fff44c1d3b01fe2ff00599ec3 (diff)
downloadsimplejson-2e0050046dc4c35508758669ec02b5f8c8b091cf.tar.gz
http://bugs.python.org/issue5381 ordered_pairs_hook backport to simplejson
git-svn-id: http://simplejson.googlecode.com/svn/trunk@178 a4795897-2c25-0410-b006-0d3caba88fa1
Diffstat (limited to 'simplejson/decoder.py')
-rw-r--r--simplejson/decoder.py71
1 files changed, 46 insertions, 25 deletions
diff --git a/simplejson/decoder.py b/simplejson/decoder.py
index 90188a5..0b10560 100644
--- a/simplejson/decoder.py
+++ b/simplejson/decoder.py
@@ -149,8 +149,8 @@ WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS)
WHITESPACE_STR = ' \t\n\r'
def JSONObject((s, end), encoding, strict, scan_once, object_hook,
- _w=WHITESPACE.match, _ws=WHITESPACE_STR):
- pairs = {}
+ object_pairs_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
+ pairs = []
# Use a slice to prevent IndexError from being raised, the following
# check will raise a more specific ValueError if the string is empty
nextchar = s[end:end + 1]
@@ -189,7 +189,7 @@ def JSONObject((s, end), encoding, strict, scan_once, object_hook,
value, end = scan_once(s, end)
except StopIteration:
raise ValueError(errmsg("Expecting object", s, end))
- pairs[key] = value
+ pairs.append((key, value))
try:
nextchar = s[end]
@@ -220,6 +220,10 @@ def JSONObject((s, end), encoding, strict, scan_once, object_hook,
if nextchar != '"':
raise ValueError(errmsg("Expecting property name", s, end - 1))
+ if object_pairs_hook is not None:
+ result = object_pairs_hook(pairs)
+ return result, end
+ pairs = dict(pairs)
if object_hook is not None:
pairs = object_hook(pairs)
return pairs, end
@@ -291,37 +295,54 @@ class JSONDecoder(object):
"""
def __init__(self, encoding=None, object_hook=None, parse_float=None,
- parse_int=None, parse_constant=None, strict=True):
- """``encoding`` determines the encoding used to interpret any ``str``
- objects decoded by this instance (utf-8 by default). It has no
- effect when decoding ``unicode`` objects.
+ parse_int=None, parse_constant=None, strict=True,
+ object_pairs_hook=None):
+ """
+ *encoding* determines the encoding used to interpret any
+ :class:`str` objects decoded by this instance (``'utf-8'`` by
+ default). It has no effect when decoding :class:`unicode` objects.
Note that currently only encodings that are a superset of ASCII work,
- strings of other encodings should be passed in as ``unicode``.
+ strings of other encodings should be passed in as :class:`unicode`.
- ``object_hook``, if specified, will be called with the result
- of every JSON object decoded and its return value will be used in
- place of the given ``dict``. This can be used to provide custom
+ *object_hook*, if specified, will be called with the result of every
+ JSON object decoded and its return value will be used in place of the
+ given :class:`dict`. This can be used to provide custom
deserializations (e.g. to support JSON-RPC class hinting).
- ``parse_float``, if specified, will be called with the string
- of every JSON float to be decoded. By default this is equivalent to
- float(num_str). This can be used to use another datatype or parser
- for JSON floats (e.g. decimal.Decimal).
-
- ``parse_int``, if specified, will be called with the string
- of every JSON int to be decoded. By default this is equivalent to
- int(num_str). This can be used to use another datatype or parser
- for JSON integers (e.g. float).
-
- ``parse_constant``, if specified, will be called with one of the
- following strings: -Infinity, Infinity, NaN.
- This can be used to raise an exception if invalid JSON numbers
- are encountered.
+ *object_pairs_hook* is an optional function that will be called with
+ the result of any object literal decode with an ordered list of pairs.
+ The return value of *object_pairs_hook* will be used instead of the
+ :class:`dict`. This feature can be used to implement custom decoders
+ that rely on the order that the key and value pairs are decoded (for
+ example, :func:`collections.OrderedDict` will remember the order of
+ insertion). If *object_hook* is also defined, the *object_pairs_hook*
+ takes priority.
+
+ *parse_float*, if specified, will be called with the string of every
+ JSON float to be decoded. By default, this is equivalent to
+ ``float(num_str)``. This can be used to use another datatype or parser
+ for JSON floats (e.g. :class:`decimal.Decimal`).
+
+ *parse_int*, if specified, will be called with the string of every
+ JSON int to be decoded. By default, this is equivalent to
+ ``int(num_str)``. This can be used to use another datatype or parser
+ for JSON integers (e.g. :class:`float`).
+
+ *parse_constant*, if specified, will be called with one of the
+ following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``. This
+ can be used to raise an exception if invalid JSON numbers are
+ encountered.
+
+ *strict* controls the parser's behavior when it encounters an
+ invalid control character in a string. The default setting of
+ ``True`` means that unescaped control characters are parse errors, if
+ ``False`` then control characters will be allowed in strings.
"""
self.encoding = encoding
self.object_hook = object_hook
+ self.object_pairs_hook = object_pairs_hook
self.parse_float = parse_float or float
self.parse_int = parse_int or int
self.parse_constant = parse_constant or _CONSTANTS.__getitem__