#16850 closed Bug (fixed)
Testsuite failing on JSON serialization
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Core (Serialization) | Version: | 1.3 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Trying to build Django 1.3.1 on Debian unstable with python 2.6 and python-simplejson 2.2.0 installed I get two test suite failures.
Without python-simplejson
====================================================================== ERROR: test_serialize_unicode (modeltests.serializers.tests.JsonSerializerTestCase) Tests that unicode makes the roundtrip intact ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/rhertzog/deb/pkg/TEAMS/build-area/python-django-1.3.1/tests/modeltests/serializers/tests.py", line 172, in test_serialize_unicode obj_list = list(serializers.deserialize(self.serializer_name, serial_str)) File "/home/rhertzog/deb/pkg/TEAMS/build-area/python-django-1.3.1/django/core/serializers/json.py", line 35, in Deserializer for obj in PythonDeserializer(simplejson.load(stream), **options): File "/home/rhertzog/deb/pkg/TEAMS/build-area/python-django-1.3.1/django/core/serializers/python.py", line 128, in Deserializer data[field.name] = field.to_python(field_value) File "/home/rhertzog/deb/pkg/TEAMS/build-area/python-django-1.3.1/django/db/models/fields/__init__.py", line 761, in to_python return decimal.Decimal(value) File "/usr/lib/python2.6/decimal.py", line 649, in __new__ "First convert the float to a string") TypeError: Cannot convert float to Decimal. First convert the float to a string ====================================================================== ERROR: test_json_serializer (regressiontests.serializers_regress.tests.SerializerTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/rhertzog/deb/pkg/TEAMS/build-area/python-django-1.3.1/django/utils/functional.py", line 55, in _curried return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs)) File "/home/rhertzog/deb/pkg/TEAMS/build-area/python-django-1.3.1/tests/regressiontests/serializers_regress/tests.py", line 373, in serializerTest for obj in serializers.deserialize(format, serialized_data): File "/home/rhertzog/deb/pkg/TEAMS/build-area/python-django-1.3.1/django/core/serializers/json.py", line 35, in Deserializer for obj in PythonDeserializer(simplejson.load(stream), **options): File "/home/rhertzog/deb/pkg/TEAMS/build-area/python-django-1.3.1/django/core/serializers/python.py", line 128, in Deserializer data[field.name] = field.to_python(field_value) File "/home/rhertzog/deb/pkg/TEAMS/build-area/python-django-1.3.1/django/db/models/fields/__init__.py", line 761, in to_python return decimal.Decimal(value) File "/usr/lib/python2.6/decimal.py", line 649, in __new__ "First convert the float to a string") TypeError: Cannot convert float to Decimal. First convert the float to a string
I also filed https://github.com/simplejson/simplejson/issues/17 because I'm not sure whether Django is improperly using simplejson or whether simplejson has a bug.
Change History (8)
comment:1 by , 13 years ago
comment:2 by , 13 years ago
Note that the comment above was made by the simplejson author/maintainer (see https://github.com/simplejson/simplejson/issues/17#issuecomment-2105920).
comment:3 by , 13 years ago
Triage Stage: | Unreviewed → Accepted |
---|
We should just use that use_decimal=False option, then. I don't see a compelling case for changing the dumped output to use numbers instead of strings for decimals, given that it can lose precision in the round-trip.
follow-up: 5 comment:4 by , 13 years ago
There is something strange in the fact that testing things with Python 2.7 (I also use Debian unstable, Python 2.7 has recently entered Sid) and the same simplejson 2.2.0 version (provided by debian python-simplejson DEB package) doesn't show these failures.
Just to be sure, I ran the serializers tests with Python 2.6 in the same system and I see the reported failures.
Maybe Python 2.6 also has something to do with this?
comment:5 by , 13 years ago
Replying to ramiro:
There is something strange in the fact that testing things with Python 2.7 (I also use Debian unstable, Python 2.7 has recently entered Sid) and the same simplejson 2.2.0 version (provided by debian python-simplejson DEB package) doesn't show these failures.
Just to be sure, I ran the serializers tests with Python 2.6 in the same system and I see the reported failures.
Maybe Python 2.6 also has something to do with this?
The reason for this is because additionally the version of Decimal shipped with Python 2.7 has a new Decimal.from_float()
method that gets used during decoding from JSON operations instead or raising the error reported with Python 2.6 by the OP. This method can lose precision and neither we nor simplejson can control that.
This seems to be an additional reason to keep using strings to encode Decimal's
It looks like the problem here is that Django expects that decimal objects will get converted to string (by its default method) instead of a JSON number. This change to the default options was made for usability reasons in simplejson 2.2.0, most people want decimals to get encoded as numbers even though there's a possible loss of precision if decoded on the other end without the right options. This behavior can be turned back off with use_decimal=False on encode. The version embedded in Django also supports this option (default False rather than True), so explicitly specifying this behavior would be compatible with whichever version of dump/dumps ends up getting used.