From 9f07ff35a18ea456b555ba79c227d99f5d008cc5 Mon Sep 17 00:00:00 2001 From: Michael Elovskikh Date: Thu, 8 Jun 2017 01:02:17 +0500 Subject: [PATCH] PYTHON-1334 Don't change readpreference value at uri parsing (#325) --- pymongo/client_options.py | 6 ++++-- pymongo/common.py | 12 +++++------- pymongo/read_preferences.py | 6 ++++++ test/test_client.py | 6 ++++++ test/test_uri_parser.py | 28 ++++++++++++++++++---------- 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/pymongo/client_options.py b/pymongo/client_options.py index b9313db39..739a24098 100644 --- a/pymongo/client_options.py +++ b/pymongo/client_options.py @@ -22,7 +22,8 @@ from pymongo.errors import ConfigurationError from pymongo.monitoring import _EventListeners from pymongo.pool import PoolOptions from pymongo.read_concern import ReadConcern -from pymongo.read_preferences import make_read_preference +from pymongo.read_preferences import (make_read_preference, + read_pref_mode_from_name) from pymongo.ssl_support import get_ssl_context from pymongo.write_concern import WriteConcern @@ -42,7 +43,8 @@ def _parse_read_preference(options): if 'read_preference' in options: return options['read_preference'] - mode = options.get('readpreference', 0) + name = options.get('readpreference', 'primary') + mode = read_pref_mode_from_name(name) tags = options.get('readpreferencetags') max_staleness = options.get('maxstalenessseconds', -1) return make_read_preference(mode, tags, max_staleness) diff --git a/pymongo/common.py b/pymongo/common.py index 577e03ac8..cd4584d39 100644 --- a/pymongo/common.py +++ b/pymongo/common.py @@ -28,8 +28,7 @@ from pymongo.auth import MECHANISMS from pymongo.errors import ConfigurationError from pymongo.monitoring import _validate_event_listeners from pymongo.read_concern import ReadConcern -from pymongo.read_preferences import (read_pref_mode_from_name, - _ServerMode) +from pymongo.read_preferences import _MONGOS_MODES, _ServerMode from pymongo.ssl_support import validate_cert_reqs from pymongo.write_concern import WriteConcern @@ -302,13 +301,12 @@ def validate_read_preference(dummy, value): return value -def validate_read_preference_mode(dummy, name): +def validate_read_preference_mode(dummy, value): """Validate read preference mode for a MongoReplicaSetClient. """ - try: - return read_pref_mode_from_name(name) - except ValueError: - raise ValueError("%s is not a valid read preference" % (name,)) + if value not in _MONGOS_MODES: + raise ValueError("%s is not a valid read preference" % (value,)) + return value def validate_auth_mechanism(option, value): diff --git a/pymongo/read_preferences.py b/pymongo/read_preferences.py index b0b592dd9..ab06d821a 100644 --- a/pymongo/read_preferences.py +++ b/pymongo/read_preferences.py @@ -101,6 +101,12 @@ class _ServerMode(object): """ return self.__class__.__name__ + @property + def mongos_mode(self): + """The mongos mode of this read preference. + """ + return self.__mongos_mode + @property def document(self): """Read preference as a document. diff --git a/test/test_client.py b/test/test_client.py index b6123354c..90aa50b68 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -203,6 +203,12 @@ class ClientUnitTest(unittest.TestCase): MongoClient('mongodb://host/?' 'readpreference=primary&readpreferencetags=dc:east') + def test_read_preference(self): + c = rs_or_single_client( + "mongodb://host", connect=False, + readpreference=ReadPreference.NEAREST.mongos_mode) + self.assertEqual(c.read_preference, ReadPreference.NEAREST) + def test_metadata(self): metadata = _METADATA.copy() metadata['application'] = {'name': 'foobar'} diff --git a/test/test_uri_parser.py b/test/test_uri_parser.py index 2cb58f012..cf9ef24bf 100644 --- a/test/test_uri_parser.py +++ b/test/test_uri_parser.py @@ -338,7 +338,9 @@ class TestURI(unittest.TestCase): res, parse_uri("mongodb://localhost/test.name/with \"delimiters")) res = copy.deepcopy(orig) - res['options'] = {'readpreference': ReadPreference.SECONDARY.mode} + res['options'] = { + 'readpreference': ReadPreference.SECONDARY.mongos_mode + } self.assertEqual(res, parse_uri( "mongodb://localhost/?readPreference=secondary")) @@ -395,10 +397,13 @@ class TestURI(unittest.TestCase): "@localhost/foo?authMechanism=GSSAPI")) res = copy.deepcopy(orig) - res['options'] = {'readpreference': ReadPreference.SECONDARY.mode, - 'readpreferencetags': [ - {'dc': 'west', 'use': 'website'}, - {'dc': 'east', 'use': 'website'}]} + res['options'] = { + 'readpreference': ReadPreference.SECONDARY.mongos_mode, + 'readpreferencetags': [ + {'dc': 'west', 'use': 'website'}, + {'dc': 'east', 'use': 'website'} + ] + } res['username'] = 'user@domain.com' res['password'] = 'password' res['database'] = 'foo' @@ -409,11 +414,14 @@ class TestURI(unittest.TestCase): "readpreferencetags=dc:east,use:website")) res = copy.deepcopy(orig) - res['options'] = {'readpreference': ReadPreference.SECONDARY.mode, - 'readpreferencetags': [ - {'dc': 'west', 'use': 'website'}, - {'dc': 'east', 'use': 'website'}, - {}]} + res['options'] = { + 'readpreference': ReadPreference.SECONDARY.mongos_mode, + 'readpreferencetags': [ + {'dc': 'west', 'use': 'website'}, + {'dc': 'east', 'use': 'website'}, + {} + ] + } res['username'] = 'user@domain.com' res['password'] = 'password' res['database'] = 'foo'