Skip to content

Commit

Permalink
Use Python's repr() to emit float values
Browse files Browse the repository at this point in the history
This fixes issue #101: RJ's dtoa() seems to have a weird behavior with particular floating
point values.

See also Tencent/rapidjson#1237.
  • Loading branch information
lelit committed May 12, 2018
1 parent f53e987 commit 6a4cdaf
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
21 changes: 19 additions & 2 deletions rapidjson.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2276,8 +2276,25 @@ dumps_internal(
else
writer->RawValue("Infinity", 8, kNumberType);
}
else
writer->Double(d);
else {
// The RJ dtoa() produces "strange" results for particular values, see #101:
// use Python's repr() to emit a raw value instead of writer->Double(d)

PyObject *dr = PyObject_Repr(object);

if (dr == NULL)
return false;

Py_ssize_t l;
const char* rs = PyUnicode_AsUTF8AndSize(dr, &l);
if (rs == NULL) {
Py_DECREF(dr);
return false;
}

writer->RawValue(rs, l, kNumberType);
Py_DECREF(dr);
}
}
else if (PyUnicode_Check(object)) {
Py_ssize_t l;
Expand Down
7 changes: 7 additions & 0 deletions tests/test_base_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ def test_base_values(value, dumps, loads):
assert loaded == value and type(loaded) is type(value)


@pytest.mark.unit
def test_float(dumps):
value = 0.1 + 0.2
dumped = dumps(value)
assert dumped == '0.30000000000000004'


@pytest.mark.unit
def test_tuple(dumps):
obj = [1, 2, 'a', 1.2, {'foo': 'bar'},]
Expand Down

0 comments on commit 6a4cdaf

Please sign in to comment.