Skip to content

Commit a2175c0

Browse files
committed
Format decimal.Decimal as full precision strings in .to_json(...)
1 parent a81d52f commit a2175c0

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

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

+37-2
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,31 @@ static char *PyTimeToJSON(JSOBJ _obj, JSONTypeContext *tc, size_t *outLen) {
373373
return outValue;
374374
}
375375

376+
static char *PyDecimalToUTF8Callback(JSOBJ _obj, JSONTypeContext *tc,
377+
size_t *len) {
378+
PyObject *obj = (PyObject *)_obj;
379+
PyObject *str = PyObject_Str(obj);
380+
if (str == NULL) {
381+
*len = 0;
382+
if (!PyErr_Occurred()) {
383+
PyErr_SetString(PyExc_ValueError, "Failed to convert decimal");
384+
}
385+
((JSONObjectEncoder *)tc->encoder)->errorMsg = "";
386+
return NULL;
387+
}
388+
if (PyUnicode_Check(str)) {
389+
PyObject *tmp = str;
390+
str = PyUnicode_AsUTF8String(str);
391+
Py_DECREF(tmp);
392+
}
393+
394+
GET_TC(tc)->newObj = str;
395+
396+
*len = PyBytes_GET_SIZE(str);
397+
char *outValue = PyBytes_AS_STRING(str);
398+
return outValue;
399+
}
400+
376401
//=============================================================================
377402
// Numpy array iteration functions
378403
//=============================================================================
@@ -1467,8 +1492,18 @@ static void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
14671492
tc->type = JT_UTF8;
14681493
return;
14691494
} else if (object_is_decimal_type(obj)) {
1470-
pc->doubleValue = PyFloat_AsDouble(obj);
1471-
tc->type = JT_DOUBLE;
1495+
PyObject *is_nan_py = PyObject_RichCompare(obj, obj, Py_NE);
1496+
if (is_nan_py == NULL) {
1497+
goto INVALID;
1498+
}
1499+
int is_nan = (is_nan_py == Py_True);
1500+
Py_DECREF(is_nan_py);
1501+
if (is_nan) {
1502+
tc->type = JT_NULL;
1503+
return;
1504+
}
1505+
pc->PyTypeToUTF8 = PyDecimalToUTF8Callback;
1506+
tc->type = JT_UTF8;
14721507
return;
14731508
} else if (PyDateTime_Check(obj) || PyDate_Check(obj)) {
14741509
if (object_is_nat_type(obj)) {

0 commit comments

Comments
 (0)