Skip to content

Commit 18b18a3

Browse files
authored
Merge branch 'master' into PYTHON-5164
2 parents 53545d0 + 080c1c6 commit 18b18a3

File tree

6 files changed

+65
-22
lines changed

6 files changed

+65
-22
lines changed

doc/changelog.rst

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
11
Changelog
22
=========
33

4-
Changes in Version 4.11.0 (YYYY/MM/DD)
4+
Changes in Version 4.11.2 (YYYY/MM/DD)
5+
--------------------------------------
6+
7+
Version 4.11.2 is a bug fix release.
8+
9+
- Fixed a bug where :meth:`~pymongo.database.Database.command` would fail when attempting to run the bulkWrite command.
10+
11+
Issues Resolved
12+
...............
13+
14+
See the `PyMongo 4.11.2 release notes in JIRA`_ for the list of resolved issues in this release.
15+
16+
.. _PyMongo 4.11.2 release notes in JIRA: https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=10004&version=42506
17+
18+
Changes in Version 4.11.1 (2025/02/10)
19+
--------------------------------------
20+
21+
- Fixed support for prebuilt ``ppc64le`` and ``s390x`` wheels.
22+
23+
Changes in Version 4.11.0 (2025/01/28)
524
--------------------------------------
625

726
.. warning:: PyMongo 4.11 drops support for Python 3.8 and PyPy 3.9: Python 3.9+ or PyPy 3.10+ is now required.

gridfs/asynchronous/grid_file.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,11 +1301,8 @@ async def write(self, data: Any) -> None:
13011301
raise ValueError("cannot write to a closed file")
13021302

13031303
try:
1304-
if isinstance(data, AsyncGridOut):
1305-
read = data.read
1306-
else:
1307-
# file-like
1308-
read = data.read
1304+
# file-like
1305+
read = data.read
13091306
except AttributeError:
13101307
# string
13111308
if not isinstance(data, (str, bytes)):
@@ -1317,7 +1314,7 @@ async def write(self, data: Any) -> None:
13171314
raise TypeError(
13181315
"must specify an encoding for file in order to write str"
13191316
) from None
1320-
read = io.BytesIO(data).read # type: ignore[assignment]
1317+
read = io.BytesIO(data).read
13211318

13221319
if inspect.iscoroutinefunction(read):
13231320
await self._write_async(read)
@@ -1331,15 +1328,15 @@ async def write(self, data: Any) -> None:
13311328
except BaseException:
13321329
await self.abort()
13331330
raise
1334-
self._buffer.write(to_write) # type: ignore
1335-
if len(to_write) < space: # type: ignore
1331+
self._buffer.write(to_write)
1332+
if len(to_write) < space:
13361333
return # EOF or incomplete
13371334
await self._flush_buffer()
13381335
to_write = read(self.chunk_size)
1339-
while to_write and len(to_write) == self.chunk_size: # type: ignore
1336+
while to_write and len(to_write) == self.chunk_size:
13401337
await self._flush_data(to_write)
13411338
to_write = read(self.chunk_size)
1342-
self._buffer.write(to_write) # type: ignore
1339+
self._buffer.write(to_write)
13431340

13441341
async def _write_async(self, read: Any) -> None:
13451342
if self._buffer.tell() > 0:

gridfs/synchronous/grid_file.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,11 +1291,8 @@ def write(self, data: Any) -> None:
12911291
raise ValueError("cannot write to a closed file")
12921292

12931293
try:
1294-
if isinstance(data, GridOut):
1295-
read = data.read
1296-
else:
1297-
# file-like
1298-
read = data.read
1294+
# file-like
1295+
read = data.read
12991296
except AttributeError:
13001297
# string
13011298
if not isinstance(data, (str, bytes)):
@@ -1307,7 +1304,7 @@ def write(self, data: Any) -> None:
13071304
raise TypeError(
13081305
"must specify an encoding for file in order to write str"
13091306
) from None
1310-
read = io.BytesIO(data).read # type: ignore[assignment]
1307+
read = io.BytesIO(data).read
13111308

13121309
if inspect.iscoroutinefunction(read):
13131310
self._write_async(read)
@@ -1321,15 +1318,15 @@ def write(self, data: Any) -> None:
13211318
except BaseException:
13221319
self.abort()
13231320
raise
1324-
self._buffer.write(to_write) # type: ignore
1325-
if len(to_write) < space: # type: ignore
1321+
self._buffer.write(to_write)
1322+
if len(to_write) < space:
13261323
return # EOF or incomplete
13271324
self._flush_buffer()
13281325
to_write = read(self.chunk_size)
1329-
while to_write and len(to_write) == self.chunk_size: # type: ignore
1326+
while to_write and len(to_write) == self.chunk_size:
13301327
self._flush_data(to_write)
13311328
to_write = read(self.chunk_size)
1332-
self._buffer.write(to_write) # type: ignore
1329+
self._buffer.write(to_write)
13331330

13341331
def _write_async(self, read: Any) -> None:
13351332
if self._buffer.tell() > 0:

pymongo/message.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
"insert": "documents",
106106
"update": "updates",
107107
"delete": "deletes",
108-
"bulkWrite": "bulkWrite",
108+
"bulkWrite": "ops",
109109
}
110110

111111
_UNICODE_REPLACE_CODEC_OPTIONS: CodecOptions[Mapping[str, Any]] = CodecOptions(

test/asynchronous/test_database.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,21 @@ async def test_command_with_regex(self):
430430
for doc in result["cursor"]["firstBatch"]:
431431
self.assertTrue(isinstance(doc["r"], Regex))
432432

433+
async def test_command_bulkWrite(self):
434+
# Ensure bulk write commands can be run directly via db.command().
435+
if async_client_context.version.at_least(8, 0):
436+
await self.client.admin.command(
437+
{
438+
"bulkWrite": 1,
439+
"nsInfo": [{"ns": self.db.test.full_name}],
440+
"ops": [{"insert": 0, "document": {}}],
441+
}
442+
)
443+
await self.db.command({"insert": "test", "documents": [{}]})
444+
await self.db.command({"update": "test", "updates": [{"q": {}, "u": {"$set": {"x": 1}}}]})
445+
await self.db.command({"delete": "test", "deletes": [{"q": {}, "limit": 1}]})
446+
await self.db.test.drop()
447+
433448
async def test_cursor_command(self):
434449
db = self.client.pymongo_test
435450
await db.test.drop()

test/test_database.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,21 @@ def test_command_with_regex(self):
425425
for doc in result["cursor"]["firstBatch"]:
426426
self.assertTrue(isinstance(doc["r"], Regex))
427427

428+
def test_command_bulkWrite(self):
429+
# Ensure bulk write commands can be run directly via db.command().
430+
if client_context.version.at_least(8, 0):
431+
self.client.admin.command(
432+
{
433+
"bulkWrite": 1,
434+
"nsInfo": [{"ns": self.db.test.full_name}],
435+
"ops": [{"insert": 0, "document": {}}],
436+
}
437+
)
438+
self.db.command({"insert": "test", "documents": [{}]})
439+
self.db.command({"update": "test", "updates": [{"q": {}, "u": {"$set": {"x": 1}}}]})
440+
self.db.command({"delete": "test", "deletes": [{"q": {}, "limit": 1}]})
441+
self.db.test.drop()
442+
428443
def test_cursor_command(self):
429444
db = self.client.pymongo_test
430445
db.test.drop()

0 commit comments

Comments
 (0)