diff --git a/bson/json_util.py b/bson/json_util.py index 5eb3f32a9..9e5ee3682 100644 --- a/bson/json_util.py +++ b/bson/json_util.py @@ -48,7 +48,13 @@ instances (as they are extended strings you can't provide custom defaults), but it will be faster as there is less recursion. .. versionchanged:: 2.8 - Supports $numberLong and $undefined - new in MongoDB 2.6. Also supports + The output format for :class:`~bson.timestamp.Timestamp` has changed from + '{"t": , "i": }' to '{"$timestamp": {"t": , "i": }}'. + This new format will be decoded to an instance of + :class:`~bson.timestamp.Timestamp`. The old format will continue to be + decoded to a python dict as before. Encoding to the old format is no longer + supported as it was never correct and loses type information. + Added support for $numberLong and $undefined - new in MongoDB 2.6 - and parsing $date in ISO-8601 format. .. versionchanged:: 2.7 @@ -212,6 +218,9 @@ def object_hook(dct, compile_re=True): return None if "$numberLong" in dct: return Int64(dct["$numberLong"]) + if "$timestamp" in dct: + tsp = dct["$timestamp"] + return Timestamp(tsp["t"], tsp["i"]) return dct @@ -256,7 +265,7 @@ def default(obj): if isinstance(obj, MaxKey): return {"$maxKey": 1} if isinstance(obj, Timestamp): - return SON([("t", obj.time), ("i", obj.inc)]) + return {"$timestamp": SON([("t", obj.time), ("i", obj.inc)])} if isinstance(obj, Code): return SON([('$code', str(obj)), ('$scope', obj.scope)]) if isinstance(obj, Binary): diff --git a/doc/changelog.rst b/doc/changelog.rst index 696bf78f2..d1667114b 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -116,6 +116,13 @@ Highlights include: - :meth:`~pymongo.mongo_client.MongoClient.copy_database` - :class:`~pymongo.master_slave_connection.MasterSlaveConnection` + The JSON format for :class:`~bson.timestamp.Timestamp` has changed from + '{"t": , "i": }' to '{"$timestamp": {"t": , "i": }}'. + This new format will be decoded to an instance of + :class:`~bson.timestamp.Timestamp`. The old format will continue to be + decoded to a python dict as before. Encoding to the old format is no + longer supported as it was never correct and loses type information. + Issues Resolved ............... diff --git a/test/test_json_util.py b/test/test_json_util.py index 87aa74167..adba57c9d 100644 --- a/test/test_json_util.py +++ b/test/test_json_util.py @@ -161,13 +161,12 @@ class TestJsonUtil(unittest.TestCase): self.round_trip({"m": MaxKey()}) def test_timestamp(self): - res = json_util.dumps({"ts": Timestamp(4, 13)}, default=json_util.default) - # Check order. - self.assertEqual('{"ts": {"t": 4, "i": 13}}', res) + dct = {"ts": Timestamp(4, 13)} + res = json_util.dumps(dct, default=json_util.default) + self.assertEqual('{"ts": {"$timestamp": {"t": 4, "i": 13}}}', res) - dct = json_util.loads(res) - self.assertEqual(dct['ts']['t'], 4) - self.assertEqual(dct['ts']['i'], 13) + rtdct = json_util.loads(res) + self.assertEqual(dct, rtdct) def test_uuid(self): self.round_trip(