#18023: Stop bundling simplejson and deprecate the module
-------------------------------------+-------------------------------------
Reporter: ogier | Owner: aaugustin
Type: | Status: reopened
Cleanup/optimization | Version: master
Component: Core | Resolution:
(Serialization) | Triage Stage: Accepted
Severity: Release blocker | Needs documentation: 0
Keywords: | Patch needs improvement: 0
Has patch: 0 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Comment (by ogier):
Replying to [comment:9 aaugustin]:
> [https://groups.google.com/forum/?fromgroups#!topic/django-
developers/JM4ndZbk_wY This thread on the mailing list] and
[https://github.com/django/django/commit/cec6bd5a59547dc97fe98975c570fc27a1e970be#L5R53
this comment on the commit] indicate that this change may be backwards
incompatible.
>
> Right now I don't know what the correct resolution is. In all cases it
should be documented here.
Here's what I believe is an accurate summary of the situation:
'''First issue: str vs. unicode'''
The simplejson API is documented as returning unicode strings for all JSON
keys and string values.
http://simplejson.readthedocs.org/en/latest/index.html#simplejson.JSONDecoder
In fact, the optional C library (installed by default when installing
simplejson) makes an API-changing optimization: if the value is entirely
ASCII characters, a `str` instance is returned instead of a `unicode`
instance.
https://github.com/simplejson/simplejson/blob/master/simplejson/_speedups.c#L527
The Python standard library `json` package was forked from simplejson at
version 1.9, and included this optimization. However, it was considered a
bug and fixed in python 2.7. http://bugs.python.org/issue11982
The net result is that it is possible that some code that runs on manually
installed versions of simplejson or python <= 2.6 depends on this
behavior. I think that Python core's approach is correct: we should
consider this a bug, because it is behavior that directly contradicts the
documentation. It's worth pointing out that any code that depends on this
behavior is already broken on python 2.7.
'''Second issue: namedtuple_as_object'''
This is a systemic problem with any shim that is supposed to be
transparent. In this case, `namedtuple_as_object` is a keyword argument to
`simplejson.JSONEncoder` that was added in simplejson 2.2. The latest
version of simplejson that was merged into the python standard library is
2.0.9 and Django 1.4 shipped with simplejson 2.0.7 bundled. This means
that nowhere in stock Django are there any references to this keyword.
This wouldn't be a huge problem, except that Django subclasses
`django.utils.simplejson.JSONEncoder` as
`django.core.serializers.json.DjangoJSONEncoder`, and naturally doesn't
know about this keyword argument.
This is a deeper problem than just passing along unrecognized keyword
arguments to the base class in `__init__()` to make sure that
`DjangoJSONEncoder` never breaks. If we want to deprecate the
`django.utils.simplejson` shim, then `DjangoJSONEncoder` must become a
subclass of `json.JSONEncoder`. This has the unfortunate effect that calls
to `simplejson.dumps({'hi':'there'}, cls=DjangoJSONEncoder)` will all fail
(this is the `simplejson` on PyPI I'm talking about). Basically
`DjangoJSONEncoder` will be incompatible with simplejson, which is a
backwards incompatibility.
The problem is that even leaving in the shim and subclassing as we do
isn't a good solution. It means that DjangoJSONEncoder needs to not only
be backwards compatible through all supported Python versions, but they
also must be forwards compatible with the latest simplejson releases,
which have already been shown to diverge in backwards incompatible ways.
(Adding an argument to a method on a base class breaks contravariance.)
If that paragraph seemed confusing, think of it this way: if
`DjangoJSONEncoder` is a `json.JSONEncoder` then passing it to
`simplejson.dumps()` is dangerous. If `DjangoJSONEncoder` is a
`simplejson.JSONEncoder` then passing it to `json.dumps()` is dangerous.
--
Ticket URL: <https://code.djangoproject.com/ticket/18023#comment:10>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.