1
0
Fork 0
mirror of https://github.com/ultrajson/ultrajson.git synced 2024-06-02 14:46:04 +02:00

Differentiate integer vs explicit indent

This commit is contained in:
joncrall 2022-04-17 21:13:41 -04:00
parent d82654b34c
commit 4c68a0b74e
No known key found for this signature in database
GPG Key ID: BE04D092BDD81C0D
5 changed files with 52 additions and 44 deletions

View File

@ -260,6 +260,7 @@ typedef struct __JSONObjectEncoder
Configuration for spaces of indent */
int indentLength;
const char* indentChars;
int indentIsSpace; // encodes if the indent is given in indentChars or if it should just be pure spaces
/*
If true, NaN will be encoded as a string matching the Python standard library's JSON behavior.

View File

@ -552,18 +552,18 @@ static void Buffer_AppendIndentUnchecked(JSONObjectEncoder *enc, JSINT32 value)
int i;
if (enc->indentLength > -1)
{
/*if (enc->indentChars == NULL) */
/*{ */
/* while (value-- > 0) */
/* for (i = 0; i < enc->indentLength; i++)*/
/* Buffer_AppendCharUnchecked(enc, ' ');*/
/*} */
/*else */
/*{ */
if (enc->indentIsSpace == 1)
{
while (value-- > 0)
for (i = 0; i < enc->indentLength; i++)
Buffer_AppendCharUnchecked(enc, ' ');
}
else
{
while (value-- > 0)
for (i = 0; i < enc->indentLength; i++)
Buffer_AppendCharUnchecked(enc, enc->indentChars[i]);
/*}*/
}
}
}

View File

@ -830,8 +830,9 @@ PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs)
0, //encodeHTMLChars
1, //escapeForwardSlashes
0, //sortKeys
0, //indent
NULL, //indent chars
-1, //indentLength
NULL, //indentChars
0, // indentIsSpace
1, //allowNan
1, //rejectBytes
NULL, //prv
@ -870,29 +871,24 @@ PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs)
// Handle multiple input types
if (oindent == Py_None)
{
// Case where the indent is specified as None
// This should be exactly the same as if oindent is NULL
encoder.indentLength = -1;
/*sprintf(encoder.indentChars, ""); // how to do this right in C?*/
}
else if (PyLong_Check(oindent))
{
// Case where the indent is specified as an integer
// In this case the indent characters should only be
// space chars (i.e. ASCII 32)
encoder.indentLength = PyLong_AsLong(oindent);
sprintf(encoder.indentChars, " "); // how to do this right in C?
encoder.indentIsSpace = 1;
}
else if (PyUnicode_Check(oindent))
{
// set a custom indent string
// Case where custom UTF-8 indent is specified.
int olen = -1;
printf("\nIndent Print: '''\n");
PyObject_Print(oindent, stdout, 0);
printf("\n'''\n");
printf("before olen = %d\n", olen);
encoder.indentChars = _PyUnicodeToChars(oindent, &olen);
printf("after olen = %d\n", olen);
encoder.indentLength = (int) olen;
printf("encoder.indentChars = '%s'\n", encoder.indentChars);
printf("encoder.indentLength = %d\n", encoder.indentLength);
if(encoder.indentChars == NULL && encoder.indentLength == -1)
{
PyErr_SetString(PyExc_ValueError, "malformed indent");
@ -933,20 +929,20 @@ PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs)
csInf, csNan, 'e', DCONV_DECIMAL_IN_SHORTEST_LOW, DCONV_DECIMAL_IN_SHORTEST_HIGH, 0, 0);
PRINTMARK();
printf("a retLen = %d\n", retLen);
// printf("a retLen = %d\n", retLen);
ret = JSON_EncodeObject (oinput, &encoder, buffer, sizeof (buffer), &retLen);
printf("b retLen = %d\n", retLen);
// printf("b retLen = %d\n", retLen);
PRINTMARK();
dconv_d2s_free(&encoder.d2s);
printf("a\n");
// printf("a\n");
if (PyErr_Occurred())
{
return NULL;
}
printf("a\n");
// printf("a\n");
if (encoder.errorMsg)
{
if (ret != buffer)
@ -967,9 +963,9 @@ PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs)
PRINTMARK();
printf("\newobj : '''\n");
PyObject_Print(newobj, stdout, 0);
printf("\n'''\n");
// printf("\newobj : '''\n");
// PyObject_Print(newobj, stdout, 0);
// printf("\n'''\n");
return newobj;
}

View File

@ -2,6 +2,9 @@ r"""
Compare cases
python -c "import json as json; print(repr(json.dumps({None: None})))"
python -c "import ujson as json; print(repr(json.dumps({None: None})))"
python -c "import json ; print(repr(json.dumps([1], indent='\x000')))"
python -c "import ujson as json; print(repr(json.dumps([1], indent='\x000')))"
@ -9,9 +12,16 @@ python -c "import json ; print(repr(json.dumps([1, 2], indent='a \x000 b
python -c "import ujson as json; print(repr(json.dumps([1, 2], indent='a \x000 b')))"
python -c "import json ; print(repr(json.dumps([1], indent='\udfff')))"
python -c "import json as json; print(repr(json.dumps([1, 2, 3], indent='\udfff')))"
python -c "import ujson as json; print(repr(json.dumps([1, 2, 3], indent='\udfff')))"
python -c "import ujson as json; print(repr(json.dumps([1, 2, 3], indent='\udfff')))"
python -c "import ujson as json; print(repr(json.encode(json.decode('{\n \"obj\": 31337\n}'), indent=4)))"
python -c "import ujson as json; print(repr(json.encode([1, 2, 3], indent=4)))"
"""
import ujson

View File

@ -271,7 +271,9 @@ def test_encode_to_utf8():
)
def test_encode_indent(test_input):
obj = ujson.decode(test_input)
print('obj = {!r}'.format(obj))
output = ujson.encode(obj, indent=4)
print('output = {!r}'.format(output))
assert test_input == output
assert output == json.dumps(obj, indent=4)
@ -288,13 +290,12 @@ def test_indent_types():
output4a = ujson.encode(data, indent=4)
output4b = ujson.encode(data, indent=" ")
assert output0a == output0c
assert output0a == output0b
assert output0a == output0d
assert output4a == output4b
assert output0a != output4a
assert output0a == '[1,2,3]'
assert output0b == '[1,2,3]'
assert output0c == '[\n1,\n2,\n3\n]'
assert output0d == '[\n1,\n2,\n3\n]'
assert output4a == '[\n 1,\n 2,\n 3\n]'
assert output4b == '[\n 1,\n 2,\n 3\n]'
def test_nonspace_indent():
@ -548,7 +549,7 @@ def test_decode_array_empty():
def test_encode_surrogate_characters():
assert ujson.dumps("\udc7f") == r'"\udc7f"'
out = r'{"\ud800":"\udfff"}'
out = r'{"\ud800": "\udfff"}'
assert ujson.dumps({"\ud800": "\udfff"}) == out
assert ujson.dumps({"\ud800": "\udfff"}, sort_keys=True) == out
o = {b"\xed\xa0\x80": b"\xed\xbf\xbf"}
@ -831,10 +832,10 @@ def test_encode_no_assert(test_input):
"test_input, expected",
[
(1.0, "1.0"),
(OrderedDict([(1, 1), (0, 0), (8, 8), (2, 2)]), '{"1":1,"0":0,"8":8,"2":2}'),
({"a": float("NaN")}, '{"a":NaN}'),
({"a": float("inf")}, '{"a":Inf}'),
({"a": -float("inf")}, '{"a":-Inf}'),
(OrderedDict([(1, 1), (0, 0), (8, 8), (2, 2)]), '{"1": 1,"0": 0,"8": 8,"2": 2}'),
({"a": float("NaN")}, '{"a": NaN}'),
({"a": float("inf")}, '{"a": Inf}'),
({"a": -float("inf")}, '{"a": -Inf}'),
],
)
def test_encode(test_input, expected):
@ -962,12 +963,12 @@ def test_reject_bytes_true():
def test_reject_bytes_false():
data = {"a": b"b"}
assert ujson.dumps(data, reject_bytes=False) == '{"a":"b"}'
assert ujson.dumps(data, reject_bytes=False) == '{"a": "b"}'
def test_encode_none_key():
data = {None: None}
assert ujson.dumps(data) == '{"null":null}'
assert ujson.dumps(data) == '{"null": null}'
def test_default_function():