@@ -135,44 +135,52 @@ def test_read_preference_tags_in_host_query_allows_mongoclient_construction(self
135
135
MongoClient without raising validation errors, and result in correct tag sets.
136
136
This verifies we no longer rely on pymongo's normalized options dict for tags.
137
137
"""
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" ,
175
141
[{"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