Skip to content

Commit 793a720

Browse files
committed
Write float repr directly into UnicodeWriter in JSON encoder
For finite float values, format into a stack buffer with _Py_double_repr_buffered() and write the bytes straight into the encoder's writer with PyUnicodeWriter_WriteASCII(), instead of building an intermediate PyUnicode object via tp_repr. Non-finite values fall through to encoder_encode_float() so that allow_nan semantics are preserved.
1 parent b2c23f1 commit 793a720

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

Modules/_json.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "pycore_global_strings.h" // _Py_ID()
1515
#include "pycore_pyerrors.h" // _PyErr_FormatNote
1616
#include "pycore_runtime.h" // _PyRuntime
17+
#include "pycore_ryu.h" // _Py_double_repr_buffered()
1718
#include "pycore_tuple.h" // _PyTuple_FromPair
1819
#include "pycore_unicodeobject.h" // _PyUnicode_CheckConsistency()
1920

@@ -1597,6 +1598,15 @@ encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer,
15971598
return _steal_accumulate(writer, encoded);
15981599
}
15991600
else if (PyFloat_Check(obj)) {
1601+
#if _PY_SHORT_FLOAT_REPR == 1
1602+
double d = PyFloat_AS_DOUBLE(obj);
1603+
if (isfinite(d)) {
1604+
char buf[_Py_DOUBLE_REPR_BUFSIZE];
1605+
Py_ssize_t len = _Py_double_repr_buffered(d, buf, sizeof(buf),
1606+
Py_DTSF_ADD_DOT_0);
1607+
return PyUnicodeWriter_WriteASCII(writer, buf, len);
1608+
}
1609+
#endif
16001610
PyObject *encoded = encoder_encode_float(s, obj);
16011611
if (encoded == NULL)
16021612
return -1;

0 commit comments

Comments
 (0)