From 428a88835fedf83d651986b9cbb211f82b2a961b Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Wed, 5 Feb 2025 10:02:30 -0500 Subject: [PATCH 1/3] PYTHON-4993 - Reevaluate handling of asyncio.CancelledError --- pymongo/_client_bulk_shared.py | 3 +++ pymongo/asynchronous/encryption.py | 4 ---- pymongo/asynchronous/mongo_client.py | 7 ------- pymongo/asynchronous/monitor.py | 7 ------- pymongo/asynchronous/pool.py | 2 -- pymongo/synchronous/encryption.py | 5 ----- pymongo/synchronous/mongo_client.py | 7 ------- pymongo/synchronous/monitor.py | 7 ------- pymongo/synchronous/pool.py | 2 -- 9 files changed, 3 insertions(+), 41 deletions(-) diff --git a/pymongo/_client_bulk_shared.py b/pymongo/_client_bulk_shared.py index 649f1c6aa0..dfa3ae807e 100644 --- a/pymongo/_client_bulk_shared.py +++ b/pymongo/_client_bulk_shared.py @@ -16,6 +16,7 @@ """Constants, types, and classes shared across Client Bulk Write API implementations.""" from __future__ import annotations +import asyncio from typing import TYPE_CHECKING, Any, Mapping, MutableMapping, NoReturn from pymongo.errors import ClientBulkWriteException, OperationFailure @@ -75,5 +76,7 @@ def _throw_client_bulk_write_exception( ) raise OperationFailure(errmsg, code, full_result) if isinstance(full_result["error"], BaseException): + if isinstance(full_result["error"], asyncio.CancelledError): + raise raise ClientBulkWriteException(full_result, verbose_results) from full_result["error"] raise ClientBulkWriteException(full_result, verbose_results) diff --git a/pymongo/asynchronous/encryption.py b/pymongo/asynchronous/encryption.py index f777104cf5..9d3ea67191 100644 --- a/pymongo/asynchronous/encryption.py +++ b/pymongo/asynchronous/encryption.py @@ -127,8 +127,6 @@ def _wrap_encryption_errors() -> Iterator[None]: # BSON encoding/decoding errors are unrelated to encryption so # we should propagate them unchanged. raise - except asyncio.CancelledError: - raise except Exception as exc: raise EncryptionError(exc) from exc @@ -766,8 +764,6 @@ async def create_encrypted_collection( await database.create_collection(name=name, **kwargs), encrypted_fields, ) - except asyncio.CancelledError: - raise except Exception as exc: raise EncryptedCollectionError(exc, encrypted_fields) from exc diff --git a/pymongo/asynchronous/mongo_client.py b/pymongo/asynchronous/mongo_client.py index cf7de19c2f..8504147743 100644 --- a/pymongo/asynchronous/mongo_client.py +++ b/pymongo/asynchronous/mongo_client.py @@ -32,7 +32,6 @@ """ from __future__ import annotations -import asyncio import contextlib import os import warnings @@ -2038,8 +2037,6 @@ async def _process_kill_cursors(self) -> None: for address, cursor_id, conn_mgr in pinned_cursors: try: await self._cleanup_cursor_lock(cursor_id, address, conn_mgr, None, False) - except asyncio.CancelledError: - raise except Exception as exc: if isinstance(exc, InvalidOperation) and self._topology._closed: # Raise the exception when client is closed so that it @@ -2054,8 +2051,6 @@ async def _process_kill_cursors(self) -> None: for address, cursor_ids in address_to_cursor_ids.items(): try: await self._kill_cursors(cursor_ids, address, topology, session=None) - except asyncio.CancelledError: - raise except Exception as exc: if isinstance(exc, InvalidOperation) and self._topology._closed: raise @@ -2070,8 +2065,6 @@ async def _process_periodic_tasks(self) -> None: try: await self._process_kill_cursors() await self._topology.update_pool() - except asyncio.CancelledError: - raise except Exception as exc: if isinstance(exc, InvalidOperation) and self._topology._closed: return diff --git a/pymongo/asynchronous/monitor.py b/pymongo/asynchronous/monitor.py index ad1bc70aba..5c4ecd8e93 100644 --- a/pymongo/asynchronous/monitor.py +++ b/pymongo/asynchronous/monitor.py @@ -16,7 +16,6 @@ from __future__ import annotations -import asyncio import atexit import logging import time @@ -257,8 +256,6 @@ async def _check_server(self) -> ServerDescription: details = cast(Mapping[str, Any], exc.details) await self._topology.receive_cluster_time(details.get("$clusterTime")) raise - except asyncio.CancelledError: - raise except ReferenceError: raise except Exception as error: @@ -424,8 +421,6 @@ def _get_seedlist(self) -> Optional[list[tuple[str, Any]]]: if len(seedlist) == 0: # As per the spec: this should be treated as a failure. raise Exception - except asyncio.CancelledError: - raise except Exception: # As per the spec, upon encountering an error: # - An error must not be raised @@ -489,8 +484,6 @@ async def _run(self) -> None: except ReferenceError: # Topology was garbage-collected. await self.close() - except asyncio.CancelledError: - raise except Exception: await self._pool.reset() diff --git a/pymongo/asynchronous/pool.py b/pymongo/asynchronous/pool.py index bf2f2b4946..a6eeb25e4f 100644 --- a/pymongo/asynchronous/pool.py +++ b/pymongo/asynchronous/pool.py @@ -704,8 +704,6 @@ def _close_conn(self) -> None: # shutdown. try: self.conn.close() - except asyncio.CancelledError: - raise except Exception: # noqa: S110 pass diff --git a/pymongo/synchronous/encryption.py b/pymongo/synchronous/encryption.py index 59f38e1913..7cbac1c509 100644 --- a/pymongo/synchronous/encryption.py +++ b/pymongo/synchronous/encryption.py @@ -15,7 +15,6 @@ """Support for explicit client-side field level encryption.""" from __future__ import annotations -import asyncio import contextlib import enum import socket @@ -127,8 +126,6 @@ def _wrap_encryption_errors() -> Iterator[None]: # BSON encoding/decoding errors are unrelated to encryption so # we should propagate them unchanged. raise - except asyncio.CancelledError: - raise except Exception as exc: raise EncryptionError(exc) from exc @@ -760,8 +757,6 @@ def create_encrypted_collection( database.create_collection(name=name, **kwargs), encrypted_fields, ) - except asyncio.CancelledError: - raise except Exception as exc: raise EncryptedCollectionError(exc, encrypted_fields) from exc diff --git a/pymongo/synchronous/mongo_client.py b/pymongo/synchronous/mongo_client.py index 706623c214..f32d5d1b43 100644 --- a/pymongo/synchronous/mongo_client.py +++ b/pymongo/synchronous/mongo_client.py @@ -32,7 +32,6 @@ """ from __future__ import annotations -import asyncio import contextlib import os import warnings @@ -2032,8 +2031,6 @@ def _process_kill_cursors(self) -> None: for address, cursor_id, conn_mgr in pinned_cursors: try: self._cleanup_cursor_lock(cursor_id, address, conn_mgr, None, False) - except asyncio.CancelledError: - raise except Exception as exc: if isinstance(exc, InvalidOperation) and self._topology._closed: # Raise the exception when client is closed so that it @@ -2048,8 +2045,6 @@ def _process_kill_cursors(self) -> None: for address, cursor_ids in address_to_cursor_ids.items(): try: self._kill_cursors(cursor_ids, address, topology, session=None) - except asyncio.CancelledError: - raise except Exception as exc: if isinstance(exc, InvalidOperation) and self._topology._closed: raise @@ -2064,8 +2059,6 @@ def _process_periodic_tasks(self) -> None: try: self._process_kill_cursors() self._topology.update_pool() - except asyncio.CancelledError: - raise except Exception as exc: if isinstance(exc, InvalidOperation) and self._topology._closed: return diff --git a/pymongo/synchronous/monitor.py b/pymongo/synchronous/monitor.py index df4130d4ab..b4e2bc6735 100644 --- a/pymongo/synchronous/monitor.py +++ b/pymongo/synchronous/monitor.py @@ -16,7 +16,6 @@ from __future__ import annotations -import asyncio import atexit import logging import time @@ -257,8 +256,6 @@ def _check_server(self) -> ServerDescription: details = cast(Mapping[str, Any], exc.details) self._topology.receive_cluster_time(details.get("$clusterTime")) raise - except asyncio.CancelledError: - raise except ReferenceError: raise except Exception as error: @@ -424,8 +421,6 @@ def _get_seedlist(self) -> Optional[list[tuple[str, Any]]]: if len(seedlist) == 0: # As per the spec: this should be treated as a failure. raise Exception - except asyncio.CancelledError: - raise except Exception: # As per the spec, upon encountering an error: # - An error must not be raised @@ -489,8 +484,6 @@ def _run(self) -> None: except ReferenceError: # Topology was garbage-collected. self.close() - except asyncio.CancelledError: - raise except Exception: self._pool.reset() diff --git a/pymongo/synchronous/pool.py b/pymongo/synchronous/pool.py index 05f930d480..1e9a98cc14 100644 --- a/pymongo/synchronous/pool.py +++ b/pymongo/synchronous/pool.py @@ -702,8 +702,6 @@ def _close_conn(self) -> None: # shutdown. try: self.conn.close() - except asyncio.CancelledError: - raise except Exception: # noqa: S110 pass From 633d0c15755925a98ff561fb78d67ffdd52f3876 Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Mon, 10 Feb 2025 08:40:13 -0500 Subject: [PATCH 2/3] Remove _throw_client_bulk_write_exception case --- pymongo/_client_bulk_shared.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/pymongo/_client_bulk_shared.py b/pymongo/_client_bulk_shared.py index dfa3ae807e..649f1c6aa0 100644 --- a/pymongo/_client_bulk_shared.py +++ b/pymongo/_client_bulk_shared.py @@ -16,7 +16,6 @@ """Constants, types, and classes shared across Client Bulk Write API implementations.""" from __future__ import annotations -import asyncio from typing import TYPE_CHECKING, Any, Mapping, MutableMapping, NoReturn from pymongo.errors import ClientBulkWriteException, OperationFailure @@ -76,7 +75,5 @@ def _throw_client_bulk_write_exception( ) raise OperationFailure(errmsg, code, full_result) if isinstance(full_result["error"], BaseException): - if isinstance(full_result["error"], asyncio.CancelledError): - raise raise ClientBulkWriteException(full_result, verbose_results) from full_result["error"] raise ClientBulkWriteException(full_result, verbose_results) From 8966a9e6e521ed23f61b24ea23ff5c88df807605 Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Mon, 10 Feb 2025 14:33:11 -0500 Subject: [PATCH 3/3] Fix imports --- pymongo/asynchronous/mongo_client.py | 1 + pymongo/asynchronous/monitor.py | 1 + pymongo/synchronous/mongo_client.py | 1 + pymongo/synchronous/monitor.py | 1 + 4 files changed, 4 insertions(+) diff --git a/pymongo/asynchronous/mongo_client.py b/pymongo/asynchronous/mongo_client.py index 13da86f285..43ae589648 100644 --- a/pymongo/asynchronous/mongo_client.py +++ b/pymongo/asynchronous/mongo_client.py @@ -32,6 +32,7 @@ """ from __future__ import annotations +import asyncio import contextlib import os import warnings diff --git a/pymongo/asynchronous/monitor.py b/pymongo/asynchronous/monitor.py index 294a4c81d4..15289af4dc 100644 --- a/pymongo/asynchronous/monitor.py +++ b/pymongo/asynchronous/monitor.py @@ -16,6 +16,7 @@ from __future__ import annotations +import asyncio import atexit import logging import time diff --git a/pymongo/synchronous/mongo_client.py b/pymongo/synchronous/mongo_client.py index 3b8364a0b2..fd37ed9f8a 100644 --- a/pymongo/synchronous/mongo_client.py +++ b/pymongo/synchronous/mongo_client.py @@ -32,6 +32,7 @@ """ from __future__ import annotations +import asyncio import contextlib import os import warnings diff --git a/pymongo/synchronous/monitor.py b/pymongo/synchronous/monitor.py index c2332fc1e2..802ba4742f 100644 --- a/pymongo/synchronous/monitor.py +++ b/pymongo/synchronous/monitor.py @@ -16,6 +16,7 @@ from __future__ import annotations +import asyncio import atexit import logging import time