Skip to content

Commit e953f24

Browse files
committed
PYTHON-2046 Change default JSONMode from LEGACY to RELAXED
1 parent 2eb0df8 commit e953f24

File tree

4 files changed

+126
-62
lines changed

4 files changed

+126
-62
lines changed

bson/json_util.py

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -238,23 +238,27 @@ class JSONOptions(CodecOptions):
238238
239239
.. seealso:: The specification for Relaxed and Canonical `Extended JSON`_.
240240
241-
.. versionadded:: 3.4
241+
.. versionchanged:: 4.0
242+
The default for `json_mode` was changed from :const:`JSONMode.LEGACY`
243+
to :const:`JSONMode.RELAXED`.
242244
243245
.. versionchanged:: 3.5
244246
Accepts the optional parameter `json_mode`.
245247
248+
.. versionadded:: 3.4
246249
"""
247250

248-
def __new__(cls, strict_number_long=False,
249-
datetime_representation=DatetimeRepresentation.LEGACY,
250-
strict_uuid=False, json_mode=JSONMode.LEGACY,
251+
def __new__(cls, strict_number_long=None,
252+
datetime_representation=None,
253+
strict_uuid=None, json_mode=JSONMode.RELAXED,
251254
*args, **kwargs):
252255
kwargs["tz_aware"] = kwargs.get("tz_aware", True)
253256
if kwargs["tz_aware"]:
254257
kwargs["tzinfo"] = kwargs.get("tzinfo", utc)
255258
if datetime_representation not in (DatetimeRepresentation.LEGACY,
256259
DatetimeRepresentation.NUMBERLONG,
257-
DatetimeRepresentation.ISO8601):
260+
DatetimeRepresentation.ISO8601,
261+
None):
258262
raise ConfigurationError(
259263
"JSONOptions.datetime_representation must be one of LEGACY, "
260264
"NUMBERLONG, or ISO8601 from DatetimeRepresentation.")
@@ -267,17 +271,47 @@ def __new__(cls, strict_number_long=False,
267271
"or CANONICAL from JSONMode.")
268272
self.json_mode = json_mode
269273
if self.json_mode == JSONMode.RELAXED:
274+
if strict_number_long:
275+
raise ConfigurationError(
276+
"Cannot specify strict_number_long=True with"
277+
" JSONMode.RELAXED")
278+
if datetime_representation not in (None,
279+
DatetimeRepresentation.ISO8601):
280+
raise ConfigurationError(
281+
"datetime_representation must be DatetimeRepresentation."
282+
"ISO8601 or omitted with JSONMode.RELAXED")
283+
if strict_uuid not in (None, True):
284+
raise ConfigurationError(
285+
"Cannot specify strict_uuid=False with JSONMode.RELAXED")
270286
self.strict_number_long = False
271287
self.datetime_representation = DatetimeRepresentation.ISO8601
272288
self.strict_uuid = True
273289
elif self.json_mode == JSONMode.CANONICAL:
290+
if strict_number_long not in (None, True):
291+
raise ConfigurationError(
292+
"Cannot specify strict_number_long=False with"
293+
" JSONMode.RELAXED")
294+
if datetime_representation not in (
295+
None, DatetimeRepresentation.NUMBERLONG):
296+
raise ConfigurationError(
297+
"datetime_representation must be DatetimeRepresentation."
298+
"NUMBERLONG or omitted with JSONMode.RELAXED")
299+
if strict_uuid not in (None, True):
300+
raise ConfigurationError(
301+
"Cannot specify strict_uuid=False with JSONMode.RELAXED")
274302
self.strict_number_long = True
275303
self.datetime_representation = DatetimeRepresentation.NUMBERLONG
276304
self.strict_uuid = True
277-
else:
278-
self.strict_number_long = strict_number_long
279-
self.datetime_representation = datetime_representation
280-
self.strict_uuid = strict_uuid
305+
else: # JSONMode.LEGACY
306+
self.strict_number_long = False
307+
self.datetime_representation = DatetimeRepresentation.LEGACY
308+
self.strict_uuid = False
309+
if strict_number_long is not None:
310+
self.strict_number_long = strict_number_long
311+
if datetime_representation is not None:
312+
self.datetime_representation = datetime_representation
313+
if strict_uuid is not None:
314+
self.strict_uuid = strict_uuid
281315
return self
282316

283317
def _arguments_repr(self):
@@ -307,7 +341,7 @@ def with_options(self, **kwargs):
307341
>>> from bson.json_util import CANONICAL_JSON_OPTIONS
308342
>>> CANONICAL_JSON_OPTIONS.tz_aware
309343
True
310-
>>> json_options = CANONICAL_JSON_OPTIONS.with_options(tz_aware=False)
344+
>>> json_options = CANONICAL_JSON_OPTIONS.with_options(tz_aware=False, tzinfo=None)
311345
>>> json_options.tz_aware
312346
False
313347
@@ -329,15 +363,6 @@ def with_options(self, **kwargs):
329363
.. versionadded:: 3.5
330364
"""
331365

332-
DEFAULT_JSON_OPTIONS = LEGACY_JSON_OPTIONS
333-
"""The default :class:`JSONOptions` for JSON encoding/decoding.
334-
335-
The same as :const:`LEGACY_JSON_OPTIONS`. This will change to
336-
:const:`RELAXED_JSON_OPTIONS` in a future release.
337-
338-
.. versionadded:: 3.4
339-
"""
340-
341366
CANONICAL_JSON_OPTIONS = JSONOptions(json_mode=JSONMode.CANONICAL)
342367
""":class:`JSONOptions` for Canonical Extended JSON.
343368
@@ -354,18 +379,16 @@ def with_options(self, **kwargs):
354379
.. versionadded:: 3.5
355380
"""
356381

357-
STRICT_JSON_OPTIONS = JSONOptions(
358-
strict_number_long=True,
359-
datetime_representation=DatetimeRepresentation.ISO8601,
360-
strict_uuid=True)
361-
"""**DEPRECATED** - :class:`JSONOptions` for MongoDB Extended JSON's *Strict
362-
mode* encoding.
382+
DEFAULT_JSON_OPTIONS = RELAXED_JSON_OPTIONS
383+
"""The default :class:`JSONOptions` for JSON encoding/decoding.
363384
364-
.. versionadded:: 3.4
385+
The same as :const:`RELAXED_JSON_OPTIONS`.
365386
366-
.. versionchanged:: 3.5
367-
Deprecated. Use :const:`RELAXED_JSON_OPTIONS` or
368-
:const:`CANONICAL_JSON_OPTIONS` instead.
387+
.. versionchanged:: 4.0
388+
Changed from :const:`LEGACY_JSON_OPTIONS` to
389+
:const:`RELAXED_JSON_OPTIONS`.
390+
391+
.. versionadded:: 3.4
369392
"""
370393

371394

@@ -380,6 +403,10 @@ def dumps(obj, *args, **kwargs):
380403
encoding of MongoDB Extended JSON types. Defaults to
381404
:const:`DEFAULT_JSON_OPTIONS`.
382405
406+
.. versionchanged:: 4.0
407+
Now outputs MongoDB Relaxed Extended JSON by default (using
408+
:const:`DEFAULT_JSON_OPTIONS`).
409+
383410
.. versionchanged:: 3.4
384411
Accepts optional parameter `json_options`. See :class:`JSONOptions`.
385412
"""

doc/changelog.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ Breaking Changes in 4.0
9898
- Removed :exc:`pymongo.errors.CertificateError`.
9999
- Removed :attr:`pymongo.GEOHAYSTACK`.
100100
- Removed :class:`bson.binary.UUIDLegacy`.
101+
- Removed :const:`bson.json_util.STRICT_JSON_OPTIONS`. Use
102+
:const:`~bson.json_util.RELAXED_JSON_OPTIONS` or
103+
:const:`~bson.json_util.CANONICAL_JSON_OPTIONS` instead.
101104
- The "tls" install extra is no longer necessary or supported and will be
102105
ignored by pip.
103106

test/test_bson_corpus.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@
7171
json_options_uuid_04 = json_util.JSONOptions(json_mode=JSONMode.CANONICAL,
7272
uuid_representation=STANDARD)
7373
json_options_iso8601 = json_util.JSONOptions(
74-
datetime_representation=json_util.DatetimeRepresentation.ISO8601)
74+
datetime_representation=json_util.DatetimeRepresentation.ISO8601,
75+
json_mode=JSONMode.LEGACY)
7576
to_extjson = functools.partial(json_util.dumps,
7677
json_options=json_util.CANONICAL_JSON_OPTIONS)
7778
to_extjson_uuid_04 = functools.partial(json_util.dumps,

0 commit comments

Comments
 (0)