PYTHON-1949 CodecOptions and JSONOptions should have the same default value for tz_aware (#720)
This commit is contained in:
parent
fb20975a1f
commit
e3771587c3
@ -226,7 +226,7 @@ class JSONOptions(CodecOptions):
|
||||
- `tz_aware`: If ``True``, MongoDB Extended JSON's *Strict mode* type
|
||||
`Date` will be decoded to timezone aware instances of
|
||||
:class:`datetime.datetime`. Otherwise they will be naive. Defaults
|
||||
to ``True``.
|
||||
to ``False``.
|
||||
- `tzinfo`: A :class:`datetime.tzinfo` subclass that specifies the
|
||||
timezone from which :class:`~datetime.datetime` objects should be
|
||||
decoded. Defaults to :const:`~bson.tz_util.utc`.
|
||||
@ -245,14 +245,15 @@ class JSONOptions(CodecOptions):
|
||||
.. versionchanged:: 3.5
|
||||
Accepts the optional parameter `json_mode`.
|
||||
|
||||
.. versionadded:: 3.4
|
||||
.. versionchanged:: 4.0
|
||||
Changed default value of `tz_aware` to False.
|
||||
"""
|
||||
|
||||
def __new__(cls, strict_number_long=None,
|
||||
datetime_representation=None,
|
||||
strict_uuid=None, json_mode=JSONMode.RELAXED,
|
||||
*args, **kwargs):
|
||||
kwargs["tz_aware"] = kwargs.get("tz_aware", True)
|
||||
kwargs["tz_aware"] = kwargs.get("tz_aware", False)
|
||||
if kwargs["tz_aware"]:
|
||||
kwargs["tzinfo"] = kwargs.get("tzinfo", utc)
|
||||
if datetime_representation not in (DatetimeRepresentation.LEGACY,
|
||||
|
||||
@ -123,6 +123,9 @@ Breaking Changes in 4.0
|
||||
:class:`~bson.dbref.DBRef`.
|
||||
- The "tls" install extra is no longer necessary or supported and will be
|
||||
ignored by pip.
|
||||
- ``tz_aware``, an argument for :class:`~bson.json_util.JSONOptions`,
|
||||
now defaults to ``False`` instead of ``True``. ``json_util.loads`` now
|
||||
decodes datetime as naive by default.
|
||||
- ``directConnection`` URI option and keyword argument to :class:`~pymongo.mongo_client.MongoClient`
|
||||
defaults to ``False`` instead of ``None``, allowing for the automatic
|
||||
discovery of replica sets. This means that if you
|
||||
@ -132,6 +135,7 @@ Breaking Changes in 4.0
|
||||
with :meth:`~pymongo.collection.Collection.find`.
|
||||
- ``name`` is now a required argument for the :class:`pymongo.driver_info.DriverInfo` class.
|
||||
|
||||
d
|
||||
Notable improvements
|
||||
....................
|
||||
|
||||
|
||||
@ -183,6 +183,14 @@ can be changed to this::
|
||||
|
||||
names = client.list_database_names()
|
||||
|
||||
``tz_aware`` defaults to ``False``
|
||||
..................................
|
||||
|
||||
``tz_aware``, an argument for :class:`~bson.json_util.JSONOptions`,
|
||||
now defaults to ``False`` instead of ``True``. ``json_util.loads`` now
|
||||
decodes datetime as naive by default.
|
||||
|
||||
|
||||
Database
|
||||
--------
|
||||
|
||||
|
||||
@ -74,6 +74,7 @@ _DEPRECATED_BSON_TYPES = {
|
||||
|
||||
# Need to set tz_aware=True in order to use "strict" dates in extended JSON.
|
||||
codec_options = CodecOptions(tz_aware=True, document_class=SON)
|
||||
codec_options_no_tzaware = CodecOptions(document_class=SON)
|
||||
# We normally encode UUID as binary subtype 0x03,
|
||||
# but we'll need to encode to subtype 0x04 for one of the tests.
|
||||
codec_options_uuid_04 = codec_options._replace(uuid_representation=STANDARD)
|
||||
@ -93,7 +94,7 @@ to_relaxed_extjson = functools.partial(
|
||||
to_bson_uuid_04 = functools.partial(encode,
|
||||
codec_options=codec_options_uuid_04)
|
||||
to_bson = functools.partial(encode, codec_options=codec_options)
|
||||
decode_bson = lambda bbytes: decode(bbytes, codec_options=codec_options)
|
||||
decode_bson = functools.partial(decode, codec_options=codec_options_no_tzaware)
|
||||
decode_extjson = functools.partial(
|
||||
json_util.loads,
|
||||
json_options=json_util.JSONOptions(json_mode=JSONMode.CANONICAL,
|
||||
|
||||
@ -22,7 +22,7 @@ import uuid
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from bson import json_util, EPOCH_AWARE, SON
|
||||
from bson import json_util, EPOCH_AWARE, EPOCH_NAIVE, SON
|
||||
from bson.json_util import (DatetimeRepresentation,
|
||||
JSONMode,
|
||||
JSONOptions,
|
||||
@ -103,61 +103,45 @@ class TestJsonUtil(unittest.TestCase):
|
||||
json_util.dumps(DBRef('collection', 1, 'db')))
|
||||
|
||||
def test_datetime(self):
|
||||
tz_aware_opts = json_util.DEFAULT_JSON_OPTIONS.with_options(
|
||||
tz_aware=True)
|
||||
# only millis, not micros
|
||||
self.round_trip({"date": datetime.datetime(2009, 12, 9, 15, 49, 45,
|
||||
191000, utc)}, json_options=tz_aware_opts)
|
||||
self.round_trip({"date": datetime.datetime(2009, 12, 9, 15,
|
||||
49, 45, 191000, utc)})
|
||||
49, 45, 191000)})
|
||||
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T00:00:00.000+0000"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T00:00:00.000000+0000"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T00:00:00.000+00:00"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T00:00:00.000000+00:00"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T00:00:00.000000+00"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T00:00:00.000Z"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T00:00:00.000000Z"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T00:00:00Z"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
# No explicit offset
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T00:00:00.000"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T00:00:00"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T00:00:00.000000"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
# Localtime behind UTC
|
||||
jsn = '{"dt": { "$date" : "1969-12-31T16:00:00.000-0800"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1969-12-31T16:00:00.000000-0800"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1969-12-31T16:00:00.000-08:00"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1969-12-31T16:00:00.000000-08:00"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1969-12-31T16:00:00.000000-08"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
# Localtime ahead of UTC
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T01:00:00.000+0100"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T01:00:00.000000+0100"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T01:00:00.000+01:00"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T01:00:00.000000+01:00"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
jsn = '{"dt": { "$date" : "1970-01-01T01:00:00.000000+01"}}'
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(jsn)["dt"])
|
||||
for jsn in ['{"dt": { "$date" : "1970-01-01T00:00:00.000+0000"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T00:00:00.000000+0000"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T00:00:00.000+00:00"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T00:00:00.000000+00:00"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T00:00:00.000000+00"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T00:00:00.000Z"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T00:00:00.000000Z"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T00:00:00Z"}}',
|
||||
'{"dt": {"$date": "1970-01-01T00:00:00.000"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T00:00:00"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T00:00:00.000000"}}',
|
||||
'{"dt": { "$date" : "1969-12-31T16:00:00.000-0800"}}',
|
||||
'{"dt": { "$date" : "1969-12-31T16:00:00.000000-0800"}}',
|
||||
'{"dt": { "$date" : "1969-12-31T16:00:00.000-08:00"}}',
|
||||
'{"dt": { "$date" : "1969-12-31T16:00:00.000000-08:00"}}',
|
||||
'{"dt": { "$date" : "1969-12-31T16:00:00.000000-08"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T01:00:00.000+0100"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T01:00:00.000000+0100"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T01:00:00.000+01:00"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T01:00:00.000000+01:00"}}',
|
||||
'{"dt": { "$date" : "1970-01-01T01:00:00.000000+01"}}'
|
||||
]:
|
||||
self.assertEqual(EPOCH_AWARE, json_util.loads(
|
||||
jsn, json_options=tz_aware_opts)["dt"])
|
||||
self.assertEqual(EPOCH_NAIVE, json_util.loads(jsn)["dt"])
|
||||
|
||||
dtm = datetime.datetime(1, 1, 1, 1, 1, 1, 0, utc)
|
||||
jsn = '{"dt": {"$date": -62135593139000}}'
|
||||
self.assertEqual(dtm, json_util.loads(jsn)["dt"])
|
||||
self.assertEqual(dtm, json_util.loads(jsn, json_options=tz_aware_opts)["dt"])
|
||||
jsn = '{"dt": {"$date": {"$numberLong": "-62135593139000"}}}'
|
||||
self.assertEqual(dtm, json_util.loads(jsn)["dt"])
|
||||
self.assertEqual(dtm, json_util.loads(jsn, json_options=tz_aware_opts)["dt"])
|
||||
|
||||
# Test dumps format
|
||||
pre_epoch = {"dt": datetime.datetime(1, 1, 1, 1, 1, 1, 10000, utc)}
|
||||
@ -207,7 +191,8 @@ class TestJsonUtil(unittest.TestCase):
|
||||
self.assertEqual(
|
||||
datetime.datetime(1972, 1, 1, 1, 1, 1, 10000, utc),
|
||||
json_util.loads(
|
||||
'{"dt": {"$date": "1972-01-01T01:01:01.010+0000"}}')["dt"])
|
||||
'{"dt": {"$date": "1972-01-01T01:01:01.010+0000"}}',
|
||||
json_options=tz_aware_opts)["dt"])
|
||||
self.assertEqual(
|
||||
datetime.datetime(1972, 1, 1, 1, 1, 1, 10000, utc),
|
||||
json_util.loads(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user