Index: build/android/pylib/device/decorators.py |
diff --git a/build/android/pylib/device/decorators.py b/build/android/pylib/device/decorators.py |
index 09803dd253526072a0cac1919fdefa25dbe3fb5a..7bce245ff0b575b18257af83cf0df8bdf0755edc 100644 |
--- a/build/android/pylib/device/decorators.py |
+++ b/build/android/pylib/device/decorators.py |
@@ -21,12 +21,30 @@ sys.path.append(os.path.join(constants.DIR_SOURCE_ROOT, 'third_party', |
'android_testrunner')) |
import errors as old_errors |
+DEFAULT_TIMEOUT_ATTR = '_default_timeout' |
+DEFAULT_RETRIES_ATTR = '_default_retries' |
-def _TimeoutRetryWrapper(f, timeout_func, retries_func): |
+ |
+def _TimeoutRetryWrapper(f, timeout_func, retries_func, pass_values=False): |
+ """ Wraps a funcion with timeout and retry handling logic. |
+ |
+ Args: |
+ f: The function to wrap. |
+ timeout_func: A callable that returns the timeout value. |
+ retries_func: A callable that returns the retries value. |
+ pass_values: If True, passes the values returned by |timeout_func| and |
+ |retries_func| to the wrapped function as 'timeout' and |
+ 'retries' kwargs, respectively. |
+ Returns: |
+ The wrapped function. |
+ """ |
@functools.wraps(f) |
def TimeoutRetryWrapper(*args, **kwargs): |
timeout = timeout_func(*args, **kwargs) |
retries = retries_func(*args, **kwargs) |
+ if pass_values: |
+ kwargs['timeout'] = timeout |
+ kwargs['retries'] = retries |
def impl(): |
return f(*args, **kwargs) |
try: |
@@ -41,15 +59,32 @@ def _TimeoutRetryWrapper(f, timeout_func, retries_func): |
def WithTimeoutAndRetries(f): |
- """A decorator that handles timeouts and retries.""" |
+ """A decorator that handles timeouts and retries. |
+ |
+ 'timeout' and 'retries' kwargs must be passed to the function. |
+ |
+ Args: |
+ f: The function to decorate. |
+ Returns: |
+ The decorated function. |
+ """ |
get_timeout = lambda *a, **kw: kw['timeout'] |
get_retries = lambda *a, **kw: kw['retries'] |
return _TimeoutRetryWrapper(f, get_timeout, get_retries) |
def WithExplicitTimeoutAndRetries(timeout, retries): |
- """ |
- A decorator that handles timeouts and retries using the provided values. |
+ """Returns a decorator that handles timeouts and retries. |
+ |
+ The provided |timeout| and |retries| values are always used. |
+ |
+ Args: |
+ timeout: The number of seconds to wait for the decorated function to |
+ return. Always used. |
+ retries: The number of times the decorated function should be retried on |
+ failure. Always used. |
+ Returns: |
+ The actual decorator. |
""" |
def decorator(f): |
get_timeout = lambda *a, **kw: timeout |
@@ -59,26 +94,52 @@ def WithExplicitTimeoutAndRetries(timeout, retries): |
def WithTimeoutAndRetriesDefaults(default_timeout, default_retries): |
- """ |
- A decorator that handles timeouts and retries using the provided defaults. |
+ """Returns a decorator that handles timeouts and retries. |
+ |
+ The provided |default_timeout| and |default_retries| values are used only |
+ if timeout and retries values are not provided. |
+ |
+ Args: |
+ default_timeout: The number of seconds to wait for the decorated function |
+ to return. Only used if a 'timeout' kwarg is not passed |
+ to the decorated function. |
+ default_retries: The number of times the decorated function should be |
+ retried on failure. Only used if a 'retries' kwarg is not |
+ passed to the decorated function. |
+ Returns: |
+ The actual decorator. |
""" |
def decorator(f): |
get_timeout = lambda *a, **kw: kw.get('timeout', default_timeout) |
get_retries = lambda *a, **kw: kw.get('retries', default_retries) |
- return _TimeoutRetryWrapper(f, get_timeout, get_retries) |
+ return _TimeoutRetryWrapper(f, get_timeout, get_retries, pass_values=True) |
return decorator |
def WithTimeoutAndRetriesFromInstance( |
- default_timeout_name, default_retries_name): |
- """ |
- A decorator that handles timeouts and retries using instance defaults. |
+ default_timeout_name=DEFAULT_TIMEOUT_ATTR, |
+ default_retries_name=DEFAULT_RETRIES_ATTR): |
+ """Returns a decorator that handles timeouts and retries. |
+ |
+ The provided |default_timeout_name| and |default_retries_name| are used to |
+ get the default timeout value and the default retries value from the object |
+ instance if timeout and retries values are not provided. |
+ |
+ Note that this should only be used to decorate methods, not functions. |
+ |
+ Args: |
+ default_timeout_name: The name of the default timeout attribute of the |
+ instance. |
+ default_retries_name: The name of the default retries attribute of the |
+ instance. |
+ Returns: |
+ The actual decorator. |
""" |
def decorator(f): |
def get_timeout(inst, *_args, **kwargs): |
return kwargs.get('timeout', getattr(inst, default_timeout_name)) |
def get_retries(inst, *_args, **kwargs): |
return kwargs.get('retries', getattr(inst, default_retries_name)) |
- return _TimeoutRetryWrapper(f, get_timeout, get_retries) |
+ return _TimeoutRetryWrapper(f, get_timeout, get_retries, pass_values=True) |
return decorator |