@@ -37,7 +37,7 @@ class TestHttpxRetryTransport():
37
37
@respx .mock
38
38
async def test_no_retry_on_success (self , base_url : str , mocker : MockerFixture ):
39
39
"""Test that a successful response doesn't trigger retries."""
40
- retry_config = HttpxRetry (status = 3 , status_forcelist = [500 ])
40
+ retry_config = HttpxRetry (max_retries = 3 , status_forcelist = [500 ])
41
41
transport = HttpxRetryTransport (retry = retry_config )
42
42
client = httpx .AsyncClient (transport = transport )
43
43
@@ -55,7 +55,7 @@ async def test_no_retry_on_success(self, base_url: str, mocker: MockerFixture):
55
55
@respx .mock
56
56
async def test_no_retry_on_non_retryable_status (self , base_url : str , mocker : MockerFixture ):
57
57
"""Test that a non-retryable error status doesn't trigger retries."""
58
- retry_config = HttpxRetry (status = 3 , status_forcelist = [500 , 503 ])
58
+ retry_config = HttpxRetry (max_retries = 3 , status_forcelist = [500 , 503 ])
59
59
transport = HttpxRetryTransport (retry = retry_config )
60
60
client = httpx .AsyncClient (transport = transport )
61
61
@@ -75,7 +75,7 @@ async def test_retry_on_status_code_success_on_last_retry(
75
75
self , base_url : str , mocker : MockerFixture
76
76
):
77
77
"""Test retry on status code from status_forcelist, succeeding on the last attempt."""
78
- retry_config = HttpxRetry (status = 2 , status_forcelist = [503 , 500 ], backoff_factor = 0.5 )
78
+ retry_config = HttpxRetry (max_retries = 2 , status_forcelist = [503 , 500 ], backoff_factor = 0.5 )
79
79
transport = HttpxRetryTransport (retry = retry_config )
80
80
client = httpx .AsyncClient (transport = transport )
81
81
@@ -101,7 +101,7 @@ async def test_retry_exhausted_returns_last_response(
101
101
self , base_url : str , mocker : MockerFixture
102
102
):
103
103
"""Test that the last response is returned when retries are exhausted."""
104
- retry_config = HttpxRetry (status = 1 , status_forcelist = [500 ], backoff_factor = 0 )
104
+ retry_config = HttpxRetry (max_retries = 1 , status_forcelist = [500 ], backoff_factor = 0 )
105
105
transport = HttpxRetryTransport (retry = retry_config )
106
106
client = httpx .AsyncClient (transport = transport )
107
107
@@ -124,7 +124,8 @@ async def test_retry_exhausted_returns_last_response(
124
124
@respx .mock
125
125
async def test_retry_after_header_seconds (self , base_url : str , mocker : MockerFixture ):
126
126
"""Test respecting Retry-After header with seconds value."""
127
- retry_config = HttpxRetry (status = 1 , respect_retry_after_header = True , backoff_factor = 100 )
127
+ retry_config = HttpxRetry (
128
+ max_retries = 1 , respect_retry_after_header = True , backoff_factor = 100 )
128
129
transport = HttpxRetryTransport (retry = retry_config )
129
130
client = httpx .AsyncClient (transport = transport )
130
131
@@ -146,7 +147,8 @@ async def test_retry_after_header_seconds(self, base_url: str, mocker: MockerFix
146
147
@respx .mock
147
148
async def test_retry_after_header_http_date (self , base_url : str , mocker : MockerFixture ):
148
149
"""Test respecting Retry-After header with an HTTP-date value."""
149
- retry_config = HttpxRetry (status = 1 , respect_retry_after_header = True , backoff_factor = 100 )
150
+ retry_config = HttpxRetry (
151
+ max_retries = 1 , respect_retry_after_header = True , backoff_factor = 100 )
150
152
transport = HttpxRetryTransport (retry = retry_config )
151
153
client = httpx .AsyncClient (transport = transport )
152
154
@@ -181,7 +183,7 @@ async def test_retry_after_header_http_date(self, base_url: str, mocker: MockerF
181
183
async def test_retry_after_ignored_when_disabled (self , base_url : str , mocker : MockerFixture ):
182
184
"""Test Retry-After header is ignored if `respect_retry_after_header` is `False`."""
183
185
retry_config = HttpxRetry (
184
- status = 3 , respect_retry_after_header = False , status_forcelist = [429 ],
186
+ max_retries = 3 , respect_retry_after_header = False , status_forcelist = [429 ],
185
187
backoff_factor = 0.5 , backoff_max = 10 )
186
188
transport = HttpxRetryTransport (retry = retry_config )
187
189
client = httpx .AsyncClient (transport = transport )
@@ -215,7 +217,7 @@ async def test_retry_after_header_missing_backoff_fallback(
215
217
"""Test Retry-After header is ignored if `respect_retry_after_header`is `True` but header is
216
218
not set."""
217
219
retry_config = HttpxRetry (
218
- status = 3 , respect_retry_after_header = True , status_forcelist = [429 ],
220
+ max_retries = 3 , respect_retry_after_header = True , status_forcelist = [429 ],
219
221
backoff_factor = 0.5 , backoff_max = 10 )
220
222
transport = HttpxRetryTransport (retry = retry_config )
221
223
client = httpx .AsyncClient (transport = transport )
@@ -247,7 +249,7 @@ async def test_exponential_backoff(self, base_url: str, mocker: MockerFixture):
247
249
"""Test that sleep time increases exponentially with `backoff_factor`."""
248
250
# status=3 allows 3 retries (attempts 2, 3, 4)
249
251
retry_config = HttpxRetry (
250
- status = 3 , status_forcelist = [500 ], backoff_factor = 0.1 , backoff_max = 10.0 )
252
+ max_retries = 3 , status_forcelist = [500 ], backoff_factor = 0.1 , backoff_max = 10.0 )
251
253
transport = HttpxRetryTransport (retry = retry_config )
252
254
client = httpx .AsyncClient (transport = transport )
253
255
@@ -278,7 +280,7 @@ async def test_backoff_max(self, base_url: str, mocker: MockerFixture):
278
280
"""Test that backoff time respects `backoff_max`."""
279
281
# status=4 allows 4 retries. backoff_factor=1 causes rapid increase.
280
282
retry_config = HttpxRetry (
281
- status = 4 , status_forcelist = [500 ], backoff_factor = 1 , backoff_max = 3.0 )
283
+ max_retries = 4 , status_forcelist = [500 ], backoff_factor = 1 , backoff_max = 3.0 )
282
284
transport = HttpxRetryTransport (retry = retry_config )
283
285
client = httpx .AsyncClient (transport = transport )
284
286
@@ -310,7 +312,7 @@ async def test_backoff_max(self, base_url: str, mocker: MockerFixture):
310
312
async def test_backoff_jitter (self , base_url : str , mocker : MockerFixture ):
311
313
"""Test that `backoff_jitter` adds randomness within bounds."""
312
314
retry_config = HttpxRetry (
313
- status = 3 , status_forcelist = [500 ], backoff_factor = 0.2 , backoff_jitter = 0.1 )
315
+ max_retries = 3 , status_forcelist = [500 ], backoff_factor = 0.2 , backoff_jitter = 0.1 )
314
316
transport = HttpxRetryTransport (retry = retry_config )
315
317
client = httpx .AsyncClient (transport = transport )
316
318
@@ -343,7 +345,7 @@ async def test_backoff_jitter(self, base_url: str, mocker: MockerFixture):
343
345
@respx .mock
344
346
async def test_error_not_retryable (self , base_url ):
345
347
"""Test that non-HTTP errors are raised immediately if not retryable."""
346
- retry_config = HttpxRetry (status = 3 )
348
+ retry_config = HttpxRetry (max_retries = 3 )
347
349
transport = HttpxRetryTransport (retry = retry_config )
348
350
client = httpx .AsyncClient (transport = transport )
349
351
@@ -362,7 +364,7 @@ class TestHttpxRetry():
362
364
363
365
def test_httpx_retry_copy (self , base_url ):
364
366
"""Test that `HttpxRetry.copy()` creates a deep copy."""
365
- original = HttpxRetry (status = 5 , status_forcelist = [500 , 503 ], backoff_factor = 0.5 )
367
+ original = HttpxRetry (max_retries = 5 , status_forcelist = [500 , 503 ], backoff_factor = 0.5 )
366
368
original .history .append ((base_url , None , None )) # Add something mutable
367
369
368
370
copied = original .copy ()
@@ -372,17 +374,17 @@ def test_httpx_retry_copy(self, base_url):
372
374
assert original .history is not copied .history
373
375
374
376
# Assert values are the same initially
375
- assert copied .status == original .status
377
+ assert copied .retries_left == original .retries_left
376
378
assert copied .status_forcelist == original .status_forcelist
377
379
assert copied .backoff_factor == original .backoff_factor
378
380
assert len (copied .history ) == 1
379
381
380
382
# Modify the copy and check original is unchanged
381
- copied .status = 1
383
+ copied .retries_left = 1
382
384
copied .status_forcelist = [404 ]
383
385
copied .history .append ((base_url , None , None ))
384
386
385
- assert original .status == 5
387
+ assert original .retries_left == 5
386
388
assert original .status_forcelist == [500 , 503 ]
387
389
assert len (original .history ) == 1
388
390
@@ -413,7 +415,8 @@ def test_parse_retry_after_invalid_date(self):
413
415
retry ._parse_retry_after ('Invalid Date Format' )
414
416
415
417
def test_get_backoff_time_calculation (self ):
416
- retry = HttpxRetry (status = 6 , status_forcelist = [503 ], backoff_factor = 0.5 , backoff_max = 10.0 )
418
+ retry = HttpxRetry (
419
+ max_retries = 6 , status_forcelist = [503 ], backoff_factor = 0.5 , backoff_max = 10.0 )
417
420
response = httpx .Response (503 )
418
421
# No history -> attempt 1 -> no backoff before first request
419
422
# Note: get_backoff_time() is typically called *before* the *next* request,
@@ -447,5 +450,5 @@ def test_get_backoff_time_calculation(self):
447
450
448
451
# Simulate attempt 6 completed
449
452
retry .increment (self ._TEST_REQUEST , response )
450
- # History len 6, attempt 7 -> 0.5*(2^4 ) = 10.0
453
+ # History len 6, attempt 7 -> 0.5*(2^5 ) = 16.0 Clamped to 10
451
454
assert retry .get_backoff_time () == pytest .approx (10.0 )
0 commit comments