Skip to content

Commit 963759a

Browse files
PYTHON-2354 Add support for JSONOptions.with_options (#482)
1 parent 4a12caa commit 963759a

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

bson/codec_options.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -310,15 +310,9 @@ def with_options(self, **kwargs):
310310
311311
.. versionadded:: 3.5
312312
"""
313-
return CodecOptions(
314-
kwargs.get('document_class', self.document_class),
315-
kwargs.get('tz_aware', self.tz_aware),
316-
kwargs.get('uuid_representation', self.uuid_representation),
317-
kwargs.get('unicode_decode_error_handler',
318-
self.unicode_decode_error_handler),
319-
kwargs.get('tzinfo', self.tzinfo),
320-
kwargs.get('type_registry', self.type_registry)
321-
)
313+
opts = self._asdict()
314+
opts.update(kwargs)
315+
return CodecOptions(**opts)
322316

323317

324318
DEFAULT_CODEC_OPTIONS = CodecOptions(

bson/json_util.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,26 @@ def _arguments_repr(self):
311311
self.json_mode,
312312
super(JSONOptions, self)._arguments_repr()))
313313

314+
def with_options(self, **kwargs):
315+
"""
316+
Make a copy of this JSONOptions, overriding some options::
317+
318+
>>> from bson.json_util import CANONICAL_JSON_OPTIONS
319+
>>> CANONICAL_JSON_OPTIONS.tz_aware
320+
True
321+
>>> json_options = CANONICAL_JSON_OPTIONS.with_options(tz_aware=False)
322+
>>> json_options.tz_aware
323+
False
324+
325+
.. versionadded:: 3.12
326+
"""
327+
opts = self._asdict()
328+
for opt in ('strict_number_long', 'datetime_representation',
329+
'strict_uuid', 'json_mode'):
330+
opts[opt] = kwargs.get(opt, getattr(self, opt))
331+
opts.update(kwargs)
332+
return JSONOptions(**opts)
333+
314334

315335
LEGACY_JSON_OPTIONS = JSONOptions(json_mode=JSONMode.LEGACY)
316336
""":class:`JSONOptions` for encoding to PyMongo's legacy JSON format.

test/test_json_util.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,34 @@ def round_trip(self, doc, **kwargs):
5252
def test_basic(self):
5353
self.round_trip({"hello": "world"})
5454

55+
def test_json_options_with_options(self):
56+
opts = json_util.JSONOptions(
57+
datetime_representation=DatetimeRepresentation.NUMBERLONG)
58+
self.assertEqual(
59+
opts.datetime_representation, DatetimeRepresentation.NUMBERLONG)
60+
opts2 = opts.with_options(
61+
datetime_representation=DatetimeRepresentation.ISO8601)
62+
self.assertEqual(
63+
opts2.datetime_representation, DatetimeRepresentation.ISO8601)
64+
65+
opts = json_util.JSONOptions(strict_number_long=True)
66+
self.assertEqual(opts.strict_number_long, True)
67+
opts2 = opts.with_options(strict_number_long=False)
68+
self.assertEqual(opts2.strict_number_long, False)
69+
70+
opts = json_util.CANONICAL_JSON_OPTIONS
71+
self.assertNotEqual(
72+
opts.uuid_representation, UuidRepresentation.JAVA_LEGACY)
73+
opts2 = opts.with_options(
74+
uuid_representation=UuidRepresentation.JAVA_LEGACY)
75+
self.assertEqual(
76+
opts2.uuid_representation, UuidRepresentation.JAVA_LEGACY)
77+
self.assertEqual(opts2.document_class, dict)
78+
opts3 = opts2.with_options(document_class=SON)
79+
self.assertEqual(
80+
opts3.uuid_representation, UuidRepresentation.JAVA_LEGACY)
81+
self.assertEqual(opts3.document_class, SON)
82+
5583
def test_objectid(self):
5684
self.round_trip({"id": ObjectId()})
5785

0 commit comments

Comments
 (0)