From 9d89561227db0d388756cfdf4658901e2178180f Mon Sep 17 00:00:00 2001 From: Prashant Mital Date: Tue, 8 Sep 2020 11:59:22 -0700 Subject: [PATCH 1/5] PYTHON-2354 Add support for JSONOptions.with_options --- bson/json_util.py | 22 ++++++++++++++++++++++ test/test_json_util.py | 21 +++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/bson/json_util.py b/bson/json_util.py index 7b789b0f30..b522114c7c 100644 --- a/bson/json_util.py +++ b/bson/json_util.py @@ -311,6 +311,28 @@ def _arguments_repr(self): self.json_mode, super(JSONOptions, self)._arguments_repr())) + def with_options(self, **kwargs): + """ + Make a copy of this JSONOptions, overriding some options:: + + >>> from bson.json_util import CANONICAL_JSON_OPTIONS + >>> CANONICAL_JSON_OPTIONS.tz_aware + True + >>> json_options = CANONICAL_JSON_OPTIONS.with_options(tz_aware=False) + >>> json_options.tz_aware + True + + .. versionadded:: 3.12 + """ + return JSONOptions( + strict_number_long=kwargs.pop( + 'strict_number_long', self.strict_number_long), + datetime_representation=kwargs.pop( + 'datetime_representation', self.datetime_representation), + strict_uuid=kwargs.pop('strict_uuid', self.strict_uuid), + json_mode=kwargs.pop('json_mode', self.json_mode), + **kwargs) + LEGACY_JSON_OPTIONS = JSONOptions(json_mode=JSONMode.LEGACY) """:class:`JSONOptions` for encoding to PyMongo's legacy JSON format. diff --git a/test/test_json_util.py b/test/test_json_util.py index e8b64a16d1..1ac6d11824 100644 --- a/test/test_json_util.py +++ b/test/test_json_util.py @@ -52,6 +52,27 @@ def round_trip(self, doc, **kwargs): def test_basic(self): self.round_trip({"hello": "world"}) + def test_json_options_with_options(self): + opts = json_util.JSONOptions( + datetime_representation=DatetimeRepresentation.NUMBERLONG) + self.assertEqual( + opts.datetime_representation, DatetimeRepresentation.NUMBERLONG) + newopts = opts.with_options( + datetime_representation=DatetimeRepresentation.ISO8601) + self.assertEqual( + newopts.datetime_representation, DatetimeRepresentation.ISO8601) + + opts = json_util.JSONOptions(strict_number_long=True) + self.assertEqual(opts.strict_number_long, True) + newopts = opts.with_options(strict_number_long=False) + self.assertEqual(newopts.strict_number_long, False) + + opts = json_util.CANONICAL_JSON_OPTIONS + newopts = opts.with_options( + uuid_representation=UuidRepresentation.JAVA_LEGACY) + self.assertEqual( + newopts.uuid_representation, UuidRepresentation.JAVA_LEGACY) + def test_objectid(self): self.round_trip({"id": ObjectId()}) From bf81b203b942c0e2d772b97d58126318dd502488 Mon Sep 17 00:00:00 2001 From: Prashant Mital Date: Tue, 8 Sep 2020 12:01:36 -0700 Subject: [PATCH 2/5] typo --- bson/json_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bson/json_util.py b/bson/json_util.py index b522114c7c..bcfbbacec0 100644 --- a/bson/json_util.py +++ b/bson/json_util.py @@ -320,7 +320,7 @@ def with_options(self, **kwargs): True >>> json_options = CANONICAL_JSON_OPTIONS.with_options(tz_aware=False) >>> json_options.tz_aware - True + False .. versionadded:: 3.12 """ From 811893b60283aea211c12814b9006df5208fc0d3 Mon Sep 17 00:00:00 2001 From: Prashant Mital Date: Tue, 8 Sep 2020 17:03:20 -0700 Subject: [PATCH 3/5] fix --- bson/json_util.py | 23 +++++++++++++++-------- test/test_json_util.py | 19 +++++++++++++------ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/bson/json_util.py b/bson/json_util.py index bcfbbacec0..5c6ff07050 100644 --- a/bson/json_util.py +++ b/bson/json_util.py @@ -324,14 +324,21 @@ def with_options(self, **kwargs): .. versionadded:: 3.12 """ - return JSONOptions( - strict_number_long=kwargs.pop( - 'strict_number_long', self.strict_number_long), - datetime_representation=kwargs.pop( - 'datetime_representation', self.datetime_representation), - strict_uuid=kwargs.pop('strict_uuid', self.strict_uuid), - json_mode=kwargs.pop('json_mode', self.json_mode), - **kwargs) + opts = ('strict_number_long', + 'datetime_representation', + 'strict_uuid', + 'json_mode', + 'document_class', + 'tz_aware', + 'uuid_representation', + 'unicode_decode_error_handler', + 'tzinfo', + 'type_registry') + + for opt in opts: + kwargs[opt] = kwargs.get(opt, getattr(self, opt)) + + return JSONOptions(**kwargs) LEGACY_JSON_OPTIONS = JSONOptions(json_mode=JSONMode.LEGACY) diff --git a/test/test_json_util.py b/test/test_json_util.py index 1ac6d11824..7ea366bfe3 100644 --- a/test/test_json_util.py +++ b/test/test_json_util.py @@ -57,21 +57,28 @@ def test_json_options_with_options(self): datetime_representation=DatetimeRepresentation.NUMBERLONG) self.assertEqual( opts.datetime_representation, DatetimeRepresentation.NUMBERLONG) - newopts = opts.with_options( + opts2 = opts.with_options( datetime_representation=DatetimeRepresentation.ISO8601) self.assertEqual( - newopts.datetime_representation, DatetimeRepresentation.ISO8601) + opts2.datetime_representation, DatetimeRepresentation.ISO8601) opts = json_util.JSONOptions(strict_number_long=True) self.assertEqual(opts.strict_number_long, True) - newopts = opts.with_options(strict_number_long=False) - self.assertEqual(newopts.strict_number_long, False) + opts2 = opts.with_options(strict_number_long=False) + self.assertEqual(opts2.strict_number_long, False) opts = json_util.CANONICAL_JSON_OPTIONS - newopts = opts.with_options( + self.assertNotEqual( + opts2.uuid_representation, UuidRepresentation.JAVA_LEGACY) + opts2 = opts.with_options( uuid_representation=UuidRepresentation.JAVA_LEGACY) self.assertEqual( - newopts.uuid_representation, UuidRepresentation.JAVA_LEGACY) + opts2.uuid_representation, UuidRepresentation.JAVA_LEGACY) + self.assertEqual(opts2.document_class, dict) + opts3 = opts2.with_options(document_class=SON) + self.assertEqual( + opts3.uuid_representation, UuidRepresentation.JAVA_LEGACY) + self.assertEqual(opts3.document_class, SON) def test_objectid(self): self.round_trip({"id": ObjectId()}) From 3684c32144a206bd4d89d14bb53e27fc7a57cf06 Mon Sep 17 00:00:00 2001 From: Prashant Mital Date: Wed, 9 Sep 2020 13:23:33 -0700 Subject: [PATCH 4/5] use namedtuple._asdict() --- bson/codec_options.py | 12 +++--------- bson/json_util.py | 20 +++++--------------- 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/bson/codec_options.py b/bson/codec_options.py index 833908fad0..0db900f59b 100644 --- a/bson/codec_options.py +++ b/bson/codec_options.py @@ -310,15 +310,9 @@ def with_options(self, **kwargs): .. versionadded:: 3.5 """ - return CodecOptions( - kwargs.get('document_class', self.document_class), - kwargs.get('tz_aware', self.tz_aware), - kwargs.get('uuid_representation', self.uuid_representation), - kwargs.get('unicode_decode_error_handler', - self.unicode_decode_error_handler), - kwargs.get('tzinfo', self.tzinfo), - kwargs.get('type_registry', self.type_registry) - ) + opts = self._asdict() + opts.update(kwargs) + return CodecOptions(**opts) DEFAULT_CODEC_OPTIONS = CodecOptions( diff --git a/bson/json_util.py b/bson/json_util.py index 5c6ff07050..dc2c57dee8 100644 --- a/bson/json_util.py +++ b/bson/json_util.py @@ -324,21 +324,11 @@ def with_options(self, **kwargs): .. versionadded:: 3.12 """ - opts = ('strict_number_long', - 'datetime_representation', - 'strict_uuid', - 'json_mode', - 'document_class', - 'tz_aware', - 'uuid_representation', - 'unicode_decode_error_handler', - 'tzinfo', - 'type_registry') - - for opt in opts: - kwargs[opt] = kwargs.get(opt, getattr(self, opt)) - - return JSONOptions(**kwargs) + opts = self._asdict() + for opt in ('strict_number_long', 'datetime_representation', + 'strict_uuid', 'json_mode'): + opts[opt] = kwargs.get(opt, getattr(self, opt)) + return JSONOptions(**opts) LEGACY_JSON_OPTIONS = JSONOptions(json_mode=JSONMode.LEGACY) From 576d9af8f04f27f6b1c8820c6092380570f0d2c2 Mon Sep 17 00:00:00 2001 From: Prashant Mital Date: Wed, 9 Sep 2020 13:45:23 -0700 Subject: [PATCH 5/5] fix --- bson/json_util.py | 1 + test/test_json_util.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/bson/json_util.py b/bson/json_util.py index dc2c57dee8..f4c1b498f6 100644 --- a/bson/json_util.py +++ b/bson/json_util.py @@ -328,6 +328,7 @@ def with_options(self, **kwargs): for opt in ('strict_number_long', 'datetime_representation', 'strict_uuid', 'json_mode'): opts[opt] = kwargs.get(opt, getattr(self, opt)) + opts.update(kwargs) return JSONOptions(**opts) diff --git a/test/test_json_util.py b/test/test_json_util.py index 7ea366bfe3..7906b276f5 100644 --- a/test/test_json_util.py +++ b/test/test_json_util.py @@ -69,7 +69,7 @@ def test_json_options_with_options(self): opts = json_util.CANONICAL_JSON_OPTIONS self.assertNotEqual( - opts2.uuid_representation, UuidRepresentation.JAVA_LEGACY) + opts.uuid_representation, UuidRepresentation.JAVA_LEGACY) opts2 = opts.with_options( uuid_representation=UuidRepresentation.JAVA_LEGACY) self.assertEqual(