@@ -135,44 +135,52 @@ def test_read_preference_tags_in_host_query_allows_mongoclient_construction(self
135135 MongoClient without raising validation errors, and result in correct tag sets.
136136 This verifies we no longer rely on pymongo's normalized options dict for tags.
137137 """
138- uri = (
139- "mongodb://localhost/"
140- "?readPreference=secondary"
141- "&readPreferenceTags=dc:ny,other:sf"
142- "&readPreferenceTags=dc:2,other:1"
143- )
144-
145- # Baseline: demonstrate why relying on parsed options can be problematic.
146- parsed = pymongo .uri_parser .parse_uri (uri )
147- # Some PyMongo versions normalize this into a dict (invalid as a kwarg), others into a list.
148- # If it's a dict, passing it as a kwarg will raise a ValueError as shown in the issue.
149- # We only assert no crash in our new path below; this is informational.
150- if isinstance (parsed ["options" ].get ("readPreferenceTags" ), dict ):
151- with self .assertRaises (ValueError ):
152- pymongo .MongoClient (readPreferenceTags = parsed ["options" ]["readPreferenceTags" ])
153-
154- # New behavior: keep the raw query on HOST, not in OPTIONS.
155- settings_dict = parse_uri (uri , db_name = "db" )
156- host_with_query = settings_dict ["HOST" ]
157- # Compose a full URI for MongoClient (non-SRV -> prepend scheme
158- # and ensure "/?" before query)
159- if host_with_query .startswith ("mongodb+srv://" ):
160- full_uri = host_with_query # SRV already includes scheme
161- else :
162- if "?" in host_with_query :
163- base , q = host_with_query .split ("?" , 1 )
164- full_uri = f"mongodb://{ base } /?{ q } "
165- else :
166- full_uri = f"mongodb://{ host_with_query } /"
167-
168- # Constructing MongoClient should not raise, and should reflect the read preference + tags.
169- client = pymongo .MongoClient (full_uri , serverSelectionTimeoutMS = 1 )
170- try :
171- doc = client .read_preference .document
172- self .assertEqual (doc .get ("mode" ), "secondary" )
173- self .assertEqual (
174- doc .get ("tags" ),
138+ cases = [
139+ (
140+ "mongodb://localhost/?readPreference=secondary&readPreferenceTags=dc:ny,other:sf&readPreferenceTags=dc:2,other:1" ,
175141 [{"dc" : "ny" , "other" : "sf" }, {"dc" : "2" , "other" : "1" }],
176- )
177- finally :
178- client .close ()
142+ ),
143+ (
144+ "mongodb://localhost/?retryWrites=true&readPreference=secondary&readPreferenceTags=nodeType:ANALYTICS&w=majority&appName=sniply-production" ,
145+ [{"nodeType" : "ANALYTICS" }],
146+ ),
147+ ]
148+
149+ for uri , expected_tags in cases :
150+ with self .subTest (uri = uri ):
151+ # Baseline: demonstrate why relying on parsed options can be problematic.
152+ parsed = pymongo .uri_parser .parse_uri (uri )
153+ # Some PyMongo versions normalize this into a dict (invalid as a kwarg),
154+ # others into a list. If it's a dict, passing it as a kwarg will raise a
155+ # ValueError as shown in the issue.
156+ # We only assert no crash in our new path below; this is informational.
157+ if isinstance (parsed ["options" ].get ("readPreferenceTags" ), dict ):
158+ with self .assertRaises (ValueError ):
159+ pymongo .MongoClient (
160+ readPreferenceTags = parsed ["options" ]["readPreferenceTags" ]
161+ )
162+
163+ # New behavior: keep the raw query on HOST, not in OPTIONS.
164+ settings_dict = parse_uri (uri , db_name = "db" )
165+ host_with_query = settings_dict ["HOST" ]
166+
167+ # Compose a full URI for MongoClient (non-SRV -> prepend scheme and
168+ # ensure "/?" before query)
169+ if host_with_query .startswith ("mongodb+srv://" ):
170+ full_uri = host_with_query # SRV already includes scheme
171+ else :
172+ if "?" in host_with_query :
173+ base , q = host_with_query .split ("?" , 1 )
174+ full_uri = f"mongodb://{ base } /?{ q } "
175+ else :
176+ full_uri = f"mongodb://{ host_with_query } /"
177+
178+ # Constructing MongoClient should not raise, and should reflect the read
179+ # preference + tags.
180+ client = pymongo .MongoClient (full_uri , serverSelectionTimeoutMS = 1 )
181+ try :
182+ doc = client .read_preference .document
183+ self .assertEqual (doc .get ("mode" ), "secondary" )
184+ self .assertEqual (doc .get ("tags" ), expected_tags )
185+ finally :
186+ client .close ()
0 commit comments