Issue #5729: json.dumps to support using '\t' as an indent string

This commit is contained in:
Raymond Hettinger 2010-10-31 08:00:16 +00:00
parent 6ff2a7d121
commit b643ef8f8e
4 changed files with 38 additions and 26 deletions

View File

@ -135,10 +135,12 @@ Basic Usage
``inf``, ``-inf``) 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`` (the default) selects the most compact
representation.
If *indent* is a non-negative integer or string, then JSON array elements and
object members will be pretty-printed with that indent level. An indent level
of 0 or ``""`` will only insert newlines. ``None`` (the default) selects the
most compact representation. Using an integer indent indents that many spaces
per level. If *indent* is a string (such at '\t'), that string is used to indent
each level.
If *separators* is an ``(item_separator, dict_separator)`` tuple, then it
will be used instead of the default ``(', ', ': ')`` separators. ``(',',

View File

@ -259,6 +259,9 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
tuple=tuple,
):
if _indent is not None and not isinstance(_indent, str):
_indent = ' ' * _indent
def _iterencode_list(lst, _current_indent_level):
if not lst:
yield '[]'
@ -271,7 +274,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
buf = '['
if _indent is not None:
_current_indent_level += 1
newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
newline_indent = '\n' + _indent * _current_indent_level
separator = _item_separator + newline_indent
buf += newline_indent
else:
@ -307,7 +310,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
yield chunk
if newline_indent is not None:
_current_indent_level -= 1
yield '\n' + (' ' * (_indent * _current_indent_level))
yield '\n' + _indent * _current_indent_level
yield ']'
if markers is not None:
del markers[markerid]
@ -324,7 +327,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
yield '{'
if _indent is not None:
_current_indent_level += 1
newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
newline_indent = '\n' + _indent * _current_indent_level
item_separator = _item_separator + newline_indent
yield newline_indent
else:
@ -383,7 +386,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
yield chunk
if newline_indent is not None:
_current_indent_level -= 1
yield '\n' + (' ' * (_indent * _current_indent_level))
yield '\n' + _indent * _current_indent_level
yield '}'
if markers is not None:
del markers[markerid]

View File

@ -10,32 +10,36 @@ class TestIndent(TestCase):
expect = textwrap.dedent("""\
[
[
"blorpie"
],
[
"whoops"
],
[],
"d-shtaeou",
"d-nthiouh",
"i-vhbjkhnth",
{
"nifty": 87
},
{
"field": "yes",
"morefield": false
}
\t[
\t\t"blorpie"
\t],
\t[
\t\t"whoops"
\t],
\t[],
\t"d-shtaeou",
\t"d-nthiouh",
\t"i-vhbjkhnth",
\t{
\t\t"nifty": 87
\t},
\t{
\t\t"field": "yes",
\t\t"morefield": false
\t}
]""")
d1 = json.dumps(h)
d2 = json.dumps(h, indent=2, sort_keys=True, separators=(',', ': '))
d3 = json.dumps(h, indent='\t', sort_keys=True, separators=(',', ': '))
h1 = json.loads(d1)
h2 = json.loads(d2)
h3 = json.loads(d3)
self.assertEquals(h1, h)
self.assertEquals(h2, h)
self.assertEquals(d2, expect)
self.assertEquals(h3, h)
self.assertEquals(d2, expect.expandtabs(2))
self.assertEquals(d3, expect)

View File

@ -59,6 +59,9 @@ Core and Builtins
Library
-------
- Issue #5729: json.dumps() now supports using a string such as '\t'
for pretty-printing multilevel objects.
- Issue #10253: FileIO leaks a file descriptor when trying to open a file
for append that isn't seekable. Patch by Brian Brazil.