PYTHON-1111 JSONOptions.document_class requires simplejson in Python2.6
This commit is contained in:
parent
78c8a4522d
commit
6e2ecc1817
@ -70,10 +70,24 @@ but it will be faster as there is less recursion.
|
||||
import base64
|
||||
import collections
|
||||
import datetime
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
_HAS_OBJECT_PAIRS_HOOK = True
|
||||
if sys.version_info[:2] == (2, 6):
|
||||
# In Python 2.6, json does not include object_pairs_hook. Use simplejson
|
||||
# instead.
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
import json
|
||||
_HAS_OBJECT_PAIRS_HOOK = False
|
||||
else:
|
||||
import json
|
||||
|
||||
from pymongo.errors import ConfigurationError
|
||||
|
||||
import bson
|
||||
from bson import EPOCH_AWARE, RE_TYPE, SON
|
||||
from bson.binary import (Binary, JAVA_LEGACY, CSHARP_LEGACY, OLD_UUID_SUBTYPE,
|
||||
@ -106,6 +120,10 @@ _RE_OPT_TABLE = {
|
||||
class JSONOptions(CodecOptions):
|
||||
"""Encapsulates JSON options for :func:`dumps` and :func:`loads`.
|
||||
|
||||
Raises :exc:`~pymongo.errors.ConfigurationError` on Python 2.6 if
|
||||
`simplejson <https://pypi.python.org/pypi/simplejson>`_ is not installed
|
||||
and document_class is not the default (:class:`dict`).
|
||||
|
||||
:Parameters:
|
||||
- `strict_number_long`: If ``True``, :class:`~bson.int64.Int64` objects
|
||||
are encoded to MongoDB Extended JSON's *Strict mode* type
|
||||
@ -145,6 +163,11 @@ class JSONOptions(CodecOptions):
|
||||
if kwargs["tz_aware"]:
|
||||
kwargs["tzinfo"] = kwargs.get("tzinfo", utc)
|
||||
self = super(JSONOptions, cls).__new__(cls, *args, **kwargs)
|
||||
if not _HAS_OBJECT_PAIRS_HOOK and self.document_class != dict:
|
||||
raise ConfigurationError(
|
||||
"Support for JSONOptions.document_class on Python 2.6 "
|
||||
"requires simplejson "
|
||||
"(https://pypi.python.org/pypi/simplejson) to be installed.")
|
||||
self.strict_number_long = strict_number_long
|
||||
self.strict_date = strict_date
|
||||
self.strict_uuid = strict_uuid
|
||||
@ -177,7 +200,7 @@ def dumps(obj, *args, **kwargs):
|
||||
Recursive function that handles all BSON types including
|
||||
:class:`~bson.binary.Binary` and :class:`~bson.code.Code`.
|
||||
|
||||
Raises :class:`~bson.errors.InvalidDatetime` if `obj` contains a
|
||||
Raises :exc:`~bson.errors.InvalidDatetime` if `obj` contains a
|
||||
:class:`datetime.datetime` without a timezone and
|
||||
`json_options.strict_date` is ``True``.
|
||||
|
||||
@ -211,8 +234,11 @@ def loads(s, *args, **kwargs):
|
||||
Accepts optional parameter `json_options`. See :class:`JSONOptions`.
|
||||
"""
|
||||
json_options = kwargs.pop("json_options", DEFAULT_JSON_OPTIONS)
|
||||
kwargs["object_pairs_hook"] = lambda pairs: object_pairs_hook(pairs,
|
||||
json_options)
|
||||
if _HAS_OBJECT_PAIRS_HOOK:
|
||||
kwargs["object_pairs_hook"] = lambda pairs: object_pairs_hook(
|
||||
pairs, json_options)
|
||||
else:
|
||||
kwargs["object_hook"] = lambda obj: object_hook(obj, json_options)
|
||||
return json.loads(s, *args, **kwargs)
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,25 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Changes in Version 3.4
|
||||
----------------------
|
||||
|
||||
Version 3.4 implements the new server features introduced in MongoDB 3.4:
|
||||
|
||||
Highlights include:
|
||||
|
||||
- Finer control over JSON encoding/decoding with
|
||||
:class:`~bson.json_util.JSONOptions`.
|
||||
|
||||
|
||||
Issues Resolved
|
||||
...............
|
||||
|
||||
See the `PyMongo 3.4 release notes in JIRA`_ for the list of resolved issues
|
||||
in this release.
|
||||
|
||||
.. _PyMongo 3.4 release notes in JIRA: https://jira.mongodb.org/browse/PYTHON/fixforversion/16594
|
||||
|
||||
Changes in Version 3.3
|
||||
----------------------
|
||||
|
||||
|
||||
@ -20,8 +20,16 @@ import re
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
try:
|
||||
import simplejson
|
||||
HAS_SIMPLE_JSON = True
|
||||
except ImportError:
|
||||
HAS_SIMPLE_JSON = False
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from pymongo.errors import ConfigurationError
|
||||
|
||||
from bson import json_util, EPOCH_AWARE, EPOCH_NAIVE, SON
|
||||
from bson.binary import (Binary, MD5_SUBTYPE, USER_DEFINED_SUBTYPE,
|
||||
JAVA_LEGACY, CSHARP_LEGACY, STANDARD)
|
||||
@ -39,6 +47,7 @@ from bson.tz_util import FixedOffset, utc
|
||||
from test import unittest, IntegrationTest
|
||||
|
||||
PY3 = sys.version_info[0] == 3
|
||||
PY26 = sys.version_info[:2] == (2, 6)
|
||||
|
||||
|
||||
class TestJsonUtil(unittest.TestCase):
|
||||
@ -321,9 +330,17 @@ class TestJsonUtil(unittest.TestCase):
|
||||
jsn)
|
||||
|
||||
def test_loads_document_class(self):
|
||||
self.assertEqual(SON([("foo", "bar"), ("b", 1)]), json_util.loads(
|
||||
'{"foo": "bar", "b": 1}',
|
||||
json_options=json_util.JSONOptions(document_class=SON)))
|
||||
# document_class dict should always work
|
||||
self.assertEqual({"foo": "bar"}, json_util.loads(
|
||||
'{"foo": "bar"}',
|
||||
json_options=json_util.JSONOptions(document_class=dict)))
|
||||
if PY26 and not HAS_SIMPLE_JSON:
|
||||
self.assertRaises(
|
||||
ConfigurationError, json_util.JSONOptions, document_class=SON)
|
||||
else:
|
||||
self.assertEqual(SON([("foo", "bar"), ("b", 1)]), json_util.loads(
|
||||
'{"foo": "bar", "b": 1}',
|
||||
json_options=json_util.JSONOptions(document_class=SON)))
|
||||
|
||||
|
||||
class TestJsonUtilRoundtrip(IntegrationTest):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user