Skip to content

Commit 71007ec

Browse files
BYKclaude
andcommitted
fix: Suppress PytestUnraisableExceptionWarning for async worker tests
On Python 3.8, cancelled asyncio coroutines that were awaiting Queue.get() raise GeneratorExit during garbage collection, triggering PytestUnraisableExceptionWarning. This is a Python 3.8 asyncio limitation, not a real bug. Suppress the warning for async worker tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 299947d commit 71007ec

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

tests/test_transport.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,7 @@ async def test_async_two_way_ssl_authentication():
11641164
@skip_under_gevent
11651165
@pytest.mark.asyncio
11661166
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1167+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
11671168
async def test_async_worker_init():
11681169
"""Test AsyncWorker.__init__ sets up default state correctly."""
11691170
from sentry_sdk.worker import AsyncWorker
@@ -1180,6 +1181,7 @@ async def test_async_worker_init():
11801181
@skip_under_gevent
11811182
@pytest.mark.asyncio
11821183
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1184+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
11831185
async def test_async_worker_is_alive_not_started():
11841186
"""Test is_alive returns False before start()."""
11851187
from sentry_sdk.worker import AsyncWorker
@@ -1191,6 +1193,7 @@ async def test_async_worker_is_alive_not_started():
11911193
@skip_under_gevent
11921194
@pytest.mark.asyncio
11931195
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1196+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
11941197
async def test_async_worker_is_alive_after_start():
11951198
"""Test is_alive returns True after start() in a running loop."""
11961199
from sentry_sdk.worker import AsyncWorker
@@ -1205,6 +1208,7 @@ async def test_async_worker_is_alive_after_start():
12051208
@skip_under_gevent
12061209
@pytest.mark.asyncio
12071210
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1211+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
12081212
async def test_async_worker_is_alive_wrong_pid():
12091213
"""Test is_alive returns False when pid mismatches."""
12101214
from sentry_sdk.worker import AsyncWorker
@@ -1225,6 +1229,7 @@ async def test_async_worker_is_alive_wrong_pid():
12251229
@skip_under_gevent
12261230
@pytest.mark.asyncio
12271231
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1232+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
12281233
async def test_async_worker_is_alive_no_loop():
12291234
"""Test is_alive returns False when loop is None."""
12301235
from sentry_sdk.worker import AsyncWorker
@@ -1238,6 +1243,7 @@ async def test_async_worker_is_alive_no_loop():
12381243
@skip_under_gevent
12391244
@pytest.mark.asyncio
12401245
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1246+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
12411247
async def test_async_worker_start_creates_queue_and_task():
12421248
"""Test start() creates asyncio queue and consumer task."""
12431249
from sentry_sdk.worker import AsyncWorker
@@ -1269,6 +1275,7 @@ def test_async_worker_start_no_running_loop():
12691275
@skip_under_gevent
12701276
@pytest.mark.asyncio
12711277
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1278+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
12721279
async def test_async_worker_start_reuses_existing_queue():
12731280
"""Test start() reuses existing queue if already created."""
12741281
from sentry_sdk.worker import AsyncWorker
@@ -1288,6 +1295,7 @@ async def test_async_worker_start_reuses_existing_queue():
12881295
@skip_under_gevent
12891296
@pytest.mark.asyncio
12901297
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1298+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
12911299
async def test_async_worker_full_when_queue_is_none():
12921300
"""Test full() returns True when queue is None."""
12931301
from sentry_sdk.worker import AsyncWorker
@@ -1299,6 +1307,7 @@ async def test_async_worker_full_when_queue_is_none():
12991307
@skip_under_gevent
13001308
@pytest.mark.asyncio
13011309
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1310+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
13021311
async def test_async_worker_full_when_not_full():
13031312
"""Test full() returns False when queue has capacity."""
13041313
from sentry_sdk.worker import AsyncWorker
@@ -1313,6 +1322,7 @@ async def test_async_worker_full_when_not_full():
13131322
@skip_under_gevent
13141323
@pytest.mark.asyncio
13151324
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1325+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
13161326
async def test_async_worker_full_when_full():
13171327
"""Test full() returns True when queue is at capacity."""
13181328
from sentry_sdk.worker import AsyncWorker
@@ -1337,6 +1347,7 @@ async def slow_cb():
13371347
@skip_under_gevent
13381348
@pytest.mark.asyncio
13391349
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1350+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
13401351
async def test_async_worker_submit_and_process():
13411352
"""Test submit() queues a callback and it gets processed."""
13421353
from sentry_sdk.worker import AsyncWorker
@@ -1359,6 +1370,7 @@ async def callback():
13591370
@skip_under_gevent
13601371
@pytest.mark.asyncio
13611372
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1373+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
13621374
async def test_async_worker_submit_returns_false_when_queue_full():
13631375
"""Test submit() returns False when queue is full."""
13641376
from sentry_sdk.worker import AsyncWorker
@@ -1382,6 +1394,7 @@ async def slow_cb():
13821394
@skip_under_gevent
13831395
@pytest.mark.asyncio
13841396
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1397+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
13851398
async def test_async_worker_submit_returns_false_when_no_queue():
13861399
"""Test submit() returns False when no queue (no running loop during start)."""
13871400
from sentry_sdk.worker import AsyncWorker
@@ -1396,6 +1409,7 @@ async def test_async_worker_submit_returns_false_when_no_queue():
13961409
@skip_under_gevent
13971410
@pytest.mark.asyncio
13981411
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1412+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
13991413
async def test_async_worker_kill_cancels_tasks():
14001414
"""Test kill() cancels the main task and active callback tasks."""
14011415
from sentry_sdk.worker import AsyncWorker
@@ -1429,6 +1443,7 @@ async def slow_callback():
14291443
@skip_under_gevent
14301444
@pytest.mark.asyncio
14311445
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1446+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
14321447
async def test_async_worker_kill_queue_full():
14331448
"""Test kill() handles QueueFull when adding terminator."""
14341449
from sentry_sdk.worker import AsyncWorker
@@ -1452,6 +1467,7 @@ async def slow_cb():
14521467
@skip_under_gevent
14531468
@pytest.mark.asyncio
14541469
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1470+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
14551471
async def test_async_worker_kill_no_task():
14561472
"""Test kill() is a no-op when there's no task."""
14571473
from sentry_sdk.worker import AsyncWorker
@@ -1466,6 +1482,7 @@ async def test_async_worker_kill_no_task():
14661482
@skip_under_gevent
14671483
@pytest.mark.asyncio
14681484
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1485+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
14691486
async def test_async_worker_flush_returns_task():
14701487
"""Test flush() returns an asyncio task when alive."""
14711488
from sentry_sdk.worker import AsyncWorker
@@ -1483,6 +1500,7 @@ async def test_async_worker_flush_returns_task():
14831500
@skip_under_gevent
14841501
@pytest.mark.asyncio
14851502
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1503+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
14861504
async def test_async_worker_flush_returns_none_when_not_alive():
14871505
"""Test flush() returns None when worker is not alive."""
14881506
from sentry_sdk.worker import AsyncWorker
@@ -1494,6 +1512,7 @@ async def test_async_worker_flush_returns_none_when_not_alive():
14941512
@skip_under_gevent
14951513
@pytest.mark.asyncio
14961514
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1515+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
14971516
async def test_async_worker_flush_returns_none_zero_timeout():
14981517
"""Test flush() returns None when timeout is 0."""
14991518
from sentry_sdk.worker import AsyncWorker
@@ -1508,6 +1527,7 @@ async def test_async_worker_flush_returns_none_zero_timeout():
15081527
@skip_under_gevent
15091528
@pytest.mark.asyncio
15101529
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1530+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
15111531
async def test_async_worker_wait_flush_early_return_no_loop():
15121532
"""Test _wait_flush returns early if loop/queue is None."""
15131533
from sentry_sdk.worker import AsyncWorker
@@ -1521,6 +1541,7 @@ async def test_async_worker_wait_flush_early_return_no_loop():
15211541
@skip_under_gevent
15221542
@pytest.mark.asyncio
15231543
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1544+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
15241545
async def test_async_worker_wait_flush_with_callback():
15251546
"""Test _wait_flush calls callback on initial timeout."""
15261547
from sentry_sdk.worker import AsyncWorker
@@ -1549,6 +1570,7 @@ async def slow_cb():
15491570
@skip_under_gevent
15501571
@pytest.mark.asyncio
15511572
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1573+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
15521574
async def test_async_worker_wait_flush_second_timeout():
15531575
"""Test _wait_flush logs error on second timeout."""
15541576
from sentry_sdk.worker import AsyncWorker
@@ -1575,6 +1597,7 @@ async def very_slow_cb():
15751597
@skip_under_gevent
15761598
@pytest.mark.asyncio
15771599
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1600+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
15781601
async def test_async_worker_target_terminator():
15791602
"""Test _target exits on _TERMINATOR sentinel."""
15801603
from sentry_sdk.worker import AsyncWorker, _TERMINATOR
@@ -1591,6 +1614,7 @@ async def test_async_worker_target_terminator():
15911614
@skip_under_gevent
15921615
@pytest.mark.asyncio
15931616
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1617+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
15941618
async def test_async_worker_target_with_none_queue():
15951619
"""Test _target returns immediately when queue is None."""
15961620
from sentry_sdk.worker import AsyncWorker
@@ -1604,6 +1628,7 @@ async def test_async_worker_target_with_none_queue():
16041628
@skip_under_gevent
16051629
@pytest.mark.asyncio
16061630
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1631+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
16071632
async def test_async_worker_on_task_complete_cancelled_error():
16081633
"""Test _on_task_complete handles CancelledError gracefully."""
16091634
from sentry_sdk.worker import AsyncWorker
@@ -1640,6 +1665,7 @@ async def will_be_cancelled():
16401665
@skip_under_gevent
16411666
@pytest.mark.asyncio
16421667
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1668+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
16431669
async def test_async_worker_on_task_complete_exception():
16441670
"""Test _on_task_complete logs error on exception."""
16451671
from sentry_sdk.worker import AsyncWorker
@@ -1663,6 +1689,7 @@ async def failing_cb():
16631689
@skip_under_gevent
16641690
@pytest.mark.asyncio
16651691
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1692+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
16661693
async def test_async_worker_on_task_complete_queue_none():
16671694
"""Test _on_task_complete handles queue being None (e.g., during shutdown)."""
16681695
from sentry_sdk.worker import AsyncWorker
@@ -1693,6 +1720,7 @@ async def simple_cb():
16931720
@skip_under_gevent
16941721
@pytest.mark.asyncio
16951722
@pytest.mark.skipif(not PY38, reason="AsyncWorker requires Python 3.8+")
1723+
@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning")
16961724
async def test_async_worker_ensure_task_calls_start():
16971725
"""Test _ensure_task calls start() when not alive."""
16981726
from sentry_sdk.worker import AsyncWorker

0 commit comments

Comments
 (0)