ENH: add ujson support in pandas.io.json by jreback · Pull Request #3804 · pandas-dev/pandas (original) (raw)
Ok the following patch should make it safe to call Npy_releaseContext
multiple times (which is what was causing the problem). Segmentation fault is gone and valgrind output from Python 2.7 debug build is clean. Likewise all tests pass for Python 2.7 and valgrind output for json tests is clean (i.e. there are no warnings for json related code).
diff --git a/pandas/src/ujson/python/JSONtoObj.c b/pandas/src/ujson/python/JSONtoObj.c index 1db7586..160c30f 100644 --- a/pandas/src/ujson/python/JSONtoObj.c +++ b/pandas/src/ujson/python/JSONtoObj.c @@ -10,6 +10,7 @@ typedef struct __PyObjectDecoder JSONObjectDecoder dec;
void* npyarr; // Numpy context buffer
void* npyarr_addr; // Ref to npyarr ptr to track DECREF calls npy_intp curdim; // Current array dimension
PyArray_Descr* dtype;
@@ -67,9 +68,7 @@ void Npy_releaseContext(NpyArrContext* npyarr) } if (npyarr->dec) {
// Don't set to null, used to make sure we don't Py_DECREF npyarr
// in releaseObject
// npyarr->dec->npyarr = NULL;
npyarr->dec->npyarr = NULL; npyarr->dec->curdim = 0; } Py_XDECREF(npyarr->labels[0]);
@@ -88,6 +87,7 @@ JSOBJ Object_npyNewArray(void* _decoder) { // start of array - initialise the context buffer npyarr = decoder->npyarr = PyObject_Malloc(sizeof(NpyArrContext));
decoder->npyarr_addr = npyarr; if (!npyarr) {
@@ -515,7 +515,7 @@ JSOBJ Object_newDouble(double value) static void Object_releaseObject(JSOBJ obj, void* _decoder) { PyObjectDecoder* decoder = (PyObjectDecoder*) _decoder;
- if (obj != decoder->npyarr)
if (obj != decoder->npyarr_addr) { Py_XDECREF( ((PyObject )obj)); } @@ -555,6 +555,7 @@ PyObject JSONToObj(PyObject* self, PyObject *args, PyObject *kwargs) pyDecoder.dec = dec; pyDecoder.curdim = 0; pyDecoder.npyarr = NULL;
pyDecoder.npyarr_addr = NULL;
decoder = (JSONObjectDecoder*) &pyDecoder;
@@ -609,6 +610,7 @@ PyObject* JSONToObj(PyObject* self, PyObject *args, PyObject *kwargs)
if (PyErr_Occurred())
{
}Npy_releaseContext(pyDecoder.npyarr); return NULL;