Skip to content
This repository has been archived by the owner on May 25, 2024. It is now read-only.

Commit

Permalink
feat: add skipkeys to dumps
Browse files Browse the repository at this point in the history
  • Loading branch information
Nambers committed Apr 1, 2024
1 parent 1dbeb44 commit da9e5cf
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
20 changes: 17 additions & 3 deletions src/pycJSON_encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ typedef struct printbuffer {
size_t offset;
size_t depth; /* current nesting depth (for formatted printing) */
internal_hooks hooks;
bool format; /* is this print a formatted print */
bool using_heap;

/* args to print */
bool format; /* is this print a formatted print */
bool skipkeys;
} printbuffer;

// forward declaration
Expand Down Expand Up @@ -409,6 +412,16 @@ static bool print_object(PyObject *item, printbuffer *const output_buffer) {
}
Py_DECREF(str);
} else {
if(output_buffer->skipkeys) {
Py_DECREF(next_element);
next_element = PyIter_Next(iter);
if(next_element == NULL && *(output_buffer->buffer + output_buffer->offset - 1) == ',') {
output_buffer->offset--;
}
output_pointer = (output_buffer->buffer + output_buffer->offset);
length = 0;
goto SKIP_PRINT;
}
PyErr_SetString(PyExc_TypeError, "TypeError: Key must be str, None, bool or number");
return false;
}
Expand Down Expand Up @@ -445,6 +458,7 @@ static bool print_object(PyObject *item, printbuffer *const output_buffer) {
*output_pointer++ = ',';
}

SKIP_PRINT:
if (output_buffer->format) {
*output_pointer++ = '\n';
}
Expand Down Expand Up @@ -524,10 +538,10 @@ PyObject *pycJSON_Encode(PyObject *self, PyObject *args, PyObject *kwargs) {

unsigned char stack_buffer[CJSON_PRINTBUFFER_MAX_STACK_SIZE];

static const char *kwlist[] = {"obj", "format", NULL};
static const char *kwlist[] = {"obj", "format", "skipkeys", NULL};
PyObject *arg;
buffer->format = false;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|p", (char **) kwlist, &arg, &buffer->format)) {
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|pp", (char **) kwlist, &arg, &buffer->format, &buffer->skipkeys)) {
if (!PyErr_Occurred()) PyErr_SetString(PyExc_TypeError, "Failed to parse arguments");
return NULL;
}
Expand Down
23 changes: 23 additions & 0 deletions test/encode_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,29 @@ class A:
# with self.assertRaises(MemoryError):
# cjson.dumps(case)

def test_skipkeys(self):
import cjson
import json

class A:
pass

test_cases = [
{"a": 1, 2: 3},
{"a": "b", A(): 1},
{A(): 1, "a": "b"},
{"e": 2, A(): 1, "a": "b"},
]

for case in test_cases:
result_json = json.dumps(case, indent=None, separators=(",", ":"), ensure_ascii=False, skipkeys=True)
result_loadback_json = json.loads(result_json)

with self.subTest(msg=f'encoding_test(case={case})'):
result_cjson = cjson.dumps(case, skipkeys=True)
result_loadback_cjson = json.loads(result_cjson)
self._check_obj_same(result_loadback_json, result_loadback_cjson)

def test_encode(self):
import collections
import json
Expand Down

0 comments on commit da9e5cf

Please sign in to comment.