Skip to content

Commit 8776965

Browse files
committed
improve docstrings
1 parent 3ec5daa commit 8776965

File tree

1 file changed

+38
-7
lines changed

1 file changed

+38
-7
lines changed

s3fs/core.py

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,49 @@ def setup_logging(level=None):
7474
S3_RETRYABLE_ERRORS += (ClientPayloadError,)
7575

7676
def add_retryable_error(exc):
77-
"""Add an exception type to the list of retryable S3 errors."""
77+
"""
78+
Add an exception type to the list of retryable S3 errors.
79+
80+
Parameters
81+
----------
82+
exc : Exception
83+
The exception type to add to the retryable errors.
84+
85+
Examples
86+
----------
87+
>>> class MyCustomError(Exception): # doctest: +SKIP
88+
... pass # doctest: +SKIP
89+
>>> add_retryable_error(MyCustomError) # doctest: +SKIP
90+
"""
7891
global S3_RETRYABLE_ERRORS
7992
S3_RETRYABLE_ERRORS += (exc,)
8093

81-
_CUSTOM_ERROR_HANDLER = lambda e: False
94+
CUSTOM_ERROR_HANDLER = lambda _: False
8295
def set_custom_error_handler(func):
8396
"""Set a custom error handler function for S3 retryable errors.
8497
8598
The function should take an exception instance as its only argument,
8699
and return True if the operation should be retried, or False otherwise.
100+
This can also be used for custom behavior on `ClientError` exceptions,
101+
such as retrying other patterns.
102+
103+
Parameters
104+
----------
105+
func : callable[[Exception], bool]
106+
The custom error handler function.
107+
108+
Examples
109+
----------
110+
>>> def my_handler(e): # doctest: +SKIP
111+
... return isinstance(e, MyCustomError) and "some condition" in str(e) # doctest: +SKIP
112+
>>> set_custom_error_handler(my_handler) # doctest: +SKIP
113+
114+
>>> def another_handler(e): # doctest: +SKIP
115+
... return isinstance(e, ClientError) and "Throttling" in str(e) # doctest: +SKIP
116+
>>> set_custom_error_handler(another_handler) # doctest: +SKIP
87117
"""
88-
global _CUSTOM_ERROR_HANDLER
89-
_CUSTOM_ERROR_HANDLER = func
118+
global CUSTOM_ERROR_HANDLER
119+
CUSTOM_ERROR_HANDLER = func
90120

91121
_VALID_FILE_MODES = {"r", "w", "a", "rb", "wb", "ab"}
92122

@@ -124,6 +154,7 @@ def set_custom_error_handler(func):
124154
async def _error_wrapper(func, *, args=(), kwargs=None, retries):
125155
if kwargs is None:
126156
kwargs = {}
157+
err = None
127158
for i in range(retries):
128159
wait_time = min(1.7**i * 0.1, 15)
129160

@@ -150,18 +181,18 @@ async def _error_wrapper(func, *, args=(), kwargs=None, retries):
150181
if matched:
151182
await asyncio.sleep(wait_time)
152183
else:
153-
should_retry = _CUSTOM_ERROR_HANDLER(e)
184+
should_retry = CUSTOM_ERROR_HANDLER(e)
154185
if should_retry:
155186
await asyncio.sleep(wait_time)
156187
else:
157188
break
158189
except Exception as e:
159-
should_retry = _CUSTOM_ERROR_HANDLER(e)
190+
err = e
191+
should_retry = CUSTOM_ERROR_HANDLER(e)
160192
if should_retry:
161193
await asyncio.sleep(wait_time)
162194
else:
163195
logger.debug("Nonretryable error: %s", e)
164-
err = e
165196
break
166197

167198
if "'coroutine'" in str(err):

0 commit comments

Comments
 (0)