Skip to content

Commit 7848feb

Browse files
authored
PYTHON-4786 - Fix UpdateResult.did_upsert TypeError (#1878)
1 parent 0279407 commit 7848feb

File tree

6 files changed

+133
-2
lines changed

6 files changed

+133
-2
lines changed

Diff for: pymongo/results.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,12 @@ def upserted_id(self) -> Any:
171171

172172
@property
173173
def did_upsert(self) -> bool:
174-
"""Whether or not an upsert took place."""
174+
"""Whether an upsert took place.
175+
176+
.. versionadded:: 4.9
177+
"""
175178
assert self.__raw_result is not None
176-
return len(self.__raw_result.get("upserted", {})) > 0
179+
return "upserted" in self.__raw_result
177180

178181

179182
class DeleteResult(_WriteResult):

Diff for: test/asynchronous/test_client_bulk_write.py

+40
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,46 @@ async def test_returns_error_if_auto_encryption_configured(self):
550550
"bulk_write does not currently support automatic encryption", context.exception._message
551551
)
552552

553+
@async_client_context.require_version_min(8, 0, 0, -24)
554+
@async_client_context.require_no_serverless
555+
async def test_upserted_result(self):
556+
client = await self.async_rs_or_single_client()
557+
558+
collection = client.db["coll"]
559+
self.addAsyncCleanup(collection.drop)
560+
await collection.drop()
561+
562+
models = []
563+
models.append(
564+
UpdateOne(
565+
namespace="db.coll",
566+
filter={"_id": "a"},
567+
update={"$set": {"x": 1}},
568+
upsert=True,
569+
)
570+
)
571+
models.append(
572+
UpdateOne(
573+
namespace="db.coll",
574+
filter={"_id": None},
575+
update={"$set": {"x": 1}},
576+
upsert=True,
577+
)
578+
)
579+
models.append(
580+
UpdateOne(
581+
namespace="db.coll",
582+
filter={"_id": None},
583+
update={"$set": {"x": 1}},
584+
)
585+
)
586+
result = await client.bulk_write(models=models, verbose_results=True)
587+
588+
self.assertEqual(result.upserted_count, 2)
589+
self.assertEqual(result.update_results[0].did_upsert, True)
590+
self.assertEqual(result.update_results[1].did_upsert, True)
591+
self.assertEqual(result.update_results[2].did_upsert, False)
592+
553593

554594
# https://github.com/mongodb/specifications/blob/master/source/client-side-operations-timeout/tests/README.md#11-multi-batch-bulkwrites
555595
class TestClientBulkWriteCSOT(AsyncIntegrationTest):

Diff for: test/asynchronous/test_collection.py

+13
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,19 @@ async def test_update_one(self):
14441444
self.assertRaises(InvalidOperation, lambda: result.upserted_id)
14451445
self.assertFalse(result.acknowledged)
14461446

1447+
async def test_update_result(self):
1448+
db = self.db
1449+
await db.drop_collection("test")
1450+
1451+
result = await db.test.update_one({"x": 0}, {"$inc": {"x": 1}}, upsert=True)
1452+
self.assertEqual(result.did_upsert, True)
1453+
1454+
result = await db.test.update_one({"_id": None, "x": 0}, {"$inc": {"x": 1}}, upsert=True)
1455+
self.assertEqual(result.did_upsert, True)
1456+
1457+
result = await db.test.update_one({"_id": None}, {"$inc": {"x": 1}})
1458+
self.assertEqual(result.did_upsert, False)
1459+
14471460
async def test_update_many(self):
14481461
db = self.db
14491462
await db.drop_collection("test")

Diff for: test/test_client_bulk_write.py

+40
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,46 @@ def test_returns_error_if_auto_encryption_configured(self):
550550
"bulk_write does not currently support automatic encryption", context.exception._message
551551
)
552552

553+
@client_context.require_version_min(8, 0, 0, -24)
554+
@client_context.require_no_serverless
555+
def test_upserted_result(self):
556+
client = self.rs_or_single_client()
557+
558+
collection = client.db["coll"]
559+
self.addCleanup(collection.drop)
560+
collection.drop()
561+
562+
models = []
563+
models.append(
564+
UpdateOne(
565+
namespace="db.coll",
566+
filter={"_id": "a"},
567+
update={"$set": {"x": 1}},
568+
upsert=True,
569+
)
570+
)
571+
models.append(
572+
UpdateOne(
573+
namespace="db.coll",
574+
filter={"_id": None},
575+
update={"$set": {"x": 1}},
576+
upsert=True,
577+
)
578+
)
579+
models.append(
580+
UpdateOne(
581+
namespace="db.coll",
582+
filter={"_id": None},
583+
update={"$set": {"x": 1}},
584+
)
585+
)
586+
result = client.bulk_write(models=models, verbose_results=True)
587+
588+
self.assertEqual(result.upserted_count, 2)
589+
self.assertEqual(result.update_results[0].did_upsert, True)
590+
self.assertEqual(result.update_results[1].did_upsert, True)
591+
self.assertEqual(result.update_results[2].did_upsert, False)
592+
553593

554594
# https://github.com/mongodb/specifications/blob/master/source/client-side-operations-timeout/tests/README.md#11-multi-batch-bulkwrites
555595
class TestClientBulkWriteCSOT(IntegrationTest):

Diff for: test/test_collection.py

+13
Original file line numberDiff line numberDiff line change
@@ -1429,6 +1429,19 @@ def test_update_one(self):
14291429
self.assertRaises(InvalidOperation, lambda: result.upserted_id)
14301430
self.assertFalse(result.acknowledged)
14311431

1432+
def test_update_result(self):
1433+
db = self.db
1434+
db.drop_collection("test")
1435+
1436+
result = db.test.update_one({"x": 0}, {"$inc": {"x": 1}}, upsert=True)
1437+
self.assertEqual(result.did_upsert, True)
1438+
1439+
result = db.test.update_one({"_id": None, "x": 0}, {"$inc": {"x": 1}}, upsert=True)
1440+
self.assertEqual(result.did_upsert, True)
1441+
1442+
result = db.test.update_one({"_id": None}, {"$inc": {"x": 1}})
1443+
self.assertEqual(result.did_upsert, False)
1444+
14321445
def test_update_many(self):
14331446
db = self.db
14341447
db.drop_collection("test")

Diff for: test/test_results.py

+22
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,28 @@ def test_update_result(self):
122122
self.assertEqual(raw_result["n"], result.matched_count)
123123
self.assertEqual(raw_result["nModified"], result.modified_count)
124124
self.assertEqual(raw_result["upserted"], result.upserted_id)
125+
self.assertEqual(result.did_upsert, True)
126+
127+
raw_result_2 = {
128+
"n": 1,
129+
"nModified": 1,
130+
"upserted": [
131+
{"index": 5, "_id": 1},
132+
],
133+
}
134+
self.repr_test(UpdateResult, raw_result_2)
135+
136+
result = UpdateResult(raw_result_2, True)
137+
self.assertEqual(result.did_upsert, True)
138+
139+
raw_result_3 = {
140+
"n": 1,
141+
"nModified": 1,
142+
}
143+
self.repr_test(UpdateResult, raw_result_3)
144+
145+
result = UpdateResult(raw_result_3, True)
146+
self.assertEqual(result.did_upsert, False)
125147

126148
result = UpdateResult(raw_result, False)
127149
self.assertEqual(raw_result, result.raw_result)

0 commit comments

Comments
 (0)