Skip to content

Commit 20e8fd0

Browse files
Fix asyncio.CancelledError detection and add test coverage
- Fix module check to use startswith("asyncio") instead of == "asyncio" to properly match asyncio.exceptions.CancelledError - Add test case for asyncio.CancelledError to verify it bypasses retry loop Addresses review feedback from chatgpt-codex-connector bot
1 parent 1721d58 commit 20e8fd0

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

repos/anthropic-sdk-python

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 506a6cd37afb791f5d61760375eab841916921bd

src/openai/_base_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def _should_not_retry(exc: Exception) -> bool:
112112
return True
113113

114114
# asyncio cancellation
115-
if exc_module == "asyncio" and exc_name == "CancelledError":
115+
if exc_module.startswith("asyncio") and exc_name == "CancelledError":
116116
return True
117117

118118
return False

tests/test_client.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,37 @@ class MockCelerySoftTimeLimitExceeded(Exception):
916916
# Verify only one attempt was made (no retries)
917917
assert len(respx_mock.calls) == 1
918918

919+
@mock.patch("openai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
920+
@pytest.mark.respx(base_url=base_url)
921+
def test_asyncio_cancelled_error_not_retried(self, respx_mock: MockRouter, client: OpenAI) -> None:
922+
"""Test that asyncio.CancelledError is not retried."""
923+
client = client.with_options(max_retries=3)
924+
925+
# Create a mock exception that mimics asyncio.exceptions.CancelledError
926+
class MockCancelledError(Exception):
927+
"""Mock of asyncio.exceptions.CancelledError"""
928+
929+
__module__ = "asyncio.exceptions"
930+
__name__ = "CancelledError"
931+
932+
# Mock the request to raise our cancellation signal
933+
respx_mock.post("/chat/completions").mock(side_effect=MockCancelledError("Task cancelled"))
934+
935+
# Verify the exception propagates without retry
936+
with pytest.raises(MockCancelledError):
937+
client.chat.completions.create(
938+
messages=[
939+
{
940+
"content": "string",
941+
"role": "developer",
942+
}
943+
],
944+
model="gpt-4o",
945+
)
946+
947+
# Verify only one attempt was made (no retries)
948+
assert len(respx_mock.calls) == 1
949+
919950
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
920951
@mock.patch("openai._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
921952
@pytest.mark.respx(base_url=base_url)

0 commit comments

Comments
 (0)