fix: improve cancellation handling in middleware and mixins for Python 3.12+

This commit is contained in:
X-iZhang
2026-02-22 16:20:55 +00:00
parent a2048e4127
commit 7dedf2b426
5 changed files with 20 additions and 7 deletions
+1
View File
@@ -8,6 +8,7 @@ on:
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
+3 -2
View File
@@ -8,13 +8,14 @@ on:
jobs:
ruff:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
- name: Install dependencies
run: pip install -e ".[dev]"
- name: Install ruff
run: pip install ruff
- name: Run ruff
run: ruff check .
+3 -1
View File
@@ -8,6 +8,7 @@ on:
jobs:
pytest:
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
matrix:
python-version: ["3.11", "3.12"]
@@ -21,5 +22,6 @@ jobs:
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
python -m pip install pytest-timeout
- name: Run pytest
run: pytest -v
run: pytest -v --timeout=30
+7 -2
View File
@@ -31,13 +31,18 @@ _logger = logging.getLogger(__name__)
async def _cancel_task(task: asyncio.Task) -> None:
"""Cancel an asyncio task and await its completion.
Suppresses ``CancelledError`` so callers don't need to handle it.
Suppresses ``CancelledError`` from the cancelled *task* but re-raises
if the **current** task was itself cancelled (to avoid swallowing an
outer cancellation signal — required for correct behaviour on
Python 3.12+ where ``_must_cancel`` no longer auto-re-delivers).
"""
task.cancel()
try:
await task
except asyncio.CancelledError:
pass
current = asyncio.current_task()
if current is not None and current.cancelling() > 0:
raise
except Exception:
pass # Already logged elsewhere; prevent unhandled propagation
+6 -2
View File
@@ -252,7 +252,9 @@ class WebSocketMixin:
try:
await task
except asyncio.CancelledError:
pass
current = asyncio.current_task()
if current is not None and current.cancelling() > 0:
raise
except Exception:
pass
@@ -315,6 +317,8 @@ class PollingMixin:
try:
await task
except asyncio.CancelledError:
pass
current = asyncio.current_task()
if current is not None and current.cancelling() > 0:
raise
except Exception:
pass