Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/dump.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@

.. module:: rapidjson

:noindex:

.. testsetup::

import io
from rapidjson import dump, dumps

.. function:: dump(obj, stream, *, skipkeys=False, ensure_ascii=True, indent=None, \
default=None, sort_keys=False, number_mode=None, datetime_mode=None, \
default=None, sort_keys=False, single_line_array=False, \
number_mode=None, datetime_mode=None, \
uuid_mode=None, bytes_mode=BM_UTF8, chunk_size=65536, allow_nan=True)

Encode given Python `obj` instance into a ``JSON`` stream.
Expand All @@ -32,6 +35,7 @@
otherwise be serialized
:param bool sort_keys: whether dictionary keys should be sorted
alphabetically
:param bool single_line_array: whether to print array in a single line, in pretty mode.
:param int number_mode: enable particular behaviors in handling numbers
:param int datetime_mode: how should :class:`datetime`, :class:`time` and
:class:`date` instances be handled
Expand Down
9 changes: 8 additions & 1 deletion docs/dumps.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
NM_DECIMAL, NM_NAN, PM_NONE, PM_COMMENTS, PM_TRAILING_COMMAS)

.. function:: dumps(obj, *, skipkeys=False, ensure_ascii=True, indent=None, \
default=None, sort_keys=False, number_mode=None, datetime_mode=None, \
default=None, sort_keys=False, single_line_array=False, \
number_mode=None, datetime_mode=None, \
uuid_mode=None, bytes_mode=BM_UTF8, allow_nan=True)

Encode given Python `obj` instance into a ``JSON`` string.
Expand All @@ -33,6 +34,7 @@
otherwise be serialized
:param bool sort_keys: whether dictionary keys should be sorted
alphabetically
:param bool single_line_array: whether to print array in a single line, in pretty mode.
:param int number_mode: enable particular behaviors in handling numbers
:param int datetime_mode: how should :class:`datetime`, :class:`time` and
:class:`date` instances be handled
Expand Down Expand Up @@ -105,6 +107,11 @@
"three": 3
}
]
>>> print(dumps({'a': 1, 'b': [2, 3])], indent=2, single_line_array=True))
{
"a": 1,
"b": [2, 3]
}


.. rubric:: `default`
Expand Down
4 changes: 3 additions & 1 deletion docs/encoder.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
NM_DECIMAL, NM_NAN, PM_NONE, PM_COMMENTS, PM_TRAILING_COMMAS)

.. class:: Encoder(skip_invalid_keys=False, ensure_ascii=True, indent=None, \
sort_keys=False, number_mode=None, datetime_mode=None, \
sort_keys=False, single_line_array=False, \
uuid_mode=None, bytes_mode=BM_UTF8)

Class-based :func:`dumps`\ -like functionality.
Expand All @@ -32,6 +32,8 @@
<pretty-print>`
:param bool sort_keys: whether dictionary keys should be :ref:`sorted
alphabetically <sort-keys>`
:param bool single_line_array: whether to print array in a single line, in :ref:`pretty mode
<pretty-print>`.
:param int number_mode: enable particular :ref:`behaviors in handling numbers
<dumps-number-mode>`
:param int datetime_mode: how should :ref:`datetime, time and date instances be handled
Expand Down
55 changes: 43 additions & 12 deletions rapidjson.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,13 @@ static PyObject* decoder_new(PyTypeObject* type, PyObject* args, PyObject* kwarg

static PyObject* do_encode(PyObject* value, bool skipInvalidKeys, PyObject* defaultFn,
bool sortKeys, bool ensureAscii, bool prettyPrint,
unsigned indent, NumberMode numberMode,
unsigned indent, bool singleLineArray, NumberMode numberMode,
DatetimeMode datetimeMode, UuidMode uuidMode,
BytesMode bytesMode);
static PyObject* do_stream_encode(PyObject* value, PyObject* stream, size_t chunkSize,
bool skipInvalidKeys, PyObject* defaultFn,
bool sortKeys, bool ensureAscii, bool prettyPrint,
unsigned indent, NumberMode numberMode,
unsigned indent, bool singleLineArray, NumberMode numberMode,
DatetimeMode datetimeMode, UuidMode uuidMode,
BytesMode bytesMode);
static PyObject* encoder_call(PyObject* self, PyObject* args, PyObject* kwargs);
Expand Down Expand Up @@ -2816,6 +2816,7 @@ typedef struct {
bool prettyPrint;
unsigned indent;
bool sortKeys;
bool singleLineArray;
DatetimeMode datetimeMode;
UuidMode uuidMode;
NumberMode numberMode;
Expand All @@ -2825,7 +2826,8 @@ typedef struct {

PyDoc_STRVAR(dumps_docstring,
"dumps(obj, *, skipkeys=False, ensure_ascii=True, indent=None, default=None,"
" sort_keys=False, number_mode=None, datetime_mode=None, uuid_mode=None,"
" sort_keys=False, single_line_array=False,"
" number_mode=None, datetime_mode=None, uuid_mode=None,"
" bytes_mode=BM_UTF8, allow_nan=True)\n"
"\n"
"Encode a Python object into a JSON string.");
Expand All @@ -2842,6 +2844,7 @@ dumps(PyObject* self, PyObject* args, PyObject* kwargs)
PyObject* indent = NULL;
PyObject* defaultFn = NULL;
int sortKeys = false;
bool singleLineArray = false;
PyObject* numberModeObj = NULL;
NumberMode numberMode = NM_NAN;
PyObject* datetimeModeObj = NULL;
Expand All @@ -2860,6 +2863,7 @@ dumps(PyObject* self, PyObject* args, PyObject* kwargs)
"indent",
"default",
"sort_keys",
"single_line_array",
"number_mode",
"datetime_mode",
"uuid_mode",
Expand All @@ -2871,14 +2875,15 @@ dumps(PyObject* self, PyObject* args, PyObject* kwargs)
NULL
};

if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|$ppOOpOOOOp:rapidjson.dumps",
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|$ppOOppOOOOp:rapidjson.dumps",
(char**) kwlist,
&value,
&skipKeys,
&ensureAscii,
&indent,
&defaultFn,
&sortKeys,
&singleLineArray,
&numberModeObj,
&datetimeModeObj,
&uuidModeObj,
Expand Down Expand Up @@ -2978,13 +2983,15 @@ dumps(PyObject* self, PyObject* args, PyObject* kwargs)

return do_encode(value, skipKeys ? true : false, defaultFn, sortKeys ? true : false,
ensureAscii ? true : false, prettyPrint ? true : false,
indentCharCount, numberMode, datetimeMode, uuidMode, bytesMode);
indentCharCount, singleLineArray ? true : false,
numberMode, datetimeMode, uuidMode, bytesMode);
}


PyDoc_STRVAR(dump_docstring,
"dump(obj, stream, *, skipkeys=False, ensure_ascii=True, indent=None,"
" default=None, sort_keys=False, number_mode=None, datetime_mode=None,"
" default=None, sort_keys=False, single_line_array=False,"
" number_mode=None, datetime_mode=None,"
" uuid_mode=None, bytes_mode=BM_UTF8, chunk_size=65536, allow_nan=True)\n"
"\n"
"Encode a Python object into a JSON stream.");
Expand All @@ -3002,6 +3009,7 @@ dump(PyObject* self, PyObject* args, PyObject* kwargs)
PyObject* indent = NULL;
PyObject* defaultFn = NULL;
int sortKeys = false;
bool singleLineArray = false;
PyObject* numberModeObj = NULL;
NumberMode numberMode = NM_NAN;
PyObject* datetimeModeObj = NULL;
Expand All @@ -3023,6 +3031,7 @@ dump(PyObject* self, PyObject* args, PyObject* kwargs)
"indent",
"default",
"sort_keys",
"single_line_array",
"number_mode",
"datetime_mode",
"uuid_mode",
Expand All @@ -3035,7 +3044,7 @@ dump(PyObject* self, PyObject* args, PyObject* kwargs)
NULL
};

if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|$ppOOpOOOOOp:rapidjson.dump",
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|$ppOOppOOOOOp:rapidjson.dump",
(char**) kwlist,
&value,
&stream,
Expand All @@ -3044,6 +3053,7 @@ dump(PyObject* self, PyObject* args, PyObject* kwargs)
&indent,
&defaultFn,
&sortKeys,
&singleLineArray,
&numberModeObj,
&datetimeModeObj,
&uuidModeObj,
Expand Down Expand Up @@ -3163,14 +3173,15 @@ dump(PyObject* self, PyObject* args, PyObject* kwargs)
return do_stream_encode(value, stream, chunkSize, skipKeys ? true : false,
defaultFn, sortKeys ? true : false,
ensureAscii ? true : false, prettyPrint ? true : false,
indentCharCount, numberMode, datetimeMode, uuidMode,
indentCharCount, singleLineArray ? true : false, numberMode, datetimeMode, uuidMode,
bytesMode);
}


PyDoc_STRVAR(encoder_doc,
"Encoder(skip_invalid_keys=False, ensure_ascii=True, indent=None,"
" sort_keys=False, number_mode=None, datetime_mode=None, uuid_mode=None,"
" sort_keys=False, single_line_array=False,"
" number_mode=None, datetime_mode=None, uuid_mode=None,"
" bytes_mode=None)\n\n"
"Create and return a new Encoder instance.");

Expand All @@ -3184,6 +3195,8 @@ static PyMemberDef encoder_members[] = {
T_UINT, offsetof(EncoderObject, indent), READONLY, "indent"},
{"sort_keys",
T_BOOL, offsetof(EncoderObject, ensureAscii), READONLY, "sort_keys"},
{"single_line_array",
T_BOOL, offsetof(EncoderObject, singleLineArray), READONLY, "single_line_array"},
{"datetime_mode",
T_UINT, offsetof(EncoderObject, datetimeMode), READONLY, "datetime_mode"},
{"uuid_mode",
Expand Down Expand Up @@ -3258,7 +3271,7 @@ static PyTypeObject Encoder_Type = {

static PyObject*
do_encode(PyObject* value, bool skipInvalidKeys, PyObject* defaultFn, bool sortKeys,
bool ensureAscii, bool prettyPrint, unsigned indent,
bool ensureAscii, bool prettyPrint, unsigned indent, bool singleLineArray,
NumberMode numberMode, DatetimeMode datetimeMode, UuidMode uuidMode,
BytesMode bytesMode)
{
Expand All @@ -3278,12 +3291,18 @@ do_encode(PyObject* value, bool skipInvalidKeys, PyObject* defaultFn, bool sortK
GenericStringBuffer<ASCII<> > buf;
PrettyWriter<GenericStringBuffer<ASCII<> >, UTF8<>, ASCII<> > writer(buf);
writer.SetIndent(' ', indent);
if (singleLineArray) {
writer.SetFormatOptions(kFormatSingleLineArray);
}
return DUMPS_INTERNAL_CALL;
}
else {
StringBuffer buf;
PrettyWriter<StringBuffer> writer(buf);
writer.SetIndent(' ', indent);
if (singleLineArray) {
writer.SetFormatOptions(kFormatSingleLineArray);
}
return DUMPS_INTERNAL_CALL;
}
}
Expand All @@ -3305,7 +3324,7 @@ do_encode(PyObject* value, bool skipInvalidKeys, PyObject* defaultFn, bool sortK
static PyObject*
do_stream_encode(PyObject* value, PyObject* stream, size_t chunkSize,
bool skipInvalidKeys, PyObject* defaultFn, bool sortKeys,
bool ensureAscii, bool prettyPrint, unsigned indent,
bool ensureAscii, bool prettyPrint, unsigned indent, bool singleLineArray,
NumberMode numberMode, DatetimeMode datetimeMode, UuidMode uuidMode,
BytesMode bytesMode)
{
Expand All @@ -3324,11 +3343,17 @@ do_stream_encode(PyObject* value, PyObject* stream, size_t chunkSize,
else if (ensureAscii) {
PrettyWriter<PyWriteStreamWrapper, UTF8<>, ASCII<> > writer(os);
writer.SetIndent(' ', indent);
if (singleLineArray) {
writer.SetFormatOptions(kFormatSingleLineArray);
}
return DUMP_INTERNAL_CALL;
}
else {
PrettyWriter<PyWriteStreamWrapper> writer(os);
writer.SetIndent(' ', indent);
if (singleLineArray) {
writer.SetFormatOptions(kFormatSingleLineArray);
}
return DUMP_INTERNAL_CALL;
}
}
Expand Down Expand Up @@ -3387,12 +3412,14 @@ encoder_call(PyObject* self, PyObject* args, PyObject* kwargs)
}
result = do_stream_encode(value, stream, chunkSize, e->skipInvalidKeys, defaultFn,
e->sortKeys, e->ensureAscii, e->prettyPrint, e->indent,
e->singleLineArray,
e->numberMode, e->datetimeMode, e->uuidMode,
e->bytesMode);
}
else {
result = do_encode(value, e->skipInvalidKeys, defaultFn, e->sortKeys,
e->ensureAscii, e->prettyPrint, e->indent,
e->singleLineArray,
e->numberMode, e->datetimeMode, e->uuidMode, e->bytesMode);
}

Expand All @@ -3411,6 +3438,7 @@ encoder_new(PyTypeObject* type, PyObject* args, PyObject* kwargs)
int ensureAscii = true;
PyObject* indent = NULL;
int sortKeys = false;
bool singleLineArray = false;
PyObject* numberModeObj = NULL;
NumberMode numberMode = NM_NAN;
PyObject* datetimeModeObj = NULL;
Expand All @@ -3427,19 +3455,21 @@ encoder_new(PyTypeObject* type, PyObject* args, PyObject* kwargs)
"ensure_ascii",
"indent",
"sort_keys",
"single_line_array",
"number_mode",
"datetime_mode",
"uuid_mode",
"bytes_mode",
NULL
};

if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ppOpOOOO:Encoder",
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ppOppOOOO:Encoder",
(char**) kwlist,
&skipInvalidKeys,
&ensureAscii,
&indent,
&sortKeys,
&singleLineArray,
&numberModeObj,
&datetimeModeObj,
&uuidModeObj,
Expand Down Expand Up @@ -3530,6 +3560,7 @@ encoder_new(PyTypeObject* type, PyObject* args, PyObject* kwargs)
e->prettyPrint = prettyPrint;
e->indent = indentCharCount;
e->sortKeys = sortKeys ? true : false;
e->singleLineArray = singleLineArray ? true : false;
e->datetimeMode = datetimeMode;
e->uuidMode = uuidMode;
e->numberMode = numberMode;
Expand Down
18 changes: 18 additions & 0 deletions tests/test_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,24 @@ def test_indent(dumps):
dumps(o, indent=-1)


@pytest.mark.unit
def test_single_line_array(dumps):
o = {"a": 1, "b": [2, 3, 4]}
expected1 = '{\n "a": 1,\n "b": [2, 3, 4]\n}'
expected2 = '{\n "b": [2, 3, 4],\n "a": 1\n}'
expected = (
expected1,
expected2)

assert dumps(o, indent=4, single_line_array=True) in expected

with pytest.raises(TypeError):
dumps(o, indent="\t")

with pytest.raises(TypeError):
dumps(o, indent=-1)


@pytest.mark.unit
def test_sort_keys(dumps):
o = {"a": 1, "z": 2, "b": 3}
Expand Down