Skip to content

Commit b053902

Browse files
WillAydproost
authored andcommitted
Reduce Loosely Typed Functions in objToJSON (pandas-dev#29954)
1 parent daa154a commit b053902

File tree

1 file changed

+38
-61
lines changed

1 file changed

+38
-61
lines changed

pandas/_libs/src/ujson/python/objToJSON.c

+38-61
Original file line numberDiff line numberDiff line change
@@ -385,42 +385,8 @@ static PyObject *get_item(PyObject *obj, Py_ssize_t i) {
385385
return ret;
386386
}
387387

388-
static void *CDouble(JSOBJ obj, JSONTypeContext *tc, void *outValue,
389-
size_t *_outLen) {
390-
PRINTMARK();
391-
*((double *)outValue) = GET_TC(tc)->doubleValue;
392-
return NULL;
393-
}
394-
395-
static void *CLong(JSOBJ obj, JSONTypeContext *tc, void *outValue,
396-
size_t *_outLen) {
397-
PRINTMARK();
398-
*((JSINT64 *)outValue) = GET_TC(tc)->longValue;
399-
return NULL;
400-
}
401-
402-
static void *PyLongToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue,
403-
size_t *_outLen) {
404-
*((JSINT64 *)outValue) = GET_TC(tc)->longValue;
405-
return NULL;
406-
}
407-
408-
static void *NpyFloatToDOUBLE(JSOBJ _obj, JSONTypeContext *tc, void *outValue,
409-
size_t *_outLen) {
410-
PyObject *obj = (PyObject *)_obj;
411-
PyArray_CastScalarToCtype(obj, outValue, PyArray_DescrFromType(NPY_DOUBLE));
412-
return NULL;
413-
}
414-
415-
static void *PyFloatToDOUBLE(JSOBJ _obj, JSONTypeContext *tc, void *outValue,
416-
size_t *_outLen) {
417-
PyObject *obj = (PyObject *)_obj;
418-
*((double *)outValue) = PyFloat_AsDouble(obj);
419-
return NULL;
420-
}
421-
422388
static void *PyBytesToUTF8(JSOBJ _obj, JSONTypeContext *tc, void *outValue,
423-
size_t *_outLen) {
389+
size_t *_outLen) {
424390
PyObject *obj = (PyObject *)_obj;
425391
*_outLen = PyBytes_GET_SIZE(obj);
426392
return PyBytes_AS_STRING(obj);
@@ -571,7 +537,6 @@ static int NpyTypeToJSONType(PyObject *obj, JSONTypeContext *tc, int npyType,
571537
return JT_NULL;
572538
}
573539
GET_TC(tc)->doubleValue = (double)doubleVal;
574-
GET_TC(tc)->PyTypeToJSON = CDouble;
575540
return JT_DOUBLE;
576541
}
577542

@@ -588,10 +553,32 @@ static int NpyTypeToJSONType(PyObject *obj, JSONTypeContext *tc, int npyType,
588553
PRINTMARK();
589554
return JT_NULL;
590555
}
591-
GET_TC(tc)->longValue = (JSINT64)longVal;
592-
GET_TC(tc)->PyTypeToJSON = NpyDatetime64ToJSON;
593-
return ((PyObjectEncoder *)tc->encoder)->datetimeIso ? JT_UTF8
594-
: JT_LONG;
556+
557+
if (((PyObjectEncoder *)tc->encoder)->datetimeIso) {
558+
GET_TC(tc)->longValue = (JSINT64)longVal;
559+
GET_TC(tc)->PyTypeToJSON = NpyDatetime64ToJSON;
560+
return JT_UTF8;
561+
} else {
562+
563+
// TODO: consolidate uses of this switch
564+
switch (((PyObjectEncoder *)tc->encoder)->datetimeUnit) {
565+
case NPY_FR_ns:
566+
break;
567+
case NPY_FR_us:
568+
longVal /= 1000LL;
569+
break;
570+
case NPY_FR_ms:
571+
longVal /= 1000000LL;
572+
break;
573+
case NPY_FR_s:
574+
longVal /= 1000000000LL;
575+
break;
576+
default:
577+
break; // TODO: should raise error
578+
}
579+
GET_TC(tc)->longValue = longVal;
580+
return JT_LONG;
581+
}
595582
}
596583

597584
if (PyTypeNum_ISINTEGER(npyType)) {
@@ -604,7 +591,6 @@ static int NpyTypeToJSONType(PyObject *obj, JSONTypeContext *tc, int npyType,
604591
}
605592
castfunc(value, &longVal, 1, NULL, NULL);
606593
GET_TC(tc)->longValue = (JSINT64)longVal;
607-
GET_TC(tc)->PyTypeToJSON = CLong;
608594
return JT_LONG;
609595
}
610596

@@ -1829,7 +1815,6 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
18291815

18301816
if (PyLong_Check(obj)) {
18311817
PRINTMARK();
1832-
pc->PyTypeToJSON = PyLongToINT64;
18331818
tc->type = JT_LONG;
18341819
GET_TC(tc)->longValue = PyLong_AsLongLong(obj);
18351820

@@ -1847,7 +1832,7 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
18471832
if (npy_isnan(val) || npy_isinf(val)) {
18481833
tc->type = JT_NULL;
18491834
} else {
1850-
pc->PyTypeToJSON = PyFloatToDOUBLE;
1835+
GET_TC(tc)->doubleValue = val;
18511836
tc->type = JT_DOUBLE;
18521837
}
18531838
return;
@@ -1863,7 +1848,7 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
18631848
return;
18641849
} else if (PyObject_TypeCheck(obj, type_decimal)) {
18651850
PRINTMARK();
1866-
pc->PyTypeToJSON = PyFloatToDOUBLE;
1851+
GET_TC(tc)->doubleValue = PyFloat_AsDouble(obj);
18671852
tc->type = JT_DOUBLE;
18681853
return;
18691854
} else if (PyDateTime_Check(obj) || PyDate_Check(obj)) {
@@ -1874,12 +1859,15 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
18741859
}
18751860

18761861
PRINTMARK();
1877-
pc->PyTypeToJSON = PyDateTimeToJSON;
18781862
if (enc->datetimeIso) {
18791863
PRINTMARK();
1864+
pc->PyTypeToJSON = PyDateTimeToJSON;
18801865
tc->type = JT_UTF8;
18811866
} else {
18821867
PRINTMARK();
1868+
// TODO: last argument here is unused; should decouple string
1869+
// from long datetimelike conversion routines
1870+
PyDateTimeToJSON(obj, tc, &(GET_TC(tc)->longValue), 0);
18831871
tc->type = JT_LONG;
18841872
}
18851873
return;
@@ -1940,12 +1928,10 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
19401928
GET_TC(tc)->longValue = value;
19411929

19421930
PRINTMARK();
1943-
pc->PyTypeToJSON = PyLongToINT64;
19441931
tc->type = JT_LONG;
19451932
return;
19461933
} else if (PyArray_IsScalar(obj, Integer)) {
19471934
PRINTMARK();
1948-
pc->PyTypeToJSON = PyLongToINT64;
19491935
tc->type = JT_LONG;
19501936
PyArray_CastScalarToCtype(obj, &(GET_TC(tc)->longValue),
19511937
PyArray_DescrFromType(NPY_INT64));
@@ -1966,7 +1952,8 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
19661952
return;
19671953
} else if (PyArray_IsScalar(obj, Float) || PyArray_IsScalar(obj, Double)) {
19681954
PRINTMARK();
1969-
pc->PyTypeToJSON = NpyFloatToDOUBLE;
1955+
PyArray_CastScalarToCtype(obj, &(GET_TC(tc)->doubleValue),
1956+
PyArray_DescrFromType(NPY_DOUBLE));
19701957
tc->type = JT_DOUBLE;
19711958
return;
19721959
} else if (PyArray_Check(obj) && PyArray_CheckScalar(obj)) {
@@ -2315,21 +2302,11 @@ const char *Object_getStringValue(JSOBJ obj, JSONTypeContext *tc,
23152302
}
23162303

23172304
JSINT64 Object_getLongValue(JSOBJ obj, JSONTypeContext *tc) {
2318-
JSINT64 ret;
2319-
GET_TC(tc)->PyTypeToJSON(obj, tc, &ret, NULL);
2320-
return ret;
2321-
}
2322-
2323-
JSINT32 Object_getIntValue(JSOBJ obj, JSONTypeContext *tc) {
2324-
JSINT32 ret;
2325-
GET_TC(tc)->PyTypeToJSON(obj, tc, &ret, NULL);
2326-
return ret;
2305+
return GET_TC(tc)->longValue;
23272306
}
23282307

23292308
double Object_getDoubleValue(JSOBJ obj, JSONTypeContext *tc) {
2330-
double ret;
2331-
GET_TC(tc)->PyTypeToJSON(obj, tc, &ret, NULL);
2332-
return ret;
2309+
return GET_TC(tc)->doubleValue;
23332310
}
23342311

23352312
static void Object_releaseObject(JSOBJ _obj) { Py_DECREF((PyObject *)_obj); }
@@ -2384,7 +2361,7 @@ PyObject *objToJSON(PyObject *self, PyObject *args, PyObject *kwargs) {
23842361
Object_endTypeContext,
23852362
Object_getStringValue,
23862363
Object_getLongValue,
2387-
Object_getIntValue,
2364+
NULL, // getIntValue is unused
23882365
Object_getDoubleValue,
23892366
Object_iterBegin,
23902367
Object_iterNext,

0 commit comments

Comments
 (0)