@@ -123,6 +123,26 @@ def get_status() -> str:
123123 assert attempts ["count" ] == 1
124124
125125
126+ def test_poll_until_terminal_status_does_not_retry_stop_iteration_errors ():
127+ attempts = {"count" : 0 }
128+
129+ def get_status () -> str :
130+ attempts ["count" ] += 1
131+ raise StopIteration ("callback exhausted" )
132+
133+ with pytest .raises (StopIteration , match = "callback exhausted" ):
134+ poll_until_terminal_status (
135+ operation_name = "sync poll stop-iteration passthrough" ,
136+ get_status = get_status ,
137+ is_terminal_status = lambda value : value == "completed" ,
138+ poll_interval_seconds = 0.0001 ,
139+ max_wait_seconds = 1.0 ,
140+ max_status_failures = 5 ,
141+ )
142+
143+ assert attempts ["count" ] == 1
144+
145+
126146def test_poll_until_terminal_status_does_not_retry_timeout_or_polling_errors ():
127147 timeout_attempts = {"count" : 0 }
128148
@@ -476,6 +496,24 @@ def operation() -> str:
476496 assert attempts ["count" ] == 1
477497
478498
499+ def test_retry_operation_does_not_retry_stop_iteration_errors ():
500+ attempts = {"count" : 0 }
501+
502+ def operation () -> str :
503+ attempts ["count" ] += 1
504+ raise StopIteration ("callback exhausted" )
505+
506+ with pytest .raises (StopIteration , match = "callback exhausted" ):
507+ retry_operation (
508+ operation_name = "sync retry stop-iteration passthrough" ,
509+ operation = operation ,
510+ max_attempts = 5 ,
511+ retry_delay_seconds = 0.0001 ,
512+ )
513+
514+ assert attempts ["count" ] == 1
515+
516+
479517def test_retry_operation_does_not_retry_timeout_or_polling_errors ():
480518 timeout_attempts = {"count" : 0 }
481519
@@ -745,6 +783,29 @@ async def get_status() -> str:
745783 asyncio .run (run ())
746784
747785
786+ def test_poll_until_terminal_status_async_does_not_retry_stop_async_iteration_errors ():
787+ async def run () -> None :
788+ attempts = {"count" : 0 }
789+
790+ async def get_status () -> str :
791+ attempts ["count" ] += 1
792+ raise StopAsyncIteration ("callback exhausted" )
793+
794+ with pytest .raises (StopAsyncIteration , match = "callback exhausted" ):
795+ await poll_until_terminal_status_async (
796+ operation_name = "async poll stop-async-iteration passthrough" ,
797+ get_status = get_status ,
798+ is_terminal_status = lambda value : value == "completed" ,
799+ poll_interval_seconds = 0.0001 ,
800+ max_wait_seconds = 1.0 ,
801+ max_status_failures = 5 ,
802+ )
803+
804+ assert attempts ["count" ] == 1
805+
806+ asyncio .run (run ())
807+
808+
748809def test_poll_until_terminal_status_async_does_not_retry_timeout_or_polling_errors ():
749810 async def run () -> None :
750811 timeout_attempts = {"count" : 0 }
@@ -880,6 +941,27 @@ async def operation() -> str:
880941 asyncio .run (run ())
881942
882943
944+ def test_retry_operation_async_does_not_retry_stop_async_iteration_errors ():
945+ async def run () -> None :
946+ attempts = {"count" : 0 }
947+
948+ async def operation () -> str :
949+ attempts ["count" ] += 1
950+ raise StopAsyncIteration ("callback exhausted" )
951+
952+ with pytest .raises (StopAsyncIteration , match = "callback exhausted" ):
953+ await retry_operation_async (
954+ operation_name = "async retry stop-async-iteration passthrough" ,
955+ operation = operation ,
956+ max_attempts = 5 ,
957+ retry_delay_seconds = 0.0001 ,
958+ )
959+
960+ assert attempts ["count" ] == 1
961+
962+ asyncio .run (run ())
963+
964+
883965def test_retry_operation_async_does_not_retry_timeout_or_polling_errors ():
884966 async def run () -> None :
885967 timeout_attempts = {"count" : 0 }
@@ -1666,6 +1748,28 @@ def get_next_page(page: int) -> dict:
16661748 assert attempts ["count" ] == 1
16671749
16681750
1751+ def test_collect_paginated_results_does_not_retry_stop_iteration_errors ():
1752+ attempts = {"count" : 0 }
1753+
1754+ def get_next_page (page : int ) -> dict :
1755+ attempts ["count" ] += 1
1756+ raise StopIteration ("callback exhausted" )
1757+
1758+ with pytest .raises (StopIteration , match = "callback exhausted" ):
1759+ collect_paginated_results (
1760+ operation_name = "sync paginated stop-iteration passthrough" ,
1761+ get_next_page = get_next_page ,
1762+ get_current_page_batch = lambda response : response ["current" ],
1763+ get_total_page_batches = lambda response : response ["total" ],
1764+ on_page_success = lambda response : None ,
1765+ max_wait_seconds = 1.0 ,
1766+ max_attempts = 5 ,
1767+ retry_delay_seconds = 0.0001 ,
1768+ )
1769+
1770+ assert attempts ["count" ] == 1
1771+
1772+
16691773def test_collect_paginated_results_does_not_retry_timeout_errors ():
16701774 attempts = {"count" : 0 }
16711775
@@ -1976,6 +2080,31 @@ async def get_next_page(page: int) -> dict:
19762080 asyncio .run (run ())
19772081
19782082
2083+ def test_collect_paginated_results_async_does_not_retry_stop_async_iteration_errors ():
2084+ async def run () -> None :
2085+ attempts = {"count" : 0 }
2086+
2087+ async def get_next_page (page : int ) -> dict :
2088+ attempts ["count" ] += 1
2089+ raise StopAsyncIteration ("callback exhausted" )
2090+
2091+ with pytest .raises (StopAsyncIteration , match = "callback exhausted" ):
2092+ await collect_paginated_results_async (
2093+ operation_name = "async paginated stop-async-iteration passthrough" ,
2094+ get_next_page = get_next_page ,
2095+ get_current_page_batch = lambda response : response ["current" ],
2096+ get_total_page_batches = lambda response : response ["total" ],
2097+ on_page_success = lambda response : None ,
2098+ max_wait_seconds = 1.0 ,
2099+ max_attempts = 5 ,
2100+ retry_delay_seconds = 0.0001 ,
2101+ )
2102+
2103+ assert attempts ["count" ] == 1
2104+
2105+ asyncio .run (run ())
2106+
2107+
19792108def test_collect_paginated_results_async_does_not_retry_timeout_errors ():
19802109 async def run () -> None :
19812110 attempts = {"count" : 0 }
0 commit comments