From 8d2ed96fd6e781e210e6985aa0be7980e068ae94 Mon Sep 17 00:00:00 2001
From: ColtenOuO <jun930436@gmail.com>
Date: Fri, 1 May 2026 06:13:48 +0000
Subject: [PATCH] Use contextlib.suppress instead of try-except-pass in
 providers

Signed-off-by: ColtenOuO <jun930436@gmail.com>
---
 .../airflow/providers/amazon/aws/hooks/eks.py   |  5 ++---
 .../providers/amazon/aws/operators/eks.py       |  5 ++---
 .../system/amazon/aws/example_s3_tables.py      | 10 ++++------
 .../celery/executors/celery_executor_utils.py   | 10 ++++------
 .../providers/cncf/kubernetes/operators/pod.py  |  6 ++----
 .../providers/cncf/kubernetes/triggers/pod.py   |  5 ++---
 .../decorators/test_kubernetes_commons.py       |  5 ++---
 .../providers/common/ai/durable/storage.py      |  6 +++---
 .../ssh/src/airflow/providers/ssh/tunnel.py     | 17 +++++------------
 9 files changed, 26 insertions(+), 43 deletions(-)

diff --git a/providers/amazon/src/airflow/providers/amazon/aws/hooks/eks.py b/providers/amazon/src/airflow/providers/amazon/aws/hooks/eks.py
index 08f78540e6530..fd0dd09876ca0 100644
--- a/providers/amazon/src/airflow/providers/amazon/aws/hooks/eks.py
+++ b/providers/amazon/src/airflow/providers/amazon/aws/hooks/eks.py
@@ -586,10 +586,9 @@ def _secure_credential_context(
             if fd is not None:
                 os.close(fd)
             if temp_path and os.path.exists(temp_path):
-                try:
+                # Best effort cleanup
+                with contextlib.suppress(OSError):
                     os.unlink(temp_path)
-                except OSError:
-                    pass  # Best effort cleanup
 
     @contextmanager
     def generate_config_file(
diff --git a/providers/amazon/src/airflow/providers/amazon/aws/operators/eks.py b/providers/amazon/src/airflow/providers/amazon/aws/operators/eks.py
index cf6d147bdcfc6..7ab58406ffbf6 100644
--- a/providers/amazon/src/airflow/providers/amazon/aws/operators/eks.py
+++ b/providers/amazon/src/airflow/providers/amazon/aws/operators/eks.py
@@ -18,6 +18,7 @@
 
 from __future__ import annotations
 
+import contextlib
 import logging
 import os
 import stat
@@ -1277,10 +1278,8 @@ def _write_credentials_to_file(
                     f.write(f"export AWS_SESSION_TOKEN='{session_token}'\n")
         except Exception:
             # If fdopen fails, we need to close the file descriptor manually
-            try:
+            with contextlib.suppress(OSError):
                 os.close(fd)
-            except OSError:
-                pass
             raise
 
     def _refresh_cached_properties(self) -> None:
diff --git a/providers/amazon/tests/system/amazon/aws/example_s3_tables.py b/providers/amazon/tests/system/amazon/aws/example_s3_tables.py
index b91aff47ec35e..a46c0f1b15d28 100644
--- a/providers/amazon/tests/system/amazon/aws/example_s3_tables.py
+++ b/providers/amazon/tests/system/amazon/aws/example_s3_tables.py
@@ -32,6 +32,8 @@
     from airflow.decorators import task  # type: ignore[attr-defined,no-redef]
     from airflow.utils.trigger_rule import TriggerRule  # type: ignore[no-redef,attr-defined]
 
+import contextlib
+
 from system.amazon.aws.utils import ENV_ID_KEY, SystemTestContextBuilder
 
 DAG_ID = "example_s3tables"
@@ -83,10 +85,8 @@ def delete_namespace(table_bucket_arn: str, namespace: str):
         import boto3
 
         client = boto3.client("s3tables")
-        try:
+        with contextlib.suppress(client.exceptions.NotFoundException):
             client.delete_namespace(tableBucketARN=table_bucket_arn, namespace=namespace)
-        except client.exceptions.NotFoundException:
-            pass
 
     @task(trigger_rule=TriggerRule.ALL_DONE)
     def delete_table_bucket(table_bucket_arn: str):
@@ -94,10 +94,8 @@ def delete_table_bucket(table_bucket_arn: str):
         import boto3
 
         client = boto3.client("s3tables")
-        try:
+        with contextlib.suppress(client.exceptions.NotFoundException):
             client.delete_table_bucket(tableBucketARN=table_bucket_arn)
-        except client.exceptions.NotFoundException:
-            pass
 
     bucket_arn = create_table_bucket(name=bucket_name)
     setup_namespace = create_namespace(table_bucket_arn=bucket_arn, namespace=namespace)
diff --git a/providers/celery/src/airflow/providers/celery/executors/celery_executor_utils.py b/providers/celery/src/airflow/providers/celery/executors/celery_executor_utils.py
index 0d67b5d6fc569..9b5a9ae759a27 100644
--- a/providers/celery/src/airflow/providers/celery/executors/celery_executor_utils.py
+++ b/providers/celery/src/airflow/providers/celery/executors/celery_executor_utils.py
@@ -432,10 +432,9 @@ def send_workload_to_executor(
     # If timeout fires during import, redis module gets partially cached in sys.modules
     # without the 'client' submodule bound, causing AttributeError on subsequent access.
     # See: https://github.com/apache/airflow/issues/41359
-    try:
+    # Redis not installed or not using Redis backend.
+    with contextlib.suppress(ImportError):
         import redis.client  # noqa: F401
-    except ImportError:
-        pass  # Redis not installed or not using Redis backend.
 
     try:
         with timeout(seconds=OPERATION_TIMEOUT):
@@ -462,10 +461,9 @@ def fetch_celery_task_state(async_result: AsyncResult) -> tuple[str, str | Excep
     """
     # Pre-import redis.client to avoid SIGALRM interrupting module initialization.
     # See: https://github.com/apache/airflow/issues/41359
-    try:
+    # Redis not installed or not using Redis backend.
+    with contextlib.suppress(ImportError):
         import redis.client  # noqa: F401
-    except ImportError:
-        pass  # Redis not installed or not using Redis backend.
 
     try:
         with timeout(seconds=OPERATION_TIMEOUT):
diff --git a/providers/cncf/kubernetes/src/airflow/providers/cncf/kubernetes/operators/pod.py b/providers/cncf/kubernetes/src/airflow/providers/cncf/kubernetes/operators/pod.py
index dfe82b552245d..cead818799770 100644
--- a/providers/cncf/kubernetes/src/airflow/providers/cncf/kubernetes/operators/pod.py
+++ b/providers/cncf/kubernetes/src/airflow/providers/cncf/kubernetes/operators/pod.py
@@ -29,7 +29,7 @@
 import shlex
 import string
 from collections.abc import Callable, Container, Iterable, Sequence
-from contextlib import AbstractContextManager
+from contextlib import AbstractContextManager, suppress
 from enum import Enum
 from functools import cached_property
 from typing import TYPE_CHECKING, Any, Literal
@@ -657,10 +657,8 @@ async def _await_pod_start():
                 finally:
                     # Stop watching events
                     events_task.cancel()
-                    try:
+                    with suppress(asyncio.CancelledError):
                         await events_task
-                    except asyncio.CancelledError:
-                        pass
 
             asyncio.run(_await_pod_start())
         except PodLaunchFailedException:
diff --git a/providers/cncf/kubernetes/src/airflow/providers/cncf/kubernetes/triggers/pod.py b/providers/cncf/kubernetes/src/airflow/providers/cncf/kubernetes/triggers/pod.py
index 313c84167b65d..fc9ec300a0cdc 100644
--- a/providers/cncf/kubernetes/src/airflow/providers/cncf/kubernetes/triggers/pod.py
+++ b/providers/cncf/kubernetes/src/airflow/providers/cncf/kubernetes/triggers/pod.py
@@ -17,6 +17,7 @@
 from __future__ import annotations
 
 import asyncio
+import contextlib
 import datetime
 import traceback
 from collections.abc import AsyncIterator
@@ -288,10 +289,8 @@ async def _wait_for_pod_start(self) -> ContainerState:
         finally:
             # Stop watching events
             events_task.cancel()
-            try:
+            with contextlib.suppress(asyncio.CancelledError):
                 await events_task
-            except asyncio.CancelledError:
-                pass
 
         return self.define_container_state(await self._get_pod())
 
diff --git a/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/decorators/test_kubernetes_commons.py b/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/decorators/test_kubernetes_commons.py
index 29f261b698929..9a23349956f91 100644
--- a/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/decorators/test_kubernetes_commons.py
+++ b/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/decorators/test_kubernetes_commons.py
@@ -16,6 +16,7 @@
 # under the License.
 from __future__ import annotations
 
+import contextlib
 from collections.abc import Callable
 from unittest import mock
 
@@ -117,10 +118,8 @@ def setup(self, dag_maker):
         self.mock_fetch_logs = mock.patch(f"{POD_MANAGER_CLASS}.fetch_requested_container_logs").start()
         self.mock_fetch_logs.return_value = "logs"
 
-        try:
+        with contextlib.suppress(Exception):
             yield
-        except Exception:
-            pass
         mock.patch.stopall()
 
     def teardown_method(self):
diff --git a/providers/common/ai/src/airflow/providers/common/ai/durable/storage.py b/providers/common/ai/src/airflow/providers/common/ai/durable/storage.py
index 3129aa8dfe2f9..d4437b18d11e1 100644
--- a/providers/common/ai/src/airflow/providers/common/ai/durable/storage.py
+++ b/providers/common/ai/src/airflow/providers/common/ai/durable/storage.py
@@ -18,6 +18,7 @@
 
 from __future__ import annotations
 
+import contextlib
 import json
 from functools import lru_cache
 from typing import Any
@@ -150,9 +151,8 @@ def load_tool_result(self, key: str) -> tuple[bool, Any]:
 
     def cleanup(self) -> None:
         """Delete the cache file after successful execution."""
-        try:
+        # Best-effort cleanup
+        with contextlib.suppress(FileNotFoundError, OSError):
             self._get_path().unlink()
-        except (FileNotFoundError, OSError):
-            pass  # Best-effort cleanup
         self._cache = None
         log.debug("Durable cache cleaned up")
diff --git a/providers/ssh/src/airflow/providers/ssh/tunnel.py b/providers/ssh/src/airflow/providers/ssh/tunnel.py
index 69bb00743e6d9..f514ebaf6cc3c 100644
--- a/providers/ssh/src/airflow/providers/ssh/tunnel.py
+++ b/providers/ssh/src/airflow/providers/ssh/tunnel.py
@@ -52,6 +52,7 @@
 
 from __future__ import annotations
 
+import contextlib
 import logging
 import socket
 import threading
@@ -222,28 +223,22 @@ def _stop_forwarding(self) -> None:
         self._running = False
         # Wake the select loop
         if self._shutdown_w is not None:
-            try:
+            with contextlib.suppress(OSError):
                 self._shutdown_w.send(b"\x00")
-            except OSError:
-                pass
         if self._thread is not None:
             self._thread.join(timeout=5)
             self._thread = None
         # Close the shutdown pair
         for sock in (self._shutdown_r, self._shutdown_w):
             if sock is not None:
-                try:
+                with contextlib.suppress(OSError):
                     sock.close()
-                except OSError:
-                    pass
         self._shutdown_r = None
         self._shutdown_w = None
         # Close the server socket
         if self._server_socket is not None:
-            try:
+            with contextlib.suppress(OSError):
                 self._server_socket.close()
-            except OSError:
-                pass
             self._server_socket = None
 
     def _serve_forever(self) -> None:
@@ -357,10 +352,8 @@ def _forward_data(
     def _close_pair(local_sock: socket.socket, chan: paramiko.Channel) -> None:
         """Close both ends of a forwarded connection."""
         for closeable in (chan, local_sock):
-            try:
+            with contextlib.suppress(OSError):
                 closeable.close()
-            except OSError:
-                pass
 
 
 class AsyncSSHTunnel:
