diff options
author | Bob Ippolito <bob@redivi.com> | 2006-07-15 04:07:17 +0000 |
---|---|---|
committer | Bob Ippolito <bob@redivi.com> | 2006-07-15 04:07:17 +0000 |
commit | 4f4ffa4cf8b8cefb4edaac2430e0dae7b00c7d02 (patch) | |
tree | 83bdec0543076c4b8af435ccfb652a21f5160acc | |
parent | f92ad76613d9bac57047c8096b5dccc1670d9720 (diff) | |
download | simplejson-4f4ffa4cf8b8cefb4edaac2430e0dae7b00c7d02.tar.gz |
indent feature
git-svn-id: http://simplejson.googlecode.com/svn/trunk@29 a4795897-2c25-0410-b006-0d3caba88fa1
-rw-r--r-- | setup.cfg | 4 | ||||
-rw-r--r-- | setup.py | 2 | ||||
-rw-r--r-- | simplejson/__init__.py | 18 | ||||
-rw-r--r-- | simplejson/encoder.py | 32 | ||||
-rw-r--r-- | simplejson/tests/test_indent.py | 18 |
5 files changed, 59 insertions, 15 deletions
@@ -1,3 +1,3 @@ [egg_info] -#tag_build = dev -#tag_svn_revision = true +tag_build = dev +tag_svn_revision = true @@ -5,7 +5,7 @@ ez_setup.use_setuptools() from setuptools import setup, find_packages -VERSION = '1.3' +VERSION = '1.4' DESCRIPTION = "Simple, fast, extensible JSON encoder/decoder for Python" LONG_DESCRIPTION = """ simplejson is a simple, fast, complete, correct and extensible diff --git a/simplejson/__init__.py b/simplejson/__init__.py index 437e553..150cad7 100644 --- a/simplejson/__init__.py +++ b/simplejson/__init__.py @@ -71,7 +71,7 @@ Extending JSONEncoder:: Note that the JSON produced by this module is a subset of YAML, so it may be used as a serializer for that as well. """ -__version__ = '1.3' +__version__ = '1.4' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONEncoder', @@ -81,7 +81,7 @@ from decoder import JSONDecoder from encoder import JSONEncoder def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, - allow_nan=True, cls=None, **kw): + allow_nan=True, cls=None, indent=None, **kw): """ Serialize ``obj`` as a JSON formatted stream to ``fp`` (a ``.write()``-supporting file-like object). @@ -105,6 +105,10 @@ def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). + If ``indent`` is a non-negative integer, then JSON array elements and object + members will be pretty-printed with that indent level. An indent level + of 0 will only insert newlines. ``None`` is the most compact representation. + To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg. @@ -112,7 +116,7 @@ def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, if cls is None: cls = JSONEncoder iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, - check_circular=check_circular, allow_nan=allow_nan, + check_circular=check_circular, allow_nan=allow_nan, indent=indent, **kw).iterencode(obj) # could accelerate with writelines in some versions of Python, at # a debuggability cost @@ -120,7 +124,7 @@ def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, fp.write(chunk) def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, - allow_nan=True, cls=None, **kw): + allow_nan=True, cls=None, indent=None, **kw): """ Serialize ``obj`` to a JSON formatted ``str``. @@ -141,6 +145,10 @@ def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). + If ``indent`` is a non-negative integer, then JSON array elements and object + members will be pretty-printed with that indent level. An indent level + of 0 will only insert newlines. ``None`` is the most compact representation. + To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg. @@ -148,7 +156,7 @@ def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, if cls is None: cls = JSONEncoder return cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, - check_circular=check_circular, allow_nan=allow_nan, **kw).encode(obj) + check_circular=check_circular, allow_nan=allow_nan, indent=indent, **kw).encode(obj) def load(fp, encoding=None, cls=None, object_hook=None, **kw): """ diff --git a/simplejson/encoder.py b/simplejson/encoder.py index b694e11..9e76992 100644 --- a/simplejson/encoder.py +++ b/simplejson/encoder.py @@ -91,7 +91,7 @@ class JSONEncoder(object): """ __all__ = ['__init__', 'default', 'encode', 'iterencode'] def __init__(self, skipkeys=False, ensure_ascii=True, - check_circular=True, allow_nan=True, sort_keys=False): + check_circular=True, allow_nan=True, sort_keys=False, indent=None): """ Constructor for JSONEncoder, with sensible defaults. @@ -116,6 +116,11 @@ class JSONEncoder(object): If sort_keys is True, then the output of dictionaries will be sorted by key; this is useful for regression tests to ensure that JSON serializations can be compared on a day-to-day basis. + + If ``indent`` is a non-negative integer, then JSON array + elements and object members will be pretty-printed with that + indent level. An indent level of 0 will only insert newlines. + ``None`` is the most compact representation. """ self.skipkeys = skipkeys @@ -123,6 +128,13 @@ class JSONEncoder(object): self.check_circular = check_circular self.allow_nan = allow_nan self.sort_keys = sort_keys + self.indent = indent + self.current_indent_level = 0 + + def _newline_indent(self): + if self.indent is None: + return '' + return '\n' + (' ' * (self.indent * self.current_indent_level)) def _iterencode_list(self, lst, markers=None): if not lst: @@ -133,16 +145,19 @@ class JSONEncoder(object): if markerid in markers: raise ValueError("Circular reference detected") markers[markerid] = lst - yield '[' + self.current_indent_level += 1 + newline_indent = self._newline_indent() + yield '[' + newline_indent first = True for value in lst: if first: first = False else: - yield ', ' + yield ', ' + newline_indent for chunk in self._iterencode(value, markers): yield chunk - yield ']' + self.current_indent_level -= 1 + yield self._newline_indent() + ']' if markers is not None: del markers[markerid] @@ -155,7 +170,9 @@ class JSONEncoder(object): if markerid in markers: raise ValueError("Circular reference detected") markers[markerid] = dct - yield '{' + self.current_indent_level += 1 + newline_indent = self._newline_indent() + yield '{' + newline_indent first = True if self.ensure_ascii: encoder = encode_basestring_ascii @@ -190,12 +207,13 @@ class JSONEncoder(object): if first: first = False else: - yield ', ' + yield ', ' + newline_indent yield encoder(key) yield ': ' for chunk in self._iterencode(value, markers): yield chunk - yield '}' + self.current_indent_level -= 1 + yield self._newline_indent() + '}' if markers is not None: del markers[markerid] diff --git a/simplejson/tests/test_indent.py b/simplejson/tests/test_indent.py new file mode 100644 index 0000000..157f707 --- /dev/null +++ b/simplejson/tests/test_indent.py @@ -0,0 +1,18 @@ + + + +def test_indent(): + import simplejson + + h = [['blorpie'], ['whoops'], [], 'd-shtaeou', 'd-nthiouh', 'i-vhbjkhnth', + {'nifty': 87}, {'field': 'yes', 'morefield': False} ] + + + d1 = simplejson.dumps(h) + d2 = simplejson.dumps(h, indent=2) + + h1 = simplejson.loads(d1) + h2 = simplejson.loads(d2) + + assert h1 == h + assert h2 == h |