From 9d1d4443d5a49fa6702edbb88601b809e72e5eea Mon Sep 17 00:00:00 2001 From: Will Ayd Date: Tue, 5 Dec 2023 20:07:11 -0800 Subject: [PATCH] remove unused code from JSONtoObj --- .../src/vendored/ujson/python/JSONtoObj.c | 137 +++++------------- pandas/tests/io/json/test_ujson.py | 2 +- 2 files changed, 36 insertions(+), 103 deletions(-) diff --git a/pandas/_libs/src/vendored/ujson/python/JSONtoObj.c b/pandas/_libs/src/vendored/ujson/python/JSONtoObj.c index e7c58d498f9be..b7ee58c63a275 100644 --- a/pandas/_libs/src/vendored/ujson/python/JSONtoObj.c +++ b/pandas/_libs/src/vendored/ujson/python/JSONtoObj.c @@ -38,43 +38,9 @@ Numeric decoder derived from TCL library // Licence at LICENSES/ULTRAJSON_LICENSE -#define PY_ARRAY_UNIQUE_SYMBOL UJSON_NUMPY -#define NO_IMPORT_ARRAY -#define PY_SSIZE_T_CLEAN #include "pandas/vendored/ujson/lib/ultrajson.h" +#define PY_SSIZE_T_CLEAN #include -#include - -typedef struct __PyObjectDecoder { - JSONObjectDecoder dec; - - void *npyarr; // Numpy context buffer - void *npyarr_addr; // Ref to npyarr ptr to track DECREF calls -} PyObjectDecoder; - -typedef struct __NpyArrContext { - PyObject *ret; - PyObject *labels[2]; - PyArray_Dims shape; - - PyObjectDecoder *dec; -} NpyArrContext; - -// free the numpy context buffer -void Npy_releaseContext(NpyArrContext *npyarr) { - if (npyarr) { - if (npyarr->shape.ptr) { - PyObject_Free(npyarr->shape.ptr); - } - if (npyarr->dec) { - npyarr->dec->npyarr = NULL; - } - Py_XDECREF(npyarr->labels[0]); - Py_XDECREF(npyarr->labels[1]); - Py_XDECREF(npyarr->ret); - PyObject_Free(npyarr); - } -} static int Object_objectAddKey(void *prv, JSOBJ obj, JSOBJ name, JSOBJ value) { int ret = PyDict_SetItem(obj, name, value); @@ -132,95 +98,62 @@ static JSOBJ Object_newDouble(void *prv, double value) { } static void Object_releaseObject(void *prv, JSOBJ obj, void *_decoder) { - PyObjectDecoder *decoder = (PyObjectDecoder *)_decoder; - if (obj != decoder->npyarr_addr) { - Py_XDECREF(((PyObject *)obj)); - } + Py_XDECREF(((PyObject *)obj)); } -static char *g_kwlist[] = {"obj", "precise_float", "labelled", "dtype", NULL}; - PyObject *JSONToObj(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *ret; - PyObject *sarg; - PyObject *arg; - PyObject *opreciseFloat = NULL; - JSONObjectDecoder *decoder; - PyObjectDecoder pyDecoder; - PyArray_Descr *dtype = NULL; - int labelled = 0; - - JSONObjectDecoder dec = { - Object_newString, Object_objectAddKey, Object_arrayAddItem, - Object_newTrue, Object_newFalse, Object_newNull, - Object_newPosInf, Object_newNegInf, Object_newObject, - Object_endObject, Object_newArray, Object_endArray, - Object_newInteger, Object_newLong, Object_newUnsignedLong, - Object_newDouble, Object_releaseObject, PyObject_Malloc, - PyObject_Free, PyObject_Realloc}; - - dec.preciseFloat = 0; - dec.prv = NULL; - - pyDecoder.dec = dec; - pyDecoder.npyarr = NULL; - pyDecoder.npyarr_addr = NULL; - - decoder = (JSONObjectDecoder *)&pyDecoder; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OiiO&", g_kwlist, &arg, - &opreciseFloat, &labelled, - PyArray_DescrConverter2, &dtype)) { - Npy_releaseContext(pyDecoder.npyarr); + JSONObjectDecoder dec = {.newString = Object_newString, + .objectAddKey = Object_objectAddKey, + .arrayAddItem = Object_arrayAddItem, + .newTrue = Object_newTrue, + .newFalse = Object_newFalse, + .newNull = Object_newNull, + .newPosInf = Object_newPosInf, + .newNegInf = Object_newNegInf, + .newObject = Object_newObject, + .endObject = Object_endObject, + .newArray = Object_newArray, + .endArray = Object_endArray, + .newInt = Object_newInteger, + .newLong = Object_newLong, + .newUnsignedLong = Object_newUnsignedLong, + .newDouble = Object_newDouble, + .releaseObject = Object_releaseObject, + .malloc = PyObject_Malloc, + .free = PyObject_Free, + .realloc = PyObject_Realloc, + .errorStr = NULL, + .errorOffset = NULL, + .preciseFloat = 0, + .prv = NULL}; + + char *kwlist[] = {"obj", "precise_float", NULL}; + char *buf; + Py_ssize_t len; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|b", kwlist, &buf, &len, + &dec.preciseFloat)) { return NULL; } - if (opreciseFloat && PyObject_IsTrue(opreciseFloat)) { - decoder->preciseFloat = 1; - } - - if (PyBytes_Check(arg)) { - sarg = arg; - } else if (PyUnicode_Check(arg)) { - sarg = PyUnicode_AsUTF8String(arg); - if (sarg == NULL) { - // Exception raised above us by codec according to docs - return NULL; - } - } else { - PyErr_Format(PyExc_TypeError, "Expected 'str' or 'bytes'"); - return NULL; - } - - decoder->errorStr = NULL; - decoder->errorOffset = NULL; - - ret = JSON_DecodeObject(decoder, PyBytes_AS_STRING(sarg), - PyBytes_GET_SIZE(sarg)); - - if (sarg != arg) { - Py_DECREF(sarg); - } + PyObject *ret = JSON_DecodeObject(&dec, buf, len); if (PyErr_Occurred()) { if (ret) { Py_DECREF((PyObject *)ret); } - Npy_releaseContext(pyDecoder.npyarr); return NULL; } - if (decoder->errorStr) { + if (dec.errorStr) { /* FIXME: It's possible to give a much nicer error message here with actual failing element in input etc*/ - PyErr_Format(PyExc_ValueError, "%s", decoder->errorStr); + PyErr_Format(PyExc_ValueError, "%s", dec.errorStr); if (ret) { Py_DECREF((PyObject *)ret); } - Npy_releaseContext(pyDecoder.npyarr); return NULL; } diff --git a/pandas/tests/io/json/test_ujson.py b/pandas/tests/io/json/test_ujson.py index 646f6745936bd..56ea9ea625dff 100644 --- a/pandas/tests/io/json/test_ujson.py +++ b/pandas/tests/io/json/test_ujson.py @@ -585,7 +585,7 @@ def test_decode_numeric_int_exp(self, int_exp): assert ujson.ujson_loads(int_exp) == json.loads(int_exp) def test_loads_non_str_bytes_raises(self): - msg = "Expected 'str' or 'bytes'" + msg = "a bytes-like object is required, not 'NoneType'" with pytest.raises(TypeError, match=msg): ujson.ujson_loads(None)