Skip to content

Commit da83afc

Browse files
committed
Isolate ChainMap + add RawBSONDocument not inflated test
1 parent 13568b1 commit da83afc

File tree

5 files changed

+33
-13
lines changed

5 files changed

+33
-13
lines changed

pymongo/_client_bulk_shared.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
"""Constants, types, and classes shared across Client Bulk Write API implementations."""
1717
from __future__ import annotations
1818

19-
from collections import ChainMap
2019
from typing import TYPE_CHECKING, Any, Mapping, MutableMapping, NoReturn
2120

2221
from pymongo.errors import ClientBulkWriteException, OperationFailure
@@ -64,10 +63,6 @@ def _throw_client_bulk_write_exception(
6463
"""Raise a ClientBulkWriteException from the full result."""
6564
# retryWrites on MMAPv1 should raise an actionable error.
6665
if full_result["writeErrors"]:
67-
# Unpack ChainMaps into the original document only
68-
for doc in full_result["writeErrors"]:
69-
if "document" in doc["op"] and isinstance(doc["op"]["document"], ChainMap):
70-
doc["op"]["document"] = doc["op"]["document"].maps[0]
7166
full_result["writeErrors"].sort(key=lambda error: error["idx"])
7267
err = full_result["writeErrors"][0]
7368
code = err["code"]

pymongo/message.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,11 +1115,15 @@ def _check_doc_size_limits(
11151115
# Since the data document itself is nested within the insert document
11161116
# it won't be automatically re-ordered by the BSON conversion.
11171117
# We use ChainMap here to make the _id field the first field instead.
1118+
doc_to_encode = op_doc
11181119
if real_op_type == "insert":
1119-
op_doc["document"] = ChainMap(op_doc["document"], {"_id": op_doc["document"]["_id"]}) # type: ignore[index]
1120+
doc = op_doc["document"]
1121+
if not isinstance(doc, RawBSONDocument):
1122+
doc_to_encode = op_doc.copy() # Shallow copy
1123+
doc_to_encode["document"] = ChainMap(doc, {"_id": doc["_id"]}) # type: ignore[index]
11201124

11211125
# Encode current operation doc and, if newly added, namespace doc.
1122-
op_doc_encoded = _dict_to_bson(op_doc, False, opts)
1126+
op_doc_encoded = _dict_to_bson(doc_to_encode, False, opts)
11231127
op_length = len(op_doc_encoded)
11241128
if ns_doc:
11251129
ns_doc_encoded = _dict_to_bson(ns_doc, False, opts)

pymongo/monitoring.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def connection_checked_in(self, event):
189189
from __future__ import annotations
190190

191191
import datetime
192-
from collections import ChainMap, abc, namedtuple
192+
from collections import abc, namedtuple
193193
from typing import TYPE_CHECKING, Any, Mapping, Optional, Sequence
194194

195195
from bson.objectid import ObjectId
@@ -625,11 +625,6 @@ def __init__(
625625
raise ValueError(f"{command!r} is not a valid command")
626626
# Command name must be first key.
627627
command_name = next(iter(command))
628-
# Unpack ChainMaps into the original document only
629-
if command_name == "bulkWrite" and "ops" in command:
630-
for doc in command["ops"]:
631-
if "document" in doc and isinstance(doc["document"], ChainMap):
632-
doc["document"] = doc["document"].maps[0]
633628
super().__init__(
634629
command_name,
635630
request_id,

test/asynchronous/test_client_bulk_write.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import os
1919
import sys
2020

21+
from bson import encode
22+
2123
sys.path[0:0] = [""]
2224

2325
from test.asynchronous import (
@@ -84,6 +86,17 @@ async def test_formats_write_error_correctly(self):
8486
self.assertEqual(write_error["idx"], 1)
8587
self.assertEqual(write_error["op"], {"insert": 0, "document": {"_id": 1}})
8688

89+
@async_client_context.require_version_min(8, 0, 0, -24)
90+
@async_client_context.require_no_serverless
91+
async def test_raw_bson_not_inflated(self):
92+
doc = RawBSONDocument(encode({"a": "b" * 100}))
93+
models = [
94+
InsertOne(namespace="db.coll", document=doc),
95+
]
96+
await self.client.bulk_write(models=models)
97+
98+
self.assertIsNone(doc._RawBSONDocument__inflated_doc)
99+
87100

88101
# https://github.com/mongodb/specifications/tree/master/source/crud/tests
89102
class TestClientBulkWriteCRUD(AsyncIntegrationTest):

test/test_client_bulk_write.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import os
1919
import sys
2020

21+
from bson import encode
22+
2123
sys.path[0:0] = [""]
2224

2325
from test import (
@@ -84,6 +86,17 @@ def test_formats_write_error_correctly(self):
8486
self.assertEqual(write_error["idx"], 1)
8587
self.assertEqual(write_error["op"], {"insert": 0, "document": {"_id": 1}})
8688

89+
@client_context.require_version_min(8, 0, 0, -24)
90+
@client_context.require_no_serverless
91+
def test_raw_bson_not_inflated(self):
92+
doc = RawBSONDocument(encode({"a": "b" * 100}))
93+
models = [
94+
InsertOne(namespace="db.coll", document=doc),
95+
]
96+
self.client.bulk_write(models=models)
97+
98+
self.assertIsNone(doc._RawBSONDocument__inflated_doc)
99+
87100

88101
# https://github.com/mongodb/specifications/tree/master/source/crud/tests
89102
class TestClientBulkWriteCRUD(IntegrationTest):

0 commit comments

Comments
 (0)