Skip to content

Commit 96ad948

Browse files
authored
Merge branch 'master' into PYTHON-5101
2 parents b31172d + 1a7239c commit 96ad948

File tree

15 files changed

+169
-18
lines changed

15 files changed

+169
-18
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ documentation including narrative docs, and the [Sphinx docstring format](https:
178178
You can build the documentation locally by running:
179179

180180
```bash
181-
just docs-build
181+
just docs
182182
```
183183

184184
When updating docs, it can be helpful to run the live docs server as:

doc/async-tutorial.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,3 +420,10 @@ the collection:
420420
DuplicateKeyError: E11000 duplicate key error index: test_database.profiles.$user_id_1 dup key: { : 212 }
421421
422422
.. seealso:: The MongoDB documentation on `indexes <https://www.mongodb.com/docs/manual/indexes/>`_
423+
424+
Task Cancellation
425+
-----------------
426+
`Cancelling <https://docs.python.org/3/library/asyncio-task.html#task-cancellation>`_ an asyncio Task
427+
that is running a PyMongo operation is treated as a fatal interrupt. Any connections, cursors, and transactions
428+
involved in a cancelled Task will be safely closed and cleaned up as part of the cancellation. If those resources are
429+
also used elsewhere, attempting to utilize them after the cancellation will result in an error.

pymongo/asynchronous/change_stream.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,8 @@ async def try_next(self) -> Optional[_DocumentType]:
391391
if not _resumable(exc) and not exc.timeout:
392392
await self.close()
393393
raise
394-
except Exception:
394+
# Catch KeyboardInterrupt, CancelledError, etc. and cleanup.
395+
except BaseException:
395396
await self.close()
396397
raise
397398

pymongo/asynchronous/client_session.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,8 @@ async def callback(session, custom_arg, custom_kwarg=None):
697697
)
698698
try:
699699
ret = await callback(self)
700-
except Exception as exc:
700+
# Catch KeyboardInterrupt, CancelledError, etc. and cleanup.
701+
except BaseException as exc:
701702
if self.in_transaction:
702703
await self.abort_transaction()
703704
if (

pymongo/asynchronous/cursor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1126,7 +1126,8 @@ async def _send_message(self, operation: Union[_Query, _GetMore]) -> None:
11261126
self._killed = True
11271127
await self.close()
11281128
raise
1129-
except Exception:
1129+
# Catch KeyboardInterrupt, CancelledError, etc. and cleanup.
1130+
except BaseException:
11301131
await self.close()
11311132
raise
11321133

pymongo/asynchronous/mongo_client.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,17 +276,16 @@ def __init__(
276276
:param type_registry: instance of
277277
:class:`~bson.codec_options.TypeRegistry` to enable encoding
278278
and decoding of custom types.
279-
:param datetime_conversion: Specifies how UTC datetimes should be decoded
279+
:param kwargs: **Additional optional parameters available as keyword arguments:**
280+
281+
- `datetime_conversion` (optional): Specifies how UTC datetimes should be decoded
280282
within BSON. Valid options include 'datetime_ms' to return as a
281283
DatetimeMS, 'datetime' to return as a datetime.datetime and
282284
raising a ValueError for out-of-range values, 'datetime_auto' to
283285
return DatetimeMS objects when the underlying datetime is
284286
out-of-range and 'datetime_clamp' to clamp to the minimum and
285287
maximum possible datetimes. Defaults to 'datetime'. See
286288
:ref:`handling-out-of-range-datetimes` for details.
287-
288-
| **Other optional parameters can be passed as keyword arguments:**
289-
290289
- `directConnection` (optional): if ``True``, forces this client to
291290
connect directly to the specified MongoDB host as a standalone.
292291
If ``false``, the client connects to the entire replica set of

pymongo/asynchronous/pool.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ async def command(
559559
)
560560
except (OperationFailure, NotPrimaryError):
561561
raise
562-
# Catch socket.error, KeyboardInterrupt, etc. and close ourselves.
562+
# Catch socket.error, KeyboardInterrupt, CancelledError, etc. and close ourselves.
563563
except BaseException as error:
564564
self._raise_connection_failure(error)
565565

@@ -576,6 +576,7 @@ async def send_message(self, message: bytes, max_doc_size: int) -> None:
576576

577577
try:
578578
await async_sendall(self.conn, message)
579+
# Catch KeyboardInterrupt, CancelledError, etc. and cleanup.
579580
except BaseException as error:
580581
self._raise_connection_failure(error)
581582

@@ -586,6 +587,7 @@ async def receive_message(self, request_id: Optional[int]) -> Union[_OpReply, _O
586587
"""
587588
try:
588589
return await receive_message(self, request_id, self.max_message_size)
590+
# Catch KeyboardInterrupt, CancelledError, etc. and cleanup.
589591
except BaseException as error:
590592
self._raise_connection_failure(error)
591593

@@ -1269,6 +1271,7 @@ async def connect(self, handler: Optional[_MongoClientErrorHandler] = None) -> A
12691271

12701272
try:
12711273
sock = await _configured_socket(self.address, self.opts)
1274+
# Catch KeyboardInterrupt, CancelledError, etc. and cleanup.
12721275
except BaseException as error:
12731276
async with self.lock:
12741277
self.active_contexts.discard(tmp_context)
@@ -1308,6 +1311,7 @@ async def connect(self, handler: Optional[_MongoClientErrorHandler] = None) -> A
13081311
handler.contribute_socket(conn, completed_handshake=False)
13091312

13101313
await conn.authenticate()
1314+
# Catch KeyboardInterrupt, CancelledError, etc. and cleanup.
13111315
except BaseException:
13121316
async with self.lock:
13131317
self.active_contexts.discard(conn.cancel_context)
@@ -1369,6 +1373,7 @@ async def checkout(
13691373
async with self.lock:
13701374
self.active_contexts.add(conn.cancel_context)
13711375
yield conn
1376+
# Catch KeyboardInterrupt, CancelledError, etc. and cleanup.
13721377
except BaseException:
13731378
# Exception in caller. Ensure the connection gets returned.
13741379
# Note that when pinned is True, the session owns the
@@ -1515,6 +1520,7 @@ async def _get_conn(
15151520
async with self._max_connecting_cond:
15161521
self._pending -= 1
15171522
self._max_connecting_cond.notify()
1523+
# Catch KeyboardInterrupt, CancelledError, etc. and cleanup.
15181524
except BaseException:
15191525
if conn:
15201526
# We checked out a socket but authentication failed.

pymongo/periodic_executor.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ async def _run(self) -> None:
100100
if not await self._target():
101101
self._stopped = True
102102
break
103+
# Catch KeyboardInterrupt, CancelledError, etc. and cleanup.
103104
except BaseException:
104105
self._stopped = True
105106
raise
@@ -232,6 +233,7 @@ def _run(self) -> None:
232233
if not self._target():
233234
self._stopped = True
234235
break
236+
# Catch KeyboardInterrupt, etc. and cleanup.
235237
except BaseException:
236238
with self._lock:
237239
self._stopped = True

pymongo/synchronous/change_stream.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,8 @@ def try_next(self) -> Optional[_DocumentType]:
389389
if not _resumable(exc) and not exc.timeout:
390390
self.close()
391391
raise
392-
except Exception:
392+
# Catch KeyboardInterrupt, CancelledError, etc. and cleanup.
393+
except BaseException:
393394
self.close()
394395
raise
395396

pymongo/synchronous/client_session.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,8 @@ def callback(session, custom_arg, custom_kwarg=None):
694694
self.start_transaction(read_concern, write_concern, read_preference, max_commit_time_ms)
695695
try:
696696
ret = callback(self)
697-
except Exception as exc:
697+
# Catch KeyboardInterrupt, CancelledError, etc. and cleanup.
698+
except BaseException as exc:
698699
if self.in_transaction:
699700
self.abort_transaction()
700701
if (

0 commit comments

Comments
 (0)